第8章 I2C总线AT24C02芯片应用
8.1I2C总线概述
-
I2C总线介绍
I2C总线是近年来微电子通讯控制领域广泛采用的一种新型总线标准,它是同步通信的一种特殊形式,具有接口线少、控制简单、器件封装形式小、通信速率较高等优点。在主从通信中,可以有多个I2C总线器件同时接到I2C总线上,所有与I2C兼容的器件都具有标准的接口,通过地址来识别通信对象,使它们可以由I2C总线互相直接通信。
I2C总线有数据线SDA和时钟线SCL两条线构成通信线路,即可以发送数据,也可以接收数据。在CPU与被控IC(被控元器件)之间、IC与IC之间都可以进行双向传送,各种被控器件均并联在总线上,但每个器件都有唯一的地址。在信息传输过程中,I2C总线上并联的每个器件,计时被控器(或主控器),也是发送器(或接收器),这取决于它要完成的功能。CPU发出的控制信号分为地址码和数据码两部分:地址码用来选址,即接通需要控制的电路;数据码是通信的内容,这样各IC控制电路虽然挂在同一条总线上,却彼此独立。
-
I2C总线硬件结构
SCL是时钟线,SDA是数据线。
总线上各器件采用漏极**开路结构(漏极开路(Open Drain)即高阻状态,适用于输入/输出,其可独立输入/输出低电平和高阻状态,若需要产生高电平,则需使用外部上拉电阻或使用如LCX245等电平转换芯片。)**结构与总线相连,因此SCL和SDA均需接上拉电阻。总线在空闲状态下均保持高电平,连到总线上的任一器件输出的低电平,都将使总线的信号变低。
I2C总线支持多主和主从两种工作方式,通常为主从工作方式。**在主从工作方式中,系统中只有一个主器件(单片机),其他器件都是具有I2C总线的外围从器件。**在主从工作方式中,主器件启动数据的发送(发送启动信号),产生时钟信号,发出停止信号
-
I2C总线通信格式
下图为I2C总线上进行一次数据传输的通信格式。
-
数据位的有效性规定
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
-
总线空闲状态
I2C总线的SDA和SCL两条线处于高电平的时候,规定为总线的空闲状态,也称为释放总线。同理,SDA和SCL哪条线处于高电平了,哪条线也就是被释放了。
-
发送启动信号
再利用I2C总线进行一次数据传输时,先有主机发出启动信号,启动I2C总线。在SCL为高电平期间,SDA出现下降沿则为启动信号。此时具有I2C总线接口的从器件会检测到该信号
-
发送寻址信号
主机发送启动信号后,在发出寻址信号。器件地址有7位和10位,这里介绍7位。寻址字节的位定义如下。
寻址信号由一个字节构成,高7位为地址位,最低位为方向位,用以表明主机与从器件的数据传送方向。方向位为0时,表明主机接下来对从器件进行写操作;方向位为1,表明主机接下来对从器件进行读操作。
主机发送地址时,总线上的每一个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据方向位(R/W位)将自己确定为发送器或接收器。
从机的地址码由固定部分和可编程部分组成,其中可编程部分决定了可接入总线该类器件的最大数目。如果一个从机的7位寻址位有4位是固定位,3位是可编程位,这是仅能寻址8个同样的器件,即可有8个同样的器件接入到该I2C总线系统中。
-
应答信号
I2C总线协议规定,每传送一字节数据(含地址及命令字)(8个时钟周期)后,由接收器反馈一个应答信号(第9个时钟周期),已确定数据传送是否被对方受到,**应答信号由接收设备产生,在SCL信号为高电平期间,接收设备将SDA拉为低电平,也就是应答信号为低电平,表示数据传输正确,产生应答。应答信号为高电平时,规定为非应答信号,一般表示接收器没有成功接收该字节。**当主机作为接收设备时,主机对最后一字节不应答, 以向发送设备表示数据传送结束。
无论是以上那种情况,都会终止数据传输,这时主机或是产生停止信号释放总线,或是产生重新开始信号开始一次新的通信。
-
数据传输
主机发送寻址信号,并得到从器件应答后,便可进行数据传输,每次1位,每个位传输时间对应一个时钟周期,也就是一次时钟脉冲送一个位,那么送完一个字节要8个位,也就是8个时钟周期,那么在第9个时钟周期的时候释放数据线SDA,由接收器反馈一个应答信号,但每次传输都应在得到应答信号后再进行下一字节传送。
-
发送停止信号
在全部数据传送完毕后,主机发送停止信号,即在SCL为高电平期间,SDA上产生一个上沿信号,停止时序图如下。
8.2单片机模拟I2C总线通信
市面上许多单片机是由I2C总线接口的,工作的时候总线的状态有硬件检测控制,不用人为干涉。但是我们51单片机是没有I2C总线接口的,但是我们可以通过软件模拟I2C总线的工作时序,从而达到控制I2C总线接口器件。
为了保证数据传送的可靠性,标准I2C总线的数据传送有严格的时序要求。单片机在模拟I2C总线通信时,需写出如下关键部分的程序:总线初始化、启动信号、应答信号、停止信号、写1字节、读1字节。
-
总线初始化
void init() { SCL=1; delay(); SDA=1;//将总线都拉高以释放总线 delay(); }
-
启动信号
void start() { SDA=1; delay(); SCL=1; delay(); SDA=0; delay(); }
-
应答信号
void respons() { unsigned char i=0; SCL=1; delay(); while((SDA==1)&&(i<256)) i++; SCL=0; delay(); }
这里我们要注意一点,我们接收应答信号,是从器件将SDA拉低,所以我们这里是要接受到SDA拉低的信息。如果少了这个while函数,那么主机收不到应答信号时,就会一直停留在这里,我们让他一段时间接收不到应答信号后就自动退出。
-
停止信号
void stop() { SDA=0; delay(); SCL=1; delay(); SDA=1; delay(); }
-
写字节
-
主机在检测到总线为“空闲状态时”(即SDA、SCL均为高电平)时,发送一个启动信号,开始通信
-
主机接着发送一个寻址信号。该字节由7位外围器件地址和1位读写控制位R/W组成(此时R/W=0,表示主机对从机进行写操作)
-
相对应的从机收到寻址信号后向主机回馈应答信号 ACK(ACK=0),寻址信号也是1字节,所以也要反馈
-
主机收到从机的应答信号后开始发送第一个字节的数据
-
从机收到数据后返回一个应答信号 ACK
-
主机收到应答信号后再发送下一个数据字节
-
当主机发送最后一个数据字节并收到从机的 ACK 后,通过向从机发送一个停止信号P结束本次通信并释放总线。从机收到P信号后也退出与主机之间的通信
void write_byte() { unsigned char 1
-