凡亿教育 · 电子工程师实战教育品牌
嵌入式硬件培训:长沙/广州校区
|
课程咨询:15989478308(同微信)
免费领取课程大纲

I²C读寄存器,地址后为何还要重复起始?

I²C读寄存器,地址后为何还要重复起始?

EEPROM随机读先用写方向送内部地址,再以重复起始切换为读方向;第二个起始是同一组合事务中的方向切换点

0.png 

I²C写EEPROM正常,读却总从错误地址开始;逻辑分析仪上器件地址、SCL频率和ACK看起来都对。真正少的可能不是一个数据字节,而是内部地址之后那次重复起始。

很多人看到“读寄存器”,会直接发送器件地址加读位,然后等待数据。对带内部地址指针的EEPROM或寄存器器件,这只能从当前指针位置读,不能告诉从机目标地址在哪里。

随机读要经历两个方向阶段:先写地址指针,不写有效载荷;再重复起始并切到读方向。重复起始不释放总线,让从机把前面的内部地址与后面的读操作视为一笔组合事务。

第一步先确认器件地址与内部地址不是一回事

器件地址用于在总线上选中哪一颗从机,内部地址用于选择从机里的哪一个寄存器或存储单元。主机必须先发送器件地址加写位,获得ACK后再发送一个或多个内部地址字节。EEPROM容量不同,内部地址宽度也可能不同。

1.png 

1  24C02器件地址脚、SCL/SDA与上拉网络的硬件连接

资料中的24C02硬件图显示SCL、SDA上拉和器件地址脚。地址脚决定器件地址的一部分,读写位则位于地址帧最低位。把内部地址误当成第二个器件地址,是抓包时最常见的错位之一。

第二步在内部地址后发送重复起始

内部地址发送完成并收到ACK后,主机不发STOP,而是再次制造START条件。STM32示例代码在发送ReadAddr后明确调用第二次GenerateSTART,然后等待主模式选择事件。总线所有权仍在当前主机手中。

2.png 

2  代码在内部地址后再次产生START,再发送器件地址加读位

这次START允许主机重新发送同一器件地址,但把方向位改成读。若没有新的START,地址帧不会凭空重新开始;直接切换软件接收状态,并不能让从机理解总线方向已经改变。

**重复起始是协议事件,不是驱动函数里可有可无的一行。**

第三步切换读方向并处理末字节

重复起始后发送器件地址加读位,从机开始驱动SDA。主机每接收一个字节通常回ACK,表示还要继续;准备接收末字节时,要按控制器要求提前关闭ACK并安排STOP,避免多读或让总线状态机卡住。

3.png 

3  读流程清单把第二次起始、读方向和数据接收放在同一事务内

不同STM32系列的外设事件、标志清除顺序和末两字节处理存在差异,不能只复制旧库代码。稳定的做法是把总线时序图与当前芯片参考手册逐项对齐,再核对驱动库对START、ADDR、ACK和STOP的封装语义。

STOPSTART有时能用,却不是完全等价

部分器件在收到内部地址后,即使主机先发STOP再重新START,也会保留地址指针,因此实验可能“也能读”。但STOP表示一次事务结束,其他主机有机会占用总线,某些从机还会触发内部写周期或改变状态。

组合格式要求重复起始时,就应按规格实现。尤其在多主机、寄存器读写带副作用或需要原子访问的场景,STOP与重复起始的语义差异会变成真实故障,不能用单块EEPROM的偶然兼容推导全部I²C器件。

4.png 

4  示例串口结果只能证明一次读写运行,协议事件仍需用逻辑分析仪核对

抓包时按七个节点逐项打勾

把波形标成START、器件地址加W、ACK、内部地址、重复START、器件地址加R、数据与STOP。若在内部地址后看到STOP,或第二个地址仍是W,问题已经定位;若从机在某一步NACK,再回到地址宽度、上拉、电平和时序。

把组合事务与异常恢复分开

还要区分连续读与随机读。当前地址读可直接发送读方向,连续读会在从机内部自动递增指针;随机读才需要先指定新地址。接口命名若只写read()而不写语义,很容易让上层误用,建议明确random_read、current_address_read或register_read。

重复起始还常被电气问题掩盖。若SDA上拉过弱、总线电容过大,主机释放SDA后上升太慢,第二个START或地址位可能不满足高电平建立时间。从机NACK看起来像协议顺序错,实际还要核对上升时间。

驱动接口可把组合事务封装成不可拆分的函数,避免上层在内部地址与重复起始之间插入任务切换。带RTOS时给同一I²C控制器加互斥,并在错误退出路径恢复STOP和外设状态,防止一次NACK把后续事务全部拖死。

若总线挂死,可先检查SDA是否被从机拉低,再按器件允许的方法输出恢复时钟。恢复流程属于异常处理,不能替代正确的重复起始与ACK顺序。

结论

I²C随机读不是一条纯读命令。主机先用写方向把内部地址交给从机,再用重复起始切到读方向,两个阶段共同完成一次定位读取。

按七个协议节点标注逻辑分析仪波形,比盯驱动函数返回值更快发现漏掉的重复起始或方向位。

声明:

本文由凡亿教育整理,转载请注明来源!

投稿/招聘/广告/课程合作/资源置换 请加微信:13237418207


上一篇射频走线拐直角,为何转角不再是50Ω? 下一篇共模电感只拦共模,为何差模也会变?