单片机软件,工作环境keil C51
选用最常见的华邦MCU,带ISP在线可编程,只需要一个232的串口,就可以降低一个仿真器的成本,按如下步骤进行的话,大多数功能都可以通用。
包含有:Main.c I2C.c KeyHandle.c MCUint.c EEPROM.c GlobalVarible.c Remote.c
Main.c
void main()using 0
{
delay20ms();delay20ms();delay20ms();delay20ms();delay20ms();//减少硬件复位影响
Mcuint();
while(1){
KeyCodeHandle(); //主要检查电源按键
if(IoGotoISP==0){ //按键进入ISP
Goto_ISP();
}
if(KeyCodeCurrent==keyfactory)FactoryFlag=1;//可以设置工厂模式
if(!PowerSwitchFlag)continue; //电源按下执行
PowerSwitchFlag=0; //电源标志位复位
PowerOn_LED//open KEY BORAD LED 亮灯
//check EEPROM and Get EEPROM data //EEPROM数据保存
EEPRomInt();
//ini brighness IC
TSL2550Ini(); //为后面举例I2C,这是一颗亮度传感器
PowerSwitchFlag=1;
while(1)
{
KeyCodeHandle();
AudioHandle();
HotKeyChannelHandle();
AutoAFC();
if( (EnableDisplayDealyFlag)&&(EnableDisplayDealyTimer==0) ){
EnableDisplayDealyFlag=0;
EnableDisplay();
}
if(!PowerSwitchFlag)
{
DisableDisplay();
break;
}
if(IoGotoISP==0){
Goto_ISP();
}
ClearVariable();
}
OSDClear();
DisableDisplay();
ResetMcu();
}
}
void Goto_ISP(void)
{
//-------------------for winbord "W78E65" ISP
IE=0x00;
TCON=0x00;
T2CON=0x00;
CHPENR=0x87;
CHPENR=0x59;
CHPCON=0x03;
CHPENR=0x00;
IE=0x82;
TMOD=0x01;
TL0=0xF0;
TH0=0xFF;
TR0=1;
PCON = 0x01;
while(1);
}
I2C.c
#include "public.h"
#include <intrins.h>
#define#define SetI2CSCL() (SCL = 1)
#define ClrI2CSCL() (SCL = 0)
#define SetI2CSDA() (SDA = 1)
#define ClrI2CSDA() (SDA = 0)
#define CheckI2CSDA() (SDA == 1)
#define CheckI2CSCL() (SCL == 1)
#define SetSDAInput()
#define SetSDAOutput()
#define SetSCLInput()
#define SetSCLOutput()
enum
{
I2C_OK,
I2C_BUSY,
I2C_ERR
}; NOP()// _nop_();_nop_();_nop_();_nop_();/***每一条的指令时间为1US****/
/*******************************************************************
起动总线函数
函数原型: void Start_I2C();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
static void Start_I2C()
{
SetSDAOutput(); //some MCU io prot must be to config for input or ouput
NOP();
SetSCLOutput(); //some MCU io prot must be to config for input or ouput
NOP();
SetI2CSDA(); // Set SDA
NOP();
SetI2CSCL(); // Set SCL
NOP();
SetSCLInput(); //some MCU io prot must be to config for input or ouput
while(!(CheckI2CSCL())); // Wait until bus is released by slave
SetSCLOutput(); //some MCU io prot must be to config for input or ouput
SetI2CSDA(); // Set SDA
NOP();
ClrI2CSDA(); // Clear SDA
NOP();
ClrI2CSCL(); // Clear SCL
NOP();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
static void Stop_I2C()
{
ClrI2CSDA(); // Clear SDA
NOP();
SetI2CSCL(); // Set SCL
NOP();
SetI2CSDA(); // Set SDA
NOP();
}
/*******************************************************************
获取应答状态函数
函数原型: unsigned char GetACK_I2c();
功能: 获取IIC总线器件IIC应答状态
输出: SDA口的状态
********************************************************************/
static unsigned char GetACK_I2C()
{
unsigned char ack;
SetI2CSDA(); // Set SDA line to 1 and check it as input.
NOP();
SetI2CSCL();
NOP();
SetSDAInput(); //some MCU io prot must be to config for input or ouput
NOP();
ack = CheckI2CSDA(); // Check SDA line
SetSDAOutput(); //some MCU io prot must be to config for input or ouput
NOP();
ClrI2CSCL();
NOP();
return (ack); // Return SDA status
}
/*******************************************************************
发送应答状态函数
函数原型: unsigned char SetACK_I2C();
功能: 发送IIC应答状态
********************************************************************/
static void SetACK_I2C(unsigned char ACK )
{
if(ACK==0)ClrI2CSDA(); // Write ACK to slave
else SetI2CSDA();
NOP();
SetI2CSCL(); // Set SCL
NOP();
ClrI2CSCL();
NOP();
}
/*******************************************************************
字节数据传送函数
函数原型: unsigned char WriteByte_I2C(unsigned char WriteData);
功能: 将数据WriteData发送出去,可以是地址,也可以是数据,返回应答状态.
输入:WriteData=要发送单字节的数据
输出:返回状态标志
********************************************************************/
static unsigned char WriteByte_I2C(unsigned char WriteData)
{
unsigned char BitSelect;
BitSelect = 0x80;
while (BitSelect)
{
if (BitSelect & WriteData) // Check data bit
SetI2CSDA(); // Set SDA
else
ClrI2CSDA(); // Clear SDA
NOP();
SetI2CSCL(); // Set SCL
NOP();
ClrI2CSCL(); // Clear SCL
NOP();
BitSelect >>= 1; // Shift bit position to right
}
// Check I2C ACK
if (GetACK_I2C()) // If ACK not seen
{
Stop_I2C(); // Issue I2C STOP
return I2C_BUSY;
}
else
return I2C_OK;
}
/*******************************************************************
字节数据接收函数
函数原型: unsigned char ReadByte_I2C(void)
功能: 从IIC口上接收一个字节的数据
输出:返回接收到的一个字节数据
********************************************************************/
static unsigned char ReadByte_I2C(void)
{
unsigned char readData, BitSelect;
readData = 0; // Init data
BitSelect = 0x80;
SetI2CSDA(); // Set SDA
NOP();
SetSDAInput();
while (BitSelect)
{
// On Novatek micro, clearing SCL while SDA is low
// results in clearing SDA, so set it again.
SetI2CSDA(); NOP();
SetI2CSCL(); // Set SCL
if (CheckI2CSDA())
readData |= BitSelect; // Set data bit
else
readData &= ~BitSelect; // Clear data bit
ClrI2CSCL(); // Clear SCL
NOP();
BitSelect >>= 1; // Shift bit position to right
}
SetSDAOutput();
return readData;
}
/*******************************************************************
向有子地址器件发送多字节数据函数
函数原型: unsigned char WriteStr_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char *WriteDataStr,unsigned char WriteDataNumber);
功能: 向IIC器件连续发送多字节数据
输入: SlaveAdrees--器件地址
SlaveSubAdrees--器件子地址
WriteDataStr--待发送数据串指针
WriteDataNumber--待发送数据串字节数
输出: I2C_OK--表示数据发送成功
I2C_ERR--表示数据发送失败
********************************************************************/
unsigned char WriteStr_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char *WriteDataStr,unsigned char WriteDataNumber)
{
unsigned char ContinueNumber=10;
unsigned char NuberBak=WriteDataNumber;
while(--ContinueNumber){
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees)!=I2C_OK ) //Write SlaveAdrees to slave
goto ErrorExit;
if( WriteByte_I2C(SlaveSubAdrees)!=I2C_OK ) //Write slaveSubAdress to slave
goto ErrorExit;
while(WriteDataNumber)
{
if( WriteByte_I2C(WriteDataStr[--WriteDataNumber])!=I2C_OK )
goto ErrorExit;
}
Stop_I2C();
return(I2C_OK);
ErrorExit:
delay20ms();
WriteDataNumber=NuberBak;
continue;
}
Stop_I2C();
return(I2C_ERR);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: unsigned char ReadStr_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char *ReadDataStr,unsigned char ReadDataNumber);
功能: 向IIC器件连续发送多字节数据
输入: SlaveAdrees--器件地址
SlaveSubAdrees--器件子地址
ReadDataStr--接收到的数据串指针
ReadDataNumber--接收到数据串字节数
输出: I2C_OK--表示数据接收成功
I2C_ERR--表示数据接收失败
********************************************************************/
unsigned char ReadStr_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char *ReadDataStr,unsigned char ReadDataNumber)
{
unsigned char index=0;
unsigned char ContinueNumber=10;
while(--ContinueNumber){
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees)!=I2C_OK ) //Write SlaveAdrees to slave
goto ErrorExit;
if( WriteByte_I2C(SlaveSubAdrees)!=I2C_OK ) //Write slaveSubAdress to slave
goto ErrorExit;
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees+1)!=I2C_OK ) //Write SlaveAdrees and Read-flag to slave
goto ErrorExit;
ReadDataNumber--;
while(ReadDataNumber>index)
{
ReadDataStr[index++]=ReadByte_I2C();
SetACK_I2C(0);
}
ReadDataStr[index]=ReadByte_I2C();
SetACK_I2C(1);
Stop_I2C();
return(I2C_OK);
ErrorExit:
delay20ms();
continue;
}
Stop_I2C();
return(I2C_ERR);
}
/*******************************************************************
向有子地址器件发送单 字节数据函数
函数原型: unsigned char Write_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char WriteData);
功能: 向IIC器件连续发送多字节数据
输入: SlaveAdrees--器件地址
SlaveSubAdrees--器件子地址
WriteDataStr--待发送数据串指针
WriteDataNumber--待发送数据串字节数
输出: I2C_OK--表示数据发送成功
I2C_ERR--表示数据发送失败
********************************************************************/
unsigned char Write_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char WriteData)
{
unsigned char ContinueNumber=10;
while(--ContinueNumber){
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees)!=I2C_OK ) //Write SlaveAdrees to slave
goto ErrorExit;
if( WriteByte_I2C(SlaveSubAdrees)!=I2C_OK ) //Write slaveSubAdress to slave
goto ErrorExit;
if( WriteByte_I2C(WriteData)!=I2C_OK )
goto ErrorExit;
Stop_I2C();
return(I2C_OK);
ErrorExit:
delay20ms();
continue;
}
Stop_I2C();
return(I2C_ERR);
}
/*******************************************************************
向有子地址器件读取多字节数据函数
函数原型: unsigned char ReadStr_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees,unsigned char *ReadDataStr,unsigned char ReadDataNumber);
功能: 向IIC器件连续发送多字节数据
输入: SlaveAdrees--器件地址
SlaveSubAdrees--器件子地址
ReadDataStr--接收到的数据串指针
ReadDataNumber--接收到数据串字节数
输出: I2C_OK--表示数据接收成功
I2C_ERR--表示数据接收失败
********************************************************************/
unsigned char Read_I2C(unsigned char SlaveAdrees,unsigned char SlaveSubAdrees)
{
unsigned char ReadData=0;
unsigned char ContinueNumber=10;
while(--ContinueNumber){
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees)!=I2C_OK ) //Write SlaveAdrees to slave
goto ErrorExit;
if( WriteByte_I2C(SlaveSubAdrees)!=I2C_OK ) //Write slaveSubAdress to slave
goto ErrorExit;
Start_I2C(); //start iic
if( WriteByte_I2C(SlaveAdrees+1)!=I2C_OK ) //Write SlaveAdrees and Read-flag to slave
goto ErrorExit;
ReadData=ReadByte_I2C();
SetACK_I2C(1);
Stop_I2C();
return(ReadData);
ErrorExit:
delay20ms();
continue;
}
Stop_I2C();
return(I2C_ERR);
}