|
I2C配置顺序引发的异常案例 % |# x' t* @; ^& }6 X% \" E4 C+ }前言& p3 t* @: v( d 在参考Cube软件包中I2C例程后, 根据应用需要新增了一路I2C接口,结果新增I2C无法收发数据。本文主要对问题进行描述,分析产生原因,提供解决方法。1 p8 \5 s6 B( n% N& n+ z6 F- ^; c$ @ 一 问题描述( d) c5 u# `0 J9 t4 x# u 如前言所述,现象表现为I2C无法收发数据。得无法理解之处,在于之前已经完成了I2C的移植工作,并且运行正常。现在遵照正确的方式,新添一路I2C接口,只是更改了对应的I2C接口及引脚,为什么无法收发数据。简化测试程序如下。
二 现象分析7 f' \& e+ a* p& S 将上述程序在STM32F469i-Disco板上实现,复现现象并寻找规律。发现规律如下:" O" c1 @2 L- x' E, H
分析上表可以发现问题的产生与硬件设计有一定关系。观察发现,如果I2C没有外部上拉时,会导致问题产生。 通过单步调试,定位于HAL_I2C_Master_Transmit(),在这个函数中调用的I2C_WaitOnFlagUntilTimeout()无法执行异常,返回HAL_BUSY,导致了I2C写功能失败。在I2C_WaitOnFlagUntilTimeout函数内部,是对忙标志位BUSY@I2Cx_SR2的检测。通过对参考手册的阅读(如下截图所述),如果在未占用I2C总线时,SDA或SCL引脚存在低电平,则意味着总线处于忙状态。这种检测机制在I2C接口失能时依然工作。& t7 `2 _1 E9 Y6 ~6 z
结合程序中调用顺序,在I2C3时钟使能时,虽然I2C3没有使能,但是忙状态检测已经开始。由于对应的SCL引脚上无上拉电阻,并且由于还未对I2C3的SCL引脚进行配置。此时SCL引脚为浮空输入状态,实际测量发现为低电平, BUSY标志被置位。 三 解决方法 通过现象及分析,可了解到问题可通过硬件或者软件解决。 硬件上,为SDA、SCL引脚提供外部的I2C上拉电阻,问题不在出现。 [9 {$ ~7 f: B, e7 w 软件上,能够发现对于SCL、SDA引脚配置中,会启用内部上拉。通过将I2C时钟使能放于I2C引脚配置语句后面,问题不再出现。8 g2 V: Q' X3 i6 o) l8 ~* \ 需要注意, I2C的SDA、SCL引脚内部上拉电阻,为弱上拉。使用者可以通过对应型号STM32的数据手册,查看对应引脚的上拉电阻,以便判断是否能够满足应用需要。如下为STM32F469 上拉电阻信息截图。. D4 w$ b$ a$ x @% E
I2Cé
置顺åºå¼åçå¼å¸¸æ¡ä¾.pdf
(261.25 KB, 下载次数: 142)
|
微信公众号
手机版
STM32L053C8T6 3 \" j( U, ]- X3 Z9 E% P! Y& H8 R
Cubmex 4.23
L0包 1.10
4 b" |; G# a4 T7 [" |% {" r5 p
新配置Cubmex工程,只生成I2C,MSI 2MHz主频,在低功耗配置,能正常读写I2C设备。) u. O, j9 v- {: H2 T( M
0 b9 o G# c; a: A1 |+ s: q3 r% X- e
但一打开LCD+RTC+I2C,MSI 2MHz主频,在低功耗配置的情况下,I2C_WaitOnFlagUntilTimeout()返回TimeOUT0 i6 u' ]6 b: t" C% h8 {. J' W3 F
: |( p; T/ C7 `5 I7 E% V4 Z
+ e. S% U/ H/ m) o! i' G, B
一旦打开LCD RTC之后,I2C就没用数据输出了