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

📄 i2c.c

📁 此程序是 单片机I2C 的操作平台的底层的C子程序
💻 C
字号:
/*************************************************
  File name:  I2C.c    
  Description:  I2C   此程序是 I2C 的操作平台的底层的C子程序, 
                如发送数据,接收数据,应答位的发送,
                注意:函数采用软件延时的方法产生scl脉冲。
  Others:        
  Function List:  

    1.void Stop_I2c();启动总线函数,启动I2C总线 
    2.void Stop_I2c();结束I2C 总线
    3.void SendByte(unsigned char c);字节数据传送函数,将数据c发送出去,可以时地址,也可以时数据
               发玩后等待应答,并对此状态位进行操作(不应答或非应答多使ack=false)
               发送数据正常,ack=true;
               ack=true:被控器无应答或损坏。
    4.unsigned char  RcvByte();
    5.void Ack_I2c(bit a);
    6.bit ISendSTR();
    7.bit IRcvstr();

  History:       
    1. Date:
       Author:
       Modification:
    2. ...
*************************************************/



#include <C:\KEIL\C51\INC\PHILIPS\reg51f.h>
#include <main.h>

#include   <stdlib.h>
#include <intrins.h>



void Stop_I2c();
void Stop_I2c();
void SendByte(unsigned char c);
unsigned char  RcvByte();
void Ack_I2c(bit a);
bit ISendSTR();
bit IRcvstr();

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

bit data ack;           //应答标志位
unsigned char sla;      //从器件地址
unsigned char suba;     //子地址suba
unsigned char *I2C_buf; // 数据缓冲区指针 (读操作时会被更改)
unsigned char byte_num; // 操作数据个数 (会被更改)
unsigned char idata data_buf[6];
/*************************************************
 Function:     void Start_I2C()
 Description:  启动总线函数,启动I2C总线 
                 
 Calls:            
 Called By:     ISendSTR() 
 Input:           
 Output:           
 Return:           
 Others:          
*************************************************/
void Start_I2c()
{    
     SDA=1;      //发送起始条件的数据信号
     _nop_();
     SCL=1;
     _nop_();   //起始条件建立时间大于4.8us延时。6us;一个指令周期 2us
     _nop_();
     _nop_();
     SDA=0;     //发送起始信号
     _nop_();
     _nop_();
     _nop_();   //起始条件锁定时间大于4us
     SCL=0;      //钳住I2C总线。准备发送或接收数据
     _nop_();
        
}

/*************************************************
 Function:     void Stop_I2C()
 Description:  结束I2C 总线
                 
 Calls:            
 Called By:    ISendSTR() ,IRcvstr()   
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/  

void Stop_I2c()
{
    SDA=0;   //发送结束条件的数据信号
    _nop_(); //发送结束条件的时钟信号
    SCL=1;   //结束条件建立时间大于4us
    _nop_();
    _nop_();
    _nop_();
    SDA=1;   //发送I2C结束信号。
    _nop_();
    _nop_();
    _nop_();
} 

/*************************************************
 Function:     void SendByte(uchar)
 Description:  字节数据传送函数,将数据c发送出去,可以时地址,也可以时数据
               发玩后等待应答,并对此状态位进行操作(不应答或非应答多使ack=false)
               发送数据正常,ack=true;
               ack=true:被控器无应答或损坏。
                 
 Calls:            
 Called By:  ISendSTR() ,IRcvstr()   
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/  

void SendByte(unsigned char c)
{
    unsigned char BitCnt;
    for (BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
    {
        if((c<<BitCnt)&0x80)    //判断发送位
        {
            SDA=1;    
        }
        else
        {
            SDA=0;
        }
        _nop_();
        SCL=1;         //置时钟线为高,通知被控器开始接收数据位
        _nop_();
        _nop_();       //保证时钟高电平周期大于4us
        _nop_();
        //_nop_();
        SCL=0;
    }
    _nop_();
    //_nop_();
    SDA=1; //8位发送完后释放数据线,准备接收应答信号
    _nop_();
    //_nop_();
    SCL=1;
    _nop_();
    _nop_();
    if (SDA==1)
    {
        ack=false;
    }
    else
    {
        ack=true;
    }
    SCL=0;
    _nop_();   
    
} 

/*************************************************
 Function:     void RcvByte()
 Description:  字节数据传送函数,用来接收从器件传来的数据,并判断总线错误(不发应答信号)
               发玩后请用应答函数。
                 
 Calls:            
 Called By:      IRcvstr()
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/   

unsigned char RcvByte()
{
    unsigned char retc;
    unsigned char BitCnt;
    
    retc=0;
    
    SDA=1; //置数据线为输入方式
    for(BitCnt=0;BitCnt<8;BitCnt++)
    {
        _nop_();
        _nop_();
        SCL=0;  //置时钟线为低准备接收数据位
        _nop_();
        _nop_();
        _nop_();//时钟低电平周期大于4.7us
        _nop_();
        _nop_();
        _nop_();
        SCL=1;   //置时钟线数据为高使数据线上数据有效。
        _nop_();
        _nop_();
        retc=retc<<1;
        if (SDA==1)
        {
            retc=retc+1;//读数据位,接收的数据位放入retc
        }
        _nop_();
        _nop_();
        
    }
    SCL=0;
    _nop_();
    _nop_();
    return(retc);
}  

/*************************************************
 Function:    void Ack_I2c(bit a);
 Description: 主控器进行应答信号 (可以使应答或非应答信号)                
 Calls:            
 Called By:      
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/   
void Ack_I2c(bit a)
{
   if(a==0)    //在此发送应答或非应答信号。
   {
       SDA=0;
   }
   else
   {
       SDA=1;
   }
   _nop_();
   _nop_();
   SCL=1;     //时钟高电平周期大于4us,
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL=0;     //清时钟线,钳住I2C总线一边继续接收。
   _nop_();
   _nop_();
   _nop_();
}


/*************************************************
 Function:   bit ISendSTR()
 Description:从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,
             子地址suba,发送内容是I2C_buf指向的内容,发送byte_num个字节。
             如果返回1表示操作成功,否则操作有误   
            
 Calls:      Start_I2c();           //启动总线_ 
             Ack_I2c(1); 
             Stop_I2c();
             RcvByte(); 
             Start_I2c();

 Called By:  key_read();  
             void Cah_Warp_Save(unsigned char add,unsigned char num)
             void Cah_Temp_Save(unsigned char add,unsigned char num) 
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/ 
bit ISendSTR()
{
    unsigned char i;
    Start_I2c();   //启动总线
    SendByte(sla); //发送器件地址
    if (ack==false)
    {
        return(0);
    }
    SendByte(suba);//发送器件子地址
    if (ack==false)
    {
        return(0);   
    }
    for (i=0;i<byte_num;i++)
    {
        SendByte(*I2C_buf); //发送数据。
        if (ack==false)
        {
            return(0);
        }  
        I2C_buf++;
    } 
    Stop_I2c();
    return(1);
    
}

/*************************************************
 Function:   bit IRcvstr(unsigned char sla,unsigned char suba,unsigned char *s,unsigned char byte_num)
 Description:     向有子地址器件读取多字节函数,从启动总线到发送地址、子地址,读数据,结束总线的全过程
                  ,从器件地址sla,子地址suba,读出的内容放入I2C_buf指向的存储区,读byte_num个字节,如返回1
                  表示操作成功,否则有误。       
 Calls:           Start_I2c();           //启动总线_ 
                  Ack_I2c(1); 
                  Stop_I2c();
                  RcvByte(); 
                  Start_I2c();
                  void SendByte(unsigned char c);
 Called By:      void Read_Cah_Warp(unsigned char add,unsigned char num)
                 void Read_Cah_Temp(unsigned char add,unsigned char num)
                 void read_setvalue()
 Input:           
 Output:           
 Return:           
 Others: 
*************************************************/ 
bit IRcvstr()
{
    unsigned char i;
    
    Start_I2c();           //启动总线_
    SendByte(sla);         //发送器件地址
    if (ack==0)
    {
        return(0);
     
    }
    SendByte(suba);       //发送器件子地址
    if (ack==0)
    {
        return(0);
    }
    Start_I2c();          //重新启动总线
    SendByte(sla+1);      //准备进行读操作W/R置1
    if(ack==0)
    {
        return(0);
    }
    
    for (i=0;i<byte_num-1;i++)
    {
        *I2C_buf=RcvByte();     //发送数据     
        Ack_I2c(0);        //发送就答位
        I2C_buf++;
    }  
    *I2C_buf=RcvByte();
    Ack_I2c(1);           //发送非应位                 
    Stop_I2c();
    return(1);
 
}

⌨️ 快捷键说明

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