一、IIC基本介绍
1、IIC通信接口
• I2C(Inter IC Bus)是由Philips公司开发的一种通用数据总线
• 两根通信线:SCL(串行时钟线)、SDA(串行数据线)
• 同步,半双工
• 带数据应答
• 支持总线挂载多设备(一主多从、多主多从)
一主多从:单片机作为主机,主导I2C总线的运行,挂载在I2C总线的所有外部模块都是从机,从机只有被主机点名之后才能控制I2C总线,不能在未经允许的情况下去碰I2C总线,防止冲突。
多主多从:在总线上的任何一个模块都可以是主机
2、IIC通信接口的特点
①.双线制。一根是SCL,作为时钟同步线;一根是SDA,作为数据传输线。
②.半双工。因为真正做数据传输的只有SDA,所以使用IIC通信的双方能双向通信,但不能同时
③.同步通信。有同步信号线SCL,通信协议时序严格,SDA在通信双方初步同步后在SCL的时序下按位传输数据。
④.通信为主从机模式。支持一主多从模式,通信过程中SCL一直由主机控制,而SDA则不固定
⑤.从属设备地址。因为支持主从机模式,所以IIC总线中主机在通信过程中为了确保找到具体的从机,需要先知道该从机的设备地址(Device Address)而主机则不需要设备地址。
二、IIC从设备的地址
1、设备地址的组成
①从机地址是7位,读写位是1位。
②读写位
因为lIC是半双工通信接口,所以在主机开始与从机通信前,主机需要告诉从机此次通信是谁做为发送方,谁做为接收方。故有了读写位。
其中最低位为0表示写模式----主机作为发送方;1表示读模式----主机作为接收方
2、设备地址的作用
用于在IIC总线上唯一标识每个从设备,以便主设备能够正确地与特定从设备进行通信。通过设备地址,主设备可以向特定的从设备发送数据或请求数据,从而实现设备之间的通信和数据交换。设备地址通常是一个唯一的数字或编码,每个从设备都有一个独特的地址,主设备根据这个地址来识别和访问相应的从设备。
三、AT24COX
1、 AT24C02介绍
AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息
存储介质:E2PROM
通讯接口:I2C总线
容量:256字节
2、硬件原理图
3、设备地址
写模式设备地址:OxA0
读模式设备地址:OxA1
2、时序单元
1、起始条件
在I2C 总线处于空闲状态时:SCL和SDA都处于高电平状态,是由SCL和SDA由外挂的上拉电阻拉高至高电平,总线处于平静的高电平状态。
主机需要进行数据收发时,当从机捕获到SCL高电平,SDA下降沿信号时,就会进行自身的复位,等待主机的召唤。然后在SDA下降沿之后,主机要再把SCL拽下来,拽下SCL:1、占用总线,2、方便拼接。
2、终止条件
SCL先放手,回到高电平;SDA再放手,回到高电平,产生一个上升沿。上升沿触发终止条件,同时终止条件之后,SCL和SDA都是高电平。
3、起始条件和终止代码实现
这些是封装的函数,还是对SCL、SDA的操作,根据时序看配置低电平还是高电平。
4、发送一个字节
主机如果想发送0,就拉底SDA到低电平;如果想发送1,就放手,SDA回到高电平,在SCL低电平期间,允许改变SDA的电平。当这一位的数据放好之后,主机就松手时钟线,SCL回到高电平。在高电平期间,是从机读取SDA的时候,所以高电平期间,SDA不允许变化。SCL处于高电平之后,从机需要尽快地读取SDA,一般在上升沿这个时刻,从机就已经读取完成了。主机在放手SCL一段时间后,就可以继续拉低SCL,然后传输下一位。
5、接收一个字节
SCL低电平期间,从机将数据位依次到SDA线上(高位先行),然后释放SCL,主机在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化。
6、发送应答和接收应答
• 发送应答:主机在接收完一个字节之后,在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答
• 接收应答:主机在发送完一个字节之后,在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA
四、AT24COX代码实现
指定地址写
void AT24C02_W_REG(uint8_t adress,uint8_t data) //指定地址写
{
MyI2C_Start(); //起始条件
MyI2C_SendByte(AT24C02_ADDR_W); //指定从机设备写的地址:10100000
MyI2C_ReceiveAck(); //主机接收从机的应答 判断从机是否收到
MyI2C_SendByte(adress);//指定内部地址
MyI2C_ReceiveAck();
MyI2C_SendByte(data); //写入的数据
MyI2C_ReceiveAck();
MyI2C_Stop();
}
指定地址读
uint8_t AT24C02_R_REG(uint8_t adress) //指定地址读
{
uint8_t data;
MyI2C_Start(); //起始条件
MyI2C_SendByte(AT24C02_ADDR_W); //指定从机设备写的地址:10100000
MyI2C_ReceiveAck(); //主机接收从机的应答 判断从机是否收到
MyI2C_SendByte(adress);//指定内部地址
MyI2C_Start(); //起始条件
MyI2C_SendByte(AT24C02_ADDR_R);//读从机的数据
MyI2C_ReceiveAck(); //接收应答,从机开始发数据
data = MyI2C_ReceiveByte(); //主机接收数据
MyI2C_SendAck(1);//参数1:不给从机应答
MyI2C_Stop();
return data;
}