i2c总线编码

ぐ巨炮叔叔 提交于 2020-03-21 10:49:31

发送启动信号S

在同步时钟线SCL 为高电平时,数据线出现的由高到低的下降沿。 启动信号子程序STA

 1 /*******************************************************************************
 2 * 函数名         : I2cStart()
 3 * 函数功能         : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
 4 * 输入           : 无
 5 * 输出              : 无
 6 * 备注           : 起始之后SDA和SCL都为0
 7 *******************************************************************************/
 8 
 9 void I2cStart()
10 {
11     SDA=1;
12     Delay10us();
13     SCL=1;
14     Delay10us();//建立时间是SDA保持时间>4.7us
15     SDA=0;
16     Delay10us();//保持时间是>4us
17     SCL=0;            
18     Delay10us();        
19 }

发送停止信号P

在SCL 为高电平期间SDA 发生正跳变。

停止信号子程序STOP

 1 /*******************************************************************************
 2 * 函数名         : I2cStop()
 3 * 函数功能         : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
 4 * 输入           : 无
 5 * 输出              : 无
 6 * 备注           : 结束之后保持SDA和SCL都为1;表示总线空闲
 7 *******************************************************************************/
 8 
 9 void I2cStop()
10 {
11     SDA=0;
12     Delay10us();
13     SCL=1;
14     Delay10us();//建立时间大于4.7us
15     SDA=1;
16     Delay10us();        
17 }

等待应答信号

应答信号:应答信号由接受设备产生,在scl信号为高电平期间,接受设备将SDA拉低为低电平一段时间,表示数据传输正确。

非应答信号:应答信号由接受设备产生,在SCL信号为高电平期间,接受设备不将将SDA拉低为低电平一段时间,没有应答。

 1 /*******************************************************************************
 2 * 函数名         : yingda()
 3 * 函数功能      : 对数据是否被从机接受给出应答/非应答信号(1/0)
 4 * 输入            : 无
 5 * 输出            : 0或1。发送成功返回1,发送失败返回0
 6 * 备注            : 发送完一个字节SCL=0,SDA=1
 7 *******************************************************************************/
 8 void yingda()
 9 { 
10        unsigned char b;
11           while(SDA)//等待应答,也就是等待从设备把SDA拉低
12     {
13         b++;
14         if(b>200)     //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
15         {
16             SCL=0;
17             Delay10us();
18             return 0;
19         }
20     }
21     SCL=0;
22     Delay10us();
23      return 1;
24 }

通过I2C发送一个字节

数据传送格式

 

 

 

unsigned char I2cSendByte(unsigned char dat)
{
    unsigned char a=0;//最大255,一个机器周期为1us,最大延时255us。        
    for(a=0;a<8;a++)//要发送8位,从最高位开始
    {
        SDA=dat>>7;     //起始信号之后SCL=0,所以可以直接改变SDA信号
        dat=dat<<1;
        Delay10us();
        SCL=1;
        Delay10us();//建立时间>4.7us
        SCL=0;
        Delay10us();//时间大于4us        
    }
    SDA=1;
    Delay10us();
    SCL=1;
    yingda(); //应答子函数
}

使用I2c读取一个字节

 1 /*******************************************************************************
 2 * 函数名         : I2cReadByte()
 3 * 函数功能           : 使用I2c读取一个字节
 4 * 输入           : 无
 5 * 输出              : dat
 6 * 备注           : 接收完一个字节SCL=0,SDA=1.
 7 *******************************************************************************/
 8 
 9 unsigned char I2cReadByte()
10 {
11     unsigned char a=0,dat=0;
12     SDA=1;            //起始和发送一个字节之后SCL都是0
13     Delay10us();
14     for(a=0;a<8;a++)//接收8个字节
15     {
16         SCL=1;
17         Delay10us();
18         dat<<=1;
19         dat|=SDA;
20         Delay10us();
21         SCL=0;
22         Delay10us();
23     }
24     return dat;        
25 }

以At24c02举例说明i2c总线读写数据过程

a、主机向从机发送数据,数据传送方向在整个传送过程中不变:

注:有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。

A表示应答, A非表示非应答(高电平)。

S表示起始信号,P表示终止信号。

 1 /*******************************************************************************
 2 * 函数名         : void At24c02Write(unsigned char addr,unsigned char dat)
 3 * 函数功能           : 往24c02的一个地址写入一个数据
 4 * 输入           : 无
 5 * 输出              : 无
 6 *******************************************************************************/
 7 
 8 void At24c02Write(unsigned char addr,unsigned char dat)
 9 {
10     I2cStart();
11     I2cSendByte(0xa0);     //发送写器件地址   用“0”表示主机发送数据(T),“1”表示主机接收数据(R)
12     I2cSendByte(addr);//发送要写入内存地址 13     I2cSendByte(dat); //发送数据14     I2cStop(); 15 }

b、主机从从机读数据

 

 1 /*******************************************************************************
 2 * 函数名         : unsigned char At24c02Read(unsigned char addr)
 3 * 函数功能           : 读取24c02的一个地址的一个数据
 4 * 输入           : 无
 5 * 输出              : 无
 6 *******************************************************************************/
 7 
 8 unsigned char At24c02Read(unsigned char addr)
 9 {
10     unsigned char num;
11     I2cStart();
12     I2cSendByte(0xa0); //发送写器件地址
13     I2cSendByte(addr); //发送要读取的地址
14     I2cStart();
15     I2cSendByte(0xa1); //发送读器件地址
16     num=I2cReadByte(); //读取数据
17     I2cStop();
18     return num;    
19 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!