STM32 I2C 總線佔用問題解析

本文分享了解决STM32 MCU I2C总线占用问题的经验,包括加大LDO供电稳定、正确初始化I2C3引脚顺序以及确保Codec初始化时的正常供电三个关键解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天解决 STM32 MCU的I2C 总线占用(bus BUSY) 问题,觉得是不错的学习,从文中可得知I2C问题的思考逻辑,文末并指出经常出错的问题点,在此分享给大家。

问题描述

  1. STM32F207 MCU有三组I2C,I2C1~I2C3,此项目的初版硬件使用I2C1接三颗chip (DSP/Codec/EEPROM),运作良好。
  2. 新硬件把Codec/EEPROM移到I2C3,DSP还是留在I2C1,发现I2C3有机会传输失败,失败時log打印I2C3 bus BUSY (总线占用)
  3. 查MCU datasheet,I2C3 bus BUSY 原因是寄存器 I2C3_SR2[bit1]=1,如下表:
  4. 此狀態代表 I2C3 SCL/SDA曾经 voltage low而且没出现 stop condition,导致MCU无法开始传资料,BUSY定义如下:


  5. 此问题和时序有关,测试过程中在程序加delay就莫名PASS,再加delay又莫名BUSY。有些程序造成I2C3 100% BUSY,有些程序是60% BUSY

分析方向

  1. 观察I2C3 SCL/SDA波形

  2. 初版硬件只用I2C1,没确认过过I2C3。I2C3初始化程序是否有问题?

  3. 观察寄存器 I2C3_SR2[bit1],看何时开始BUSY,何时结束

  4. I2C3有问题可能是MCU或slave device造成,此项目的I2C3接上Codec和EEPROM,将它一个个断开,以厘清问题

  5. 和I2C bus有关?将Codec從I2C3移到 I2C1测试

  6. 为何初版硬件没问题?


分析過程

  1. 剛開始不太穩定,莫名的連續一直BUSY,有時一直PASS,而且LED時亮時暗
    > 量电压发现VDD3.3V不稳,电压在 0v ~ 3.3v 间震荡
    > 加大LDO之後VDD3.3V穩定了(Solution A),但I2C3還是BUSY

  2. 将程序東改西改,發現一版100% PASS的軟件,和另一版100% FAIL的軟件,只差在delay,應該還有其他問題

  3. 量波形,I2C1(DSP)很正常,I2C1 初始化之後一直FREE,只有傳資料期間才BUSY


  4. 100% BUSY的軟件,在I2C3 初始化之後SCL/SDA停在2.6V,當VDD3.3V ON 後才升到3.3V


  5. 100% PASS的軟件,波形同上,但之後開LED時因為LDO供電不足,SCL/SDA被短暫下拉,馬上回到3.3V

    應是因為SCL/SDA短暫下拉,誤打誤撞造成SCL/SDA high > low > high離開BUSY,有兩個證據
    證據一,如果沒下拉,I2C3就一直BUSY:
    a. 斷開小板(上面有LED) 以降低VDD3.3V電流,不會短暫下拉 > 100% PASS的軟件變成100% FAIL
    b. 斷開小版LED以降低VDD3.3V電流,不會短暫下拉 > 100% PASS的軟件變成100% FAIL
    c. 軟件關閉LED以降低VDD3.3V電流,不會短暫下拉 > 100% PASS的軟件變成100% FAIL

    證據二,如果有下拉,I2C3從BUSY恢復成FREE:
    a. 当BUSY時設SCL/SDA為GPIO out,拉low > high > low > high,重新初始化SCL/SDA (workaround) > 離開BUSY並可傳I2C指令
    b. 当BUSY時手動把SCL拉電線接地, 結果離開BUSY並可傳I2C指令
    c. 100% BUSY軟件就是因為沒下拉波形才會100% FAIL
    PS: 開LED造成電流超出LDO負荷也是問題,須加大LED電阻或更換LDO

  6. SCL/SDA短暫下拉不是造成BUSY的原因,重點在SCL/SDA有0.8s處於2.6V不正常電壓,原因可能有:
    - flash/codec去拉SCL/SDA
    - MCU去拉SCL/SDA
    - SCL/SDA上拉電阻不正確
    - SCL/SDA的上拉電路接在stby3.3v,可能stby3.3v不穩
    接下参考以下电路图,朝这几个方向除错。



  7. 斷開flash還是BUSY,而且SCL/SDA還是有0.8秒被下拉到2.6v
    > 和flash無關

  8. 斷開codec後,SCL/SDA不會下拉到2.6v,但I2C3還是BUSY
    > 懷疑Codec供電不正確,檢查I2C3初始化當下的VDD3.3v (供給Codec電壓),發現VDD3.3V本應處於無電狀態(0V),但實際量得2.7V,對codec是不正常電壓,可能造成工作異常
    > MCU將VDD3.3V提早開電(得到3.3V),確保I2c3初始化時Codec正常工作,SCL/SDA下拉電壓消失 (Solution B)
    > I2C3還是BUSY,其實還需要下個Solution


  9. 比較I2C1和I2C3初始化,發現重要差異:
    I2C1 pins(PB7, PB6)都在GPIO group B,共用一組GPIO register,填一次register可初始化兩根pin
    I2C3 pins(PA8, PC9)分在GPIO group A和C,必須分兩次初始化,先SDA再SDL
    > 懷疑初始化順序錯誤,因此改成讓I2C3先初始化SCL再SDA,終於PASS!(Solution C)


其他實驗

  1. 基本電路檢查: SCL/SDA pull high電阻都是4.7KR,Stby3.3v是穩定3.3V,SCL/SDA沒接反,Codec的25Mhz clock穩定
  2. 將Codec從I2C3移到I2C1,可正常傳輸 > 被誤導以為和Codec無關

結論

  1. I2C BUSY問題需要三個Solution. 
    A. 加大LDO讓VDD3.3V穩定供電
    B. I2C3先初始化SCL pin再SDA pin。雖然datasheet沒寫此限制,但sample code確實依照此順序執行初始化。
    C. 為確保Codec在I2C3 初始化時有正常電壓(VDD3.3v=3.3v),將VDD3.3V初始化移到I2C3初始化之前

  2. 及一個workaround 
    - 為確保BUSY時可恢復,當BUSY時將SCL/SDA設為GPIO out,然後pull low > high > low > high,再重新初始化I2C3

  3. 初版硬件沒問題是因為
    a. 初版硬件 LDO 較強力,無供電問題
    b. 初版硬件 VDD3.3v 無法由MCU開關,而是由stby3.3v穩定供電,因此無SCL/SDA 2.7V問題
    舊硬件只用I2C1,沒用I2C3。I2C1兩根pin在同一個GPIO group,無SCL/SDA初始化順序問題

以後I2C問題可檢查

    1. 電路:pull high電阻,pull high電壓,slave device供電
    2. 軟件:I2C SCL/SDA初始化,slave device初始化時序
    3. SCL/SDA檢查:SCL是否穩定,SCL/SDA電壓,slave device有回ACK? 傳輸資料是否正確
    4. 斷開I2C3 chip做測試

转载于:https://www.cnblogs.com/gavinage0/p/4825080.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值