单片机应用

单片机软件,工作环境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);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值