前言 客户使用I2C对EEPROM进行读取操作时,正常读取的最后一个字节,主机会传送一个NACK给EEPROM,以便结束该次读取过程,如果主器件给出ACK,而程序又默认结束读取过程,会出现EEPROM认为主机还需要读取数据,但此后SCL的时钟不会给出,将导致I2C总线被挂起占用,此时START,STOP命令将不会再次成功送出信号;本文针对这个异常状况结合实际应用问题给出处理方法。, \. ~) B3 i+ u8 P 问题背景 在实际应用中,如果使用中断方式或者DMA方式给出I2C的处理机制,在读取最后一个字节需要给出NACK的时候,如果此时延迟或者错误给出了ACK,I2C总线将被EEPROM挂起;该问题已经在客户端出现,但出现随机,很难判定何时出现,但确实是一个应用隐患,因为此时无法通过寄存器发送START,STOP命令; : n' c7 r* ^4 A0 o) \) u 判断依据+ ]* m0 a3 S% k* I( X+ O' J 为判定是主机(STM32F4xx)给出的ACK,还是从机(EEPROM)拉低ACK,需要加入辅助电路,如下:/ a& b( H/ ^2 Q3 n+ }) J 使用示波器探头察看A点电平,如果是EEPROM拉低电平的,则测试点电平为0V,如果是STM32F4xx端给出的ACK,拉低电平的,在A点测试将是大于0电平的一个波形存在; 波形分析1 @4 R' K: x5 k$ V$ ^ 正常读取波形 异常读取波形# X2 c( @$ N' ^ 在异常读取波形后,程序给出的起始终止条件将不会被执行; 3 @- U y* C+ i. R$ a5 V 1 M* D, E1 D2 l 处理方法 当出现上述异常时,写I2C外设寄存器方法将不起作用,I/O端口产生不了需要退出的波形,只能通过I/O口强拉效果退出,可以有两种方法进行处理:& V, A! G3 v3 m X! _0 E 方法一:当出现异常总线占用时,直接复位I2C外设,以及重新初始化I2C端口,I/O口配置为上拉模式的,产生虚拟的STOP波形;此时因为MCU端口的强拉作用,将产生一个类似于STOP的I2C退出效果; 方法二:I/O口配置为上拉模式的,SDA设置为高电平,产生虚拟的SCL波形,产生9个SCL波形,虚拟最后一个字节的读取,以便从机退出异常状态。1 ~% }' p% f( Y! _; v/ \9 D 文档下载 更多实战经验5 E, k* J2 }* c |
谢谢分享 |
图上没有找到A点,楼主换个图吧 |
讲解比较清楚,,, |
可以先更改IO口模式为普通IO,然后更改IO口电平,再将IO口模式改为IIC |
最后一步解决方法没有看懂,既然从机拉低了SDA,主机又能怎样拉高电平? |
STM32固件库分享,超全系列整理
【中文文档】AN3965_STM32F40x和STM32F41x基于串口的IAP
STM32F4-DISC 实现USB主机(U盘)和USB设备(虚拟串口)自动切换
STM32F4中文用户手册
基于STM32F407的FreeRTOS阶段性的总结(13)
STM32F400、STM32F402 Cortex-M4超值单片机
基于STM32F407的FreeRTOS获取各任务运行时间及占用情况(4)
基于STM32F407的FreeRTOS任务的挂起与恢复(3)
基于STM32F407的FreeRTOS任务的创建与删除经验分享(2)
基于STM32F407的FreeRTOS环境搭建经验分享(1)