1.IIC
1.1什么是IIC?
同步半双工通信协议,适用于小数据和短距离传输。
1.2 IIC需要几条线?
IIC总共有2条通信总线(SDA,SCL),SCL为时钟同步线,用于主机和从机间数据同步操作;SDA为数据线;
1.3 为什么上述两条线要用开漏输出且配上上拉电阻呢?
①多口同线,实现“线与”,防止短路
多个设备挂载在同一个总线上,如果采用推挽输出,其中一个设备输出高电平,另一个设备输出低电平就会造成短路。而开漏输出允许多个设备共享同一个总线或信号线,通过合理的电平控制,实现对总线或信号线的协调使用,避免冲突和干扰。
线与:只要有一个设备输出低电平,那么总线便会变成低电平
②无数据传输时,总线一直保持高电平,减少数据干扰
1.4 IIC最大支持的挂载设备数?
地址组成:7+W/R,高7位为设备地址,最低位为读写位。读写位用低电平0表示写,高电平1表示读。
最大挂载设备为:2^7-1 = 127,剩下一个用作广播地址。 广播只能传输控制命令,如复位,不能传数据。
实际上,已有IIC的设备种类远远多于这个限制,在一条总线上出现相同的地址的IIC设备的概率相当高。IIC标准提出10位的地址方案。当使用10位设备地址,可以挂载的设备理论上可以达到1024个。
10位地址对IIC协议的影响有两点:
1.地址帧为两个字节长,原来的是一个字节
2.第一个字节前五位最高有效作用为用作10位地址标识,约定是“11110”
际设计中的经验值建议不超过8个设备,受到总线电容和总线电压的限制,信号的质量和传输的可靠性可能会受到影响。
1.5 IIC的速度
标准:100 kb/s,适用较长的总线和较慢的设备,如LCD显示屏、温度传感器等
高速模式:3.4Mb/s(可双向传输的最快)适用于对数据传输速度要求非常高的设备,如高清视频处理器、高速闪存等
超快速模式:5Mb/s(只适用于单向传输)适用于需要超高速数据传输的设备,如图像处理器、高速网络接口等
注:上拉电阻越小,电流越大,电平转换效率越高,总线速率越高
1.6 IIC的信号与时序
Start 起始信号
开始条件:SDA,SCL都为高 11
起始信号:SCL为高电平时,SDA从高到低。 01
结束条件:SDA和SCL都处于低电平。 00
void IIC_Start(void)
{
SDA_H; // 拉高SDA
SCL_H; // 拉高SCL 先拉高两条线是为了确保空闲状态两个都是高电平
delay_us(speed); // 延时控制速度
SDA_L; // 启动信号,SCL高电平的时候,SDA从高电平变为低电平
delay_us(speed); // 延时,控制速度
SCL_L; // 为了准备下一个时钟周期以及接下来的数据传输做准备。
}
Stop 停止信号
开始条件:SDA,SCL都为低
时钟线拉高:SCL拉高先
结束信号:在时钟线为高的时候,SDA从低变高
void IIC_Stop(void)
{
SDA_L; //
SCL_L; // 拉低SCL代码是为了确保从设备能够检测出SDA的变化
delay_us(speed);
SCL_H; //SCL线
SDA_H; // 拉高SDA线,当SCL为高时,SDA线一个上升沿代表停止
delay_us(speed);
}
ACK 应答信号
应答信号为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;
有效应答:SDA为低电平,SCL经历一个完整的时候, 也就是SCL为高电平时候,SDA为低电平
//产生ACK应答,读取从机一字节数据后还要接着读的时候使用
//SCL在SDA一直为低电平期间完成低高电平转换
void IIC_ACK(void)
{
SCL_L; // 拉低SCL是为了让从设备检测到SDA的变化
SDA_L; // SDA为低电平表示ACK应答信号
delay_us(speed);
SCL_H; // 经历一个完整的高电平时钟
delay_us(speed);
SCL_L;
}
//不产生ACK应答,读取从机一字节数据后不读了的时候使用
//SCL在SDA一直为高电平期间完成低高电平转换
void IIC_NACK(void)
{
SCL_L; // 拉低SCL是为了让从设备检测到SDA的变化
SDA_H; // SDA为高电平表示ACK应答信号
delay_us(speed);
SCL_H; // 经历一个完整的高电平时钟
delay_us(speed);
SCL_L;
}
//等待ACK应答
//发送完一个字节后(释放SDA)的下一个时钟高电平时期,读取SDA电平,0为收到应答
bool IIC_Wait_ACK(unsigned int timeOut)
{
SDA_H;
delay_us(speed);
SCL_H;
delay_us(speed);
while(SDA_R)
{
if(--timeOut)
{
printf("Wait IIC timeOut\r\n");
IIC_Stop(); // 超时未收到应答,停止总线
return IIC_Err; //返回失败
}
delay_us(speed);
}
SCL_L;
return IIC_OK;
}
数据信号
发送数据和接收数据时通用。当SCL为高电平,如果SDA始终为高电平时表示逻辑1,如果SDA始终为低电平表示逻辑0.
IIC发送与接受数据帧
起始条件+发送要读取的地址(0,为发送数据)+接收应答位+读取的8位数据+发送应答位(0, 应答)+应答位(1,不应答,因为想停止读取)+停止条件
1.7 IIC仲裁机制
“低电平优先”,谁先发送低电平谁就掌握对总线的控制
通过线与逻辑就可以仲裁主机,如下图所示,在第四个红框的时候,主器件A和主器件B发送的数据为高电平,主器件C为低电平。此时数据线呈现低电平,A和B与数据线电平不相同,退出竞争。C相同获得数据线的归属权。
1.8 IIC时钟同步
时钟同步发生在仲裁期间,会有多个主机同时发送往SCL上发送时钟信号,需要时钟同步调整速率一致,具体来说就是SCL线上的低电平时间是由时钟低电平最长的设备决定,SCL的高电平则是由高电平时间最短的期间决定 ,通过这一方法可以同步所有设备的时钟,更好的实现仲裁
1.9 时钟拉伸
时钟拉伸就是完成时钟同步中的事,将主从设备间数据传输同步。
时钟拉伸是用于调整主从设备速率不一致的时候发生的,当从设备速度较慢或需要处理其他事情的时候,从设备主动拉低SCL线通知主设备,直到从设备释放SCL,主设备才进入下一个时许,时钟拉伸解决了I2C主从设备的数率同步问题,使得数据传输更可靠。
1.10 IIC优势
简单且灵活:I2C仅需要两根线(SDA和SCL)来进行通信,使得硬件连接和布线变得简单。
可靠性高:I2C协议采用了主从架构,由主设备控制总线上的数据传输。
多设备支持:IIC支持一主多从,每个设备都有唯一的地址。
低功耗:I2C在基本模式下使用了开漏输出结构,使得设备在非活动状态下可以撤离总线,从而降低功耗。
1.11软件IIC硬件IIC区别
硬件IIC是通过专门的硬件电路实现的,而软件IIC是通过软件控制GPIO口管脚来模拟IIC协议的时许的。
硬件IIC的优势:高速传输 + 低占用率(不需要CPU的干预)+稳定性高(时许由硬件控制,不受外部干扰)
软件IIC的优势:灵活性高(任意GPIO口)+ 可移植性强 + 适用范围广 。
1.12配置失败,一般怎么排查
硬件连接问题
电源供电问题
地址设置问题
软件程序问题
检查时序