【总线】IIC学习笔记
- 参考链接
- IIC总线介绍
- IIC总线时序
- 1.空闲信号
- 2. 启动信号与停止信号
- 3.数据的有效性
- 4.应答信号
- 5.七位地址传输
- IIC读写过程(AT24C02举例)
- IIC读过程
- IIC写过程
- 正点原子IIC驱动问题
- 1、IIC停止信号问题
- 2、IIC-AT24C02的器件地址发送的疑惑
参考链接
IIC时序图+代码
IIC总线+上拉电阻计算
IIC通信协议
IIC学习
IIC总线介绍
IIC是一种串行、半双工的总线。通信距离短、通信速度低的场合。
IIC有两根线,一个是SDA,用于收发数据的数据线;一个是SCL,用于双方通信时钟的同步。
IIC是一种多主机总线。连接在IIC总线上的器件分别为主机和从机。
主机有权启用和结束一次通信,从机只能被主机呼叫。
当总线上有多个主机同时启用总线时,IIC具有冲突检测和仲裁的功能。IIC通信的同步和仲裁是自动进行的
。
每个连接到IIC总线的器件都有一个唯一地址(7bit),每个器件就可以作为主机也作为从机,但是同一时刻只能有一个主机。
IIC总线上的器件删除或者添加,不会影响其他器件的正常工作。
总线空闲时,设备都是开漏输出
,由电路中的上拉电阻使SDA和SCL都保持高电平
。当任一设备输出低电平时都会使总线上的信号线变低。
IIC三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达3.4M/s,但目前大多IIC设备尚不支持高速模式。连接到总线的接口数量只由总线电容是 400pF 的限制决定。
IIC总线时序
1.空闲信号
在总线未被主机占用时,电路中的上拉电阻使 SDA 和 SCL 线保持高电平状态,并等待主机启用总线。
2. 启动信号与停止信号
起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态 在停止条件的某段时间后,总线再次处于空闲状态。
① 启动信号:在SCL线是高电平时,SDA线从高到低的跳变;
② 停止信号:在SCL线是高电平时,SDA线从低到高的跳变。
3.数据的有效性
在IIC总线进行数据传输时,SCL时钟信号为高电平期间,SDA数据线上的数据必须保持稳定。只有在SCL时钟线上的信号为低电平期间,SDA数据线上的电平状态才允许变化。
SDA数据线在SCL的每个时钟周期传输一位数据。
4.应答信号
发送器每发送一个字节,会在第九个时钟脉冲期间释放数据线(低电平),由接收器反馈一个响应(ACK/NACK)。
① ACK(应答信号):应答信号为低电平(0)时,表示接收器已经成功地接收了该字节;
② NACK(非应答信号):应答信号为高电平(1)时,一般表示接收器接收该字节没有成功。
5.七位地址传输
起始信号后发送的第一个字节(8位)是从机地址+数据方向位。
从机地址共有 7 位,紧接着的第 8 位是数据方向位 R/ W(表示从机进行读/写)操作。
“0” 表示“写”发送数据,“1” 表示“读”请求数据。
IIC读写过程(AT24C02举例)
本小节图片来源:IIC协议实战项目
IIC读过程
首先,主机发起启动信号。
然后,主机发送器件地址和写方向(一字节)的广播器件寻址,并等待从机应答。
从机应答后,主机发送要读取的数据存储地址,并等待从机应答。
从机应答后,主机再次发起启动信号。
然后,主机发送器件地址和读方向(一字节)的广播器件寻址,并等待从机应答。【更换接收方向】
然后,主机通过SDA读取一个字节的数据。
数据接收完毕后,如果主机不想在接收数据了,需要回复非应答信号。
最后,主机发起停止信号。
IIC写过程
首先,主机发起启动信号。
然后,主机发送器件地址和写方向(一字节)的广播器件寻址,并等待从机应答。
从机应答后,主机发送要写入的数据存储地址,并等待从机应答。
从机应答后,主机发送想要写入的数据,并等待从机应答。
从机应答后,主机发起停止信号。
正点原子IIC驱动问题
1、IIC停止信号问题
上述原版驱动代码。可以发现,一开始两根线都是低电平,并等待了4us。
然后SCL高,SDA立马拉高,并等待4us。停止信号是,在SCL为高的情况下,SDA由低向高转变。这么短的时候,留给SDA的时间太短了吧?
我搜索查到,有些朋友说,慢速没问题,时钟高了就有问题。所以,还是应该注意下。
我觉得应该如下:
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;
IIC_SCL=1;
delay_us(4);
IIC_SDA=1;
delay_us(4);
}
2、IIC-AT24C02的器件地址发送的疑惑
在IIC_Send_Byte(0XA0+((ReadAddr/256)<<1))中,0XA0是器件地址,为什么还要加上(ReadAddr/256)<<1?
在使用AT24C02的情况下,这句话并没有用。
因为24C02,一共2Kbit的大小,也就是256字节。所以用一个字节就能把它全部的读写地址表示了。
但是对于04,一共有4Kbit的大小,也就是512字节,一个字节并不能表示其全部的读写地址,得需要9bit才行。
这就跟这个IIC器件有关了,对于高容量eeprom,它有大小分区。
它将读写地址的一部分放到了器件地址中,具体的可以看数据手册。