⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vi2c_c51.c

📁 MCU 通过i2c 总线读写eeprom, i2c 读写程序是软件仿真方式来实现
💻 C
字号:
/********************************************************************
                       VI2C_C51.C
  此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
与用户程序连接并扩展.....  
  
    注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 
一定的修改....

********************************************************************/
  
  
              
#include <reg51.h>          /*include head file*/
#include <intrins.h>
#include "VI2C_C51.h"

#define  uchar unsigned char /*宏定义*/
#define  uint  unsigned int

#define  _Nop()  _nop_();_nop_();_nop_()        /*define null operate*/



/*constant/ variable define */
 
/*endport define*/
sbit SDA=P1^0;            /*IIC data bit*/
sbit SCL=P1^1;            /*IIC clock control*/

/*status flag*/
bit ack;	         /*response flag bit */
   




/*******************************************************************
                     起start bus function               
function original: void  Start_I2c();  
function: start I2C bus, 
  
********************************************************************/
void Start_I2c()
{
  SDA=1;   /*data start */
  _Nop();
  SCL=1;
  _Nop();    /*start condition setup up time 4.7us, delay*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();    
  SDA=0;   /*tx start signal*/
  _Nop();    /*start condition locked time big than 4us*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();       
  SCL=0;   /*keep I2C bus, ready tx or rx data*/
  _Nop();
  _Nop();
}




/*******************************************************************
                      end bus function            
name: void  Stop_I2c();  
function: end I2C bus, 
  
********************************************************************/
void Stop_I2c()
{
  SDA=0;  /*tx stop data condition signal*/
  _Nop();   /*tx stop clock condition signal*/
  SCL=1;  /*setup time >4us */
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  _Nop();
  SDA=1;  /*tx I2C bus stop signal*/
  _Nop();
  _Nop();
  _Nop();
  _Nop();
}




/*******************************************************************
                 byte data transmit function     
original: void  SendByte(uchar c);
function:  data c Tx-out, data or address, tx done wait response, 
          and status bit operate. error: ack=0, right ack=1.
********************************************************************/
void  SendByte(uchar c)
{
 uchar BitCnt;
 
 for(BitCnt=0;BitCnt<8;BitCnt++)  /*transmit data length is 8 bit*/
    {
     if((c<<BitCnt)&0x80)SDA=1;   /*check tx bit*/
       else  SDA=0;                
     _Nop();
     SCL=1;               /*set SCL to high, infor device rx data*/
      _Nop(); 
      _Nop();               /*hold time >4us */
      _Nop();
      _Nop();
      _Nop();         
     SCL=0; 
    }
    
    _Nop();
    _Nop();
    SDA=1;               /*8bit tx done, ready rx ack bit*/
    _Nop();
    _Nop();   
    SCL=1;
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1)ack=0;     
       else ack=1;        /*check whether rx response bit*/
    SCL=0;
    _Nop();
    _Nop();
}






/*******************************************************************
                 bit data rx function            
original: uchar  RcvByte();
function: rx device transmit data, and check bus error(ack=0)
          
********************************************************************/	
uchar  RcvByte()
{
  uchar retc;
  uchar BitCnt;
  
  retc=0; 
  SDA=1;             /*set SDA to input mode*/
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _Nop();           
        SCL=0;       /*set SCL=0, ready receive data bit*/
        _Nop();
        _Nop();         /*SCL hold time>4.7us*/
        _Nop();
        _Nop();
        _Nop();
        SCL=1;       /*set SCL=1, SDA data viable*/
        _Nop();
        _Nop();
        retc=retc<<1;
        if(SDA==1)retc=retc+1; /*read SDA, rx data bit input to retc */
        _Nop();
        _Nop(); 
      }
  SCL=0;    
  _Nop();
  _Nop();
  return(retc);
}




/********************************************************************
                     response sub-function
original:  void Ack_I2c(bit a);
 
function: main control response signal(allow ack or no ack)
********************************************************************/
void Ack_I2c(bit a)
{
  
  if(a==0)SDA=0;     /*ack or no ack*/
        else SDA=1;
  _Nop();
  _Nop();
  _Nop();      
  SCL=1;
    _Nop();
    _Nop();              /*SCL hold time>4us */
    _Nop();
    _Nop();
    _Nop();  
 SCL=0;                /*clean SCL, keep I2C bus to continue rx*/
    _Nop();
    _Nop();    
}






/*******************************************************************
                  write tx byte data function to has no sub-address device             
original: bit ISendByte(uchar sla,ucahr c);  
function: from start bus to tx address, data, end bus all process.
          sla, c tx content, return 1 operate succeed.
note: before use must end bus.
********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
   Start_I2c();               /*启start bus*/
   SendByte(sla);            /*tx device address*/
     if(ack==0)return(0);
   SendByte(c);               /*tx data*/
     if(ack==0)return(0);
  Stop_I2c();                 /*end bus*/ 
  return(1);
}




/*******************************************************************
                   write tx data to has sub-address device function          
original: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
function: from start bus to tx address, data, end bus all process.
          sla, suba, c tx content, return 1 operate succeed.
note: before use must end bus.
********************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;

   Start_I2c();               /*start bus*/
   SendByte(sla);            /*tx device address*/
     if(ack==0)return(0);
   SendByte(suba);            /*tx device sub-address*/
     if(ack==0)return(0);

   for(i=0;i<no;i++)
    {   
     SendByte(*s);               /*tx data*/
       if(ack==0)return(0);
     s++;
    } 
 Stop_I2c();                 /*stop bus*/ 
  return(1);
}






/*******************************************************************
                    read RX data function for has no sub-address         
original: bit  IRcvByte(uchar sla,ucahr *c);  
功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
          址sla,返回值在c.
           如果返回1表示操作成功,否则操作有误。
note: before use end the bus
********************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{
   Start_I2c();                /*启start bus*/
   SendByte(sla+1);           /*tx device address*/
     if(ack==0)return(0);
   *c=RcvByte();               /*read data*/
     Ack_I2c(1);               /*tx no-ack bit*/
  Stop_I2c();                  /*stop bus*/ 
  return(1);
}



/*******************************************************************
                   read mult. byte data function has sub-address            
original: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
function: read data function
note: before use must end bus
********************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
   uchar i;

   Start_I2c();               /*start bus*/
   SendByte(sla);            /*tx device address*/
     if(ack==0)return(0);
   SendByte(suba);            /*tx sub-address*/
     if(ack==0)return(0);

   Start_I2c();
   SendByte(sla+1);
      if(ack==0)return(0);

   for(i=0;i<no-1;i++)
    {   
     *s=RcvByte();               /*tx data*/
      Ack_I2c(0);                /*tx ack bit*/  
     s++;
    } 
   *s=RcvByte();
    Ack_I2c(1);                 /*tx not ack bit*/
 Stop_I2c();                    /*stop bus*/ 
  return(1);
}




/*******************************************************************
********************************************************************
********************************************************************
*******************************************************************/



/**********************************************************
write tx data to has not sub-address device function          
original: bit  ISendStr2(uchar sla,uchar *suba,ucahr *s,uchar no);  
function: from start bus to tx address, data, end bus all process.
          sla, suba, c tx content, return 1 operate succeed.
note:16 bit sub-address
********************************************************************/
bit ISendStr2(uchar sla,uchar *suba,uchar *s,uchar no)
{
   uchar i;
   Start_I2c();               //启start bus
   SendByte(sla);             //tx device address
     if(ack==0)return(0);
   SendByte(*suba);            //tx device sub-address
     if(ack==0)return(0);
   SendByte(*(suba+1));        //tx device sub-address
     if(ack==0)return(0);

   for(i=0;i<no;i++)
    {   
     SendByte(*s);             //tx data
       if(ack==0)return(0);
     s++;
    } 
   Stop_I2c();                 //end bus
   return(1);
}




/*******************************************************************
              Read rx data to has  sub-address device function          
original: bit  ISendStr2(uchar sla,uchar suba,ucahr *s,uchar no);  
function: from start bus to tx address, data, end bus all process.
          sla, suba, c tx content, return 1 operate succeed.
note:16 bit sub-address
********************************************************************/
bit IRcvStr2(uchar sla,uchar *suba,uchar *s,uchar no)
{
   uchar i;

   Start_I2c();               //启start bus
   SendByte(sla);             //TX device address
     if(ack==0)return(0);
   SendByte(*suba);            //TX device sub-address
     if(ack==0)return(0);
   SendByte(*(suba+1));        //TX deveice sub-address
     if(ack==0)return(0);

   Start_I2c();
   SendByte(sla+1);
      if(ack==0)return(0);

   for(i=0;i<no-1;i++)
    {   
     *s=RcvByte();               //tx data
      Ack_I2c(0);                //tx ack bit
     s++;
    } 
   *s=RcvByte();
   Ack_I2c(1);                   //tx not ack bit
   Stop_I2c();                   //end bus
   return(1);
}



/*******************************************************************
                    read mult data function for has sub address device            
original: bit IwCheck(uchar sla) 
function:  check whether device reponse, check device write cycle 
          whether end and device whether exist.
********************************************************************/
bit IwCheck(uchar sla)
{
  Start_I2c();              /*启start bus*/
  SendByte(sla);            /*tx device address*/
    if(ack==0)return(0);
  Stop_I2c();               /*end bus*/ 
  return(1);
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -