分享

IIC通讯时序详解(上)

 myallmy 2022-06-21 发布于北京

本文作者: 阳光,e小白网址:www.e-xiaobai.com

在刚开始接触单片机的时候,会被板级内的各种通讯接口方式弄的晕头转向。嵌入式系统中常用板级通讯方式有:并口(8位、16位)、SPI(4线、3线)、IIC、USB、TYPE-C等。具体采用什么通讯方式,要根据实际项目情况选择。并口传输速度快,处理数据量大,像处理图形图像优先考虑,硬件成本高;串口传输速度相对比较慢,接线简单,硬件成本低。这里详细介绍下IIC通讯方式的使用。
一、IIC 简介
    IIC(Inter-Integrated Circuit)总线是由NXP(原PHILIPS)公司开发的两线式串行总线,用于连接单片机及其外围设备。多用于主控制器和从器件间的主从通信,适用数据量少,传输距离短场合。在 MCU 与被控 IC 之间、IC 与 IC 之间进行二线制、双向、同步半双工传输。IIC传输速度分为标准100Kbps、快速400Kbps、高速3.4Mbps,目前大多数器件都支持快速传输。IIC总线的传输距离受到布线、速度、总线电容的影响,虽然没有明确规定距离,但是建议不要超过300mm,否则最好加上IIC中继芯片。

二、IIC物理层接线

从上图可以看出,在IIC物理层有主机(MCU)、从机(IIC器件);2条总线,SCL(时钟线)和SDA(数据线)及上拉电阻(必接4.7K-10K)。
    所有接到I2C总线设备上的串行数据SDA都必须接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。I2C总线上的每个设备都自己一个唯一的地址,来确保不同设备之间访问的准确性。器件的物理地址是器件厂商出厂设定好的,须按照IC手册设定。
    在IIC总线中可以接多个主机,其中任何一个能够进行发送和接收的设备都可以成为主总线。一个主机能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主机控制。

---------------------------------------------------------------------------------------------------------------

三、IIC协议层
    IIC 总线在传送数据过程中共有三种类型信号, 它们分别是:启始信号(Start)、终止信号(Stop)和应答信号(Ack)。
启始信号:SCL 为高电平时(1),SDA 由高电平向低电平跳变,表示起始信号,接下来可以进行数据传输,必须有;
终止信号:SCL 为高电平时(1),SDA 由低电平向高电平跳变,表示终止信号,表示结束数据传输,必须有;
应答信号:接收端器件(不论主从)在接收到 8bit 数据后,向发送端器件(不论主从)发出特定的低电平脉冲,表示已收到数据。发送端向接收端发出一个信号后,等待接收端发出一个应答信号,发送端接收到应答信号后,根据实际情况作出是否继续传递数据的判断。若在约定的等待周期内未收到应答信号,判断为接收端接收数据不成功。
非应答信号:若接收端希望结束数据传输,则可以向发送端发一个“非应答信号NAck”,接收端收到此信号后会产生一个终止信号,结束传输。
IIC 总线时序图

启始信号:SCL高电平(1)状态下,SDA由高(1)变低(0),保持至少4.7us后,产生启始信号;程序表示如下
    void IIC_Start()        
   {
       SDA=1;             //确保SDA线为高电平
       SCL=1;             //确保SCL高电平
       delay_us(5);       //保持5us
       SDA=0;             //在SCL为高时拉低SDA,产生启始信号
       delay_us(5);
   }
终止信号:SCL高电平(1)状态下,SDA由高(0)变低(1),保持至少4.7us后,产生终止信号;程序表示如下
    void IIC_Stop()         
   {
       SDA=0;             //确保SDA线为低电平
       SCL=1;             //确保SCL高电平
       delay_us(5);
       SDA=1;             //在SCL为高时拉高SDA线,产生终止信号
       delay_us(5);     
    }
应答信号:主机SCL拉高,读取从机SDA的电平,为低电平(SDA=0)表示产生应答,为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节,可以继续发送;若为高电平(SDA=1)时,为非应答位(NACK),一般表示接收器接收该字节没有成功,结束发送。如下图

每发送一个字节(8个bit)后,在一个字节传输的8个时钟后的第九个时钟期间,接收器接收数据后必须回一个ACK应答信号给发送器,这样才能进行数据传输。程序表示如下:
//主机产生应答信号Ack
void IIC_Ack(void)
{
   SCL=0;                          //先拉低SCL,使得SDA数据可以发生改变
   SDA=0;                          //SAD=0,产生应答信号 
   delay_us(2);
   SCL=1;

   delay_us(5);
   SCL=0;                         //一个SCL时钟等待周期
   delay_us(5);
   SDA=1;                         //释放SDA总线控制权

}
    有时候从机因某种原因不需要对主机应答时,须将SDA置为高电平(1),由主机产生终止信号结束数据传输。程序表示如下:
//主机产生非应答信号NAck
void IIC_NAck(void)
{
   SCL=0;                          //先拉低SCL,使得SDA数据可以发生改变
   SDA=1;                          //SAD=1,产生非应答信号 
   delay_us(2);
   SCL=1;
   delay_us(5);
   SCL=0;
   delay_us(5);
}

    在实际写程序时,我们可以用一个等待应答子程序来判断应答信号,程序如下:
等待接收端的应答信号:应答0,非应答1
u8 IIC_WaitAck (void)
{
    u8 temptime;                  //临时计时器
    SDA=1;                        // 释放SDA线的控制权              
    SCL=1;
    delay_us(5);
    if(SDA_READ==1)               // 如果读回的SDA=1,则为非应答
     {
       temptime++;
       if(temp>250)               //超时,这里250大概数参考
                    {
           IIC_Stop();            //停止传输
           return 1;
                    }
     }
     SCL=0;                      // SCL拉低
     delay_us(5);     
     return 0;                   //如果读回的SDA=0,则为应答
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多