拓冰建站拓冰建站
首页 / 资讯中心 / 正文

协议解析-IIC篇

以下内容是我对于学习笔记的整理和补充仅代表我个人还比较浅薄的认知观点如有错误还请指出感谢各位。1. IIC基础最基础特殊情况不予考虑放置于复杂情况SCL-时钟线从机只能读取不能操控开漏输出常态高电平SDA-数据线从机只有在主机允许的情况下才可以短暂被动控制开漏输出高位先行起始条件SCL高电平期间SDA从高电平切换到低电平终止条件SCL高电平期间SDA从低电平切换到高电平发送流程(8次后会有位接收应答ACK)接收流程(8次后会有位发送应答ACK)发送应答和接收应答发送应答是告诉从机是否还要继续发送接收应答是询问是否接收到对于硬件iic而言我们需要配置好引脚的状态和IIC速度占空比应答地址位数所有的开始条件结束条件位发送接收条件都已经进行了函数封装我们要做的就是注意时序每次调用函数之后需要检查对应的标志位再进行下一步操作。时序解读我们知道IIC是支持多从机的所以每一个从机都会有厂商初始的地址作为区分一般就是7位加上最低一位的010写入1读取从而变成8位。1.当前地址读主-7(地址)1(读写位1)从-1应答位从-8(数据)2.指定地址写主-7(地址)1(读写位1)从-1应答位主-8(指定地址)从应答主-(数据)3.指定地址读主-7(地址)1(读写位1)从-1应答位主-8(指定地址)从应答主-起始信号主-7(地址)1(读写位1)从-1应答位从-8(数据)我特意使用颜色进行了区分可以发现指定地址读就是前两种的糅合以起始信号取代了指定地址写的最后一个数据写入用以连接。之所以这么做就是因为地址指针从设备中指针指向哪里当前地址的数据操作就在哪里但是1时序直接就是读取没有操作指针的指向只有2操作了但是我不要写入数据所以做法就是在2时序发送指定地址后地址指针已经指向了我要的地址我就直接取消当前操作主机主动发送起始信号这样再1时序当前地址读取的就是我要的指定地址的数据了。这三种时序可以看到结尾我都没有加上停止标志比如1时序3时序你就可以直接发应答0从机会自动地址1继续发送数据给主机达到连续读的效果。2时序也是一样的操作。查了资料发现理论上存在第四种当前地址写的时序但是我们一般不会去用因为数据管理问题我们需要明确的一个地址来存放数据随便当前位置写就相当于是一个黑盒不知道写在哪里不说有可能还会破坏已有的数据或者写入了一些数据敏感的地方所以不需要去关心这一种时序。补充7位地址不够也会有用16位来发送地址但是这样需要规定发送的第一个字节必须是11110xx(读写位)所以16位的地址实际上是11110xx(0,1)xxxxxxxx10位地址要注意一下。上拉电阻也是一个需要注意的点在实际电路中电压的变化并不像逻辑01变化直上直下实际的输出波形都是有一个充放电过程的这在通信过程中就很重要因为如果这个电压变化的过程慢了总线被释放的时候电压来不及变回高电平我们就开始读取就会导致我们总线上的数据有问题。简单的理解就是上拉电阻越大电路中的电流就越小相同情况下电压的变化就会越小也就是慢所以使用小的电阻可以带来更快的电压变化也就可以使用更高的频率来通信但是如果只追求快小电阻带来的就是大电流对于电路而言功耗就是一个大问题器件也没法承受甚至可能没法正常把总线拉到地综合以上两者的考虑才会有我们常见的4.72.2K的电阻前者常用于正常模式后者则是快速模式使用。软件iic对于有独立时钟线的iic而言我们可以根据以上的几种时序来实现软件iic。首先配置要使用的引脚为开漏输出即可维持常态下scl和sda的高电平以下SCL和SDA都是代指对应的模拟GPIO引脚。SCL交替拉低即可实现时序模拟SDA交替拉低即可实现数据01的输出数据的读取可以根据SDA引脚调用GPIO_ReadInputDataBit库函数读取以下不再详细赘述上面的几种时序只以发送和接收作为参考实际操作中的时序对应上面即可。发送直接控制sda拉低电平产生开始信号在拉低scl期间sda输出对应电平再控制scl拉高从机就可以读取重复以上流程8次即可发送一个完整字节。保持SCL的信号输出等待从机sda应答结束通信直接放开scl之后放开sda产生结束时序结束通信。接收从机发送主机只需要控制scl输出上下电平输出时序在高电平期间调用库函数读取数据即可重复8次拼成一个字节。再根据需要发送对应应答即可。简单小结IIC之所以应用广泛就在于其极其精简的电路设计只需要两根引脚还可以挂载多部从设备都是共用的一根信号线理论上哪怕7位地址也有128个完全够用。但是这样带来的问题就是其通信的速度会比较慢一般只有100-400KHz所以其使用场景需要考虑到外设的数据量问题。有人要极简的引脚那也会有人要更高的速度这就是SPI的使用了。2.复杂IIC这部分内容是对上述基础iic的补充由于本人目前暂未实际遇到相关问题这里只作为一个简单的了解后续实际遇上我再进行补充。时钟拉伸基础我们讲过SCL是不能被从机操控的所以主机对于从机有着绝对的操控权但是个别情况下主机有时候发送的消息过快导致从机来不及接收需要暂停一下所以这个时候就需要从机来操纵SCL了。我们知道SCL在高电平期间是用于读取SDA既然从机来不及读取从机就可以手动拉低SCL让主设备等待给事件给从机读取数据。多主机开发过程中我们也会遇到需要从机主动发起通信的情况这种时候就需要多主机也就是让从机变成主机遇到多主机同时通信我该如何判断谁是主呢开漏输出告诉了我们答案线与。开漏输入是一个弱上拉的输出他就相当于一个受气包总是习惯于说1但是任何人挂载的设备哪怕只要有一个说我要0他就会变成0。这也就是为什么IIC协议允许多主机通信的同时还不怕多主机同时写SDA导致数据出现问题假设有多个主机一起发送数据SDA被多人写入这些人中如果大家的数据都是一样的那没有问题但是只要这个过程中任何一个人发送的数据是0而别人是1总线就会被拉低输出0那发1的主机就会自动出局直到产生停止标志之后才可以继续参与竞争这也就是为什么SCL和SDA都需要配置为开漏输出。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门