购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.8 I 2 C总线

I 2 C总线(Inter-Integrated Circuit Bus)是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的元器件之间传送信息。某些书籍或者文档中也写作IIC,读作“I方C”。

I 2 C是嵌入式中最常见的总线,也是最重要的总线通信协议之一。很多传感器、外围芯片使用I 2 C协议。它具有如下特点:

(1)硬件线路简单:I 2 C总线只需要一根数据线和一根时钟线共两根线。

(2)灵活:数据传输和地址设定由软件设定,非常灵活。总线上的元器件增加和删除不影响其他元器件正常工作。

(3)可以连接设备数量多:连接到相同总线上的IC数量只受总线最大电容的限制。

4.8.1 I 2 C元器件地址

I 2 C总线是一个主从结构的总线,所有的数据传输都必须由主机发起,通常单片机做主机,其他连接在I 2 C总线的设备称之为从机或者元器件。

I 2 C还有一个重要的概念:元器件地址。连接在I 2 C总线上的设备,除了主机之外,每个元器件都有自己的地址。主机想要和某个元器件通信时,先往I 2 C总线发送元器件地址。

I 2 C元器件地址一般为8位,最后一位是读写标志位。0表示主机要读取元器件的数据;1表示主机要往元器件写数据。

4.8.2 I 2 C时序

I 2 C总线只需要两根线,分别是时钟线(SCL)、数据线(SDA)。其中时钟线提供时间周期,时间周期越短则数据传输速率越快。数据线用来传输起始位、应答位和数据等。时序如图4.34所示。

数据格式主要有起始位、停止位、数据位、应答位(ACK)、NACK。

1.起始位

当主机想要启动I 2 C数据传输时,需要先往I 2 C总线发送起始位。起始位的条件是SCL线为高电平时,SDA线从高电平向低电平切换。

图4.34 I 2 C时序图

2.停止位

当主机想要终止I 2 C数据传输时,需要往I 2 C总线发送停止位,释放I 2 C总线的占用。停止位的条件是SCL线为高电平时,SDA线从低电平向高电平切换。

3.数据位

SDA数据线上的每字节必须是8位,每次传输的字节数量没有限制。每字节后必须跟一个响应位(ACK)。首先传输的数据是最高位(MSB),SDA上的数据必须在SCL高电平周期时保持稳定,数据的高低电平翻转变化发生在SCL低电平时期。

4.应答位

每字节传输必须带响应位,相关的响应时钟也由主机产生,在响应的时钟脉冲期间(第9个时钟周期),发送端释放SDA线,接收端把SDA拉低。

5.NACK位

以下情况会导致出现NACK位:

(1)接收机没有发送机响应的地址,接收端没有任何ACK发送给发射机。

(2)由于接收机正在忙碌处理实时程序导致接收机无法接收或者发送。

(3)传输过程中,接收机识别不了发送机的数据或命令。

(4)接收机无法接收。

(5)主机接收完成读取数据后,要发送NACK告知从机结束。

4.8.3 模拟I 2 C

I 2 C属于比较简单的总线,完全可以根据I 2 C的时序,使用I/O模拟I 2 C。本文将使用STM32的GPIO口实现模拟I 2 C的功能,帮助读者理解I 2 C的时序控制。

打开Chapter4\05_I2C_24c02\mdk\IIC24c02.uvproj工程文件,接着打开24c02.c文件,模拟I 2 C的代码都在这个文件中。

1.I 2 C初始化

I 2 C的初始化部分代码主要是对STM32的GPIO进行初始化。GPIOB_9作为数据引脚(SDA),GPIOB_8作为时钟引脚(SCL),代码如下:

2.起始信号

当SCL为高电平时,SDA出现一个下降沿表示I 2 C总线启动信号,代码如下:

IIC_SCL指I 2 C的SCL引脚,IIC_SDAOUT指I 2 C的SDA引脚输出,在24c02.h文件中分别被定义成PBout(8)和PBout(9),代码如下:

IIC_SDAOUT=1表示SDA引脚输出高电平。这里是GPIO输出高低电平的另外一种写法,等价于之前的GPIO_WriteBit(GPIOB,GPIO_Pin_9,Bit_SET)。

IIC_Start函数使用SDA、SCL引脚,通过输出高低电平和延时的操作,模拟了I 2 C启动信号。其时序如图4.35所示。

图4.35 I 2 C启动信号时序

3.停止信号

当SCL为高电平时,SDA出现一个上升沿表示I 2 C总线停止信号,代码如下:

4.应答信号

I 2 C总线上的所有数据都是以8位字节传送的,发送器每发送一字节,在响应的时钟脉冲期间(第9个时钟周期),由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK)。主机等待从机应答信号的相关代码如下:

5.数据位发送

在I 2 C总线上传送的每一位数据都有一个时钟脉冲相对应。在SCL呈现高电平期间,SDA上的电平必须保持稳定,低电平为数据0,高电平为数据1。只有在SCL为低电平期间,才允许SDA上的电平改变状态。逻辑0的电平为低电平,而逻辑1则为高电平。时序如图4.36所示。

图4.36 数据位发送时序

6.发送一字节

I 2 C写一字节相当于往I 2 C总线发送了8个数据位,根据图4.39数据位发送时序,我们可以用I/O模拟,代码如下:

其中比较关键的代码是Senddata的移位操作。

根据&和﹥﹥的特性,(Senddata&0x80)﹥﹥7相当于保留Senddata的最高位,其他位清零,同时再把最高位右移到最低位。相当于把Senddata最高位的数值赋给IIC_SDAOUT,从而实现SDA引脚根据Senddata的最高位输出响应的高低电平。

之后Senddata=(Senddata﹤﹤1),把Senddata的第2高位通过左移1位的方式,使Senddata的第2高位变成最高位。

再通过for循环,重复这两步操作,把Senddata的每一位都发送出去。为了方便理解,我们假设Senddata等于170,十六进制为:0xAA,二进制为:10101010。整个for循环的移位操作可以用图4.37直观地表示出来。

图4.37 移位操作流程图

7.读一字节

读时序和发送时序相同,不同的是发送时需要在SCL低电平的时候更改SDA数据位,而读时需要在SCL高电平的时候读取SDA数据位。同时,每读取一位数据,都需要左移1位,保证高位在前。读完数据后需要发送ACK或者NACK应答信号。代码如下:

4.8.4 小结

I 2 C是嵌入式中最常见的总线通信协议,读者需要熟练掌握,了解I 2 C的时序,并能使用I/O模拟I 2 C操作。 azbeht+W9wH1sCmv2nKkrOPFhNp3lTXRPtP2rii9TI3ZglYD14mqXvOSGlObmK4S

点击中间区域
呼出菜单
上一章
目录
下一章
×