I2C 讀取總是 0xFF,但是 ACK 是正常的解決方法


最近要讀寫 24C256,沒有參考網上代碼,自己擼了幾個小時,總是不對,讀取結果總是 0xFF,但是ACK的返回都是正確的,經過一番努力,終於找到問題所在了。
在芯片規格書里面時序圖只有 START 和 STOP,沒有 RESTART,問題就是出在 RESTART 上面, 下圖是 I2C 標准里面的圖片。

對於 I2C 這種串行協議,根據不同的斷句有兩種寫法。

第一種:

  1. START中先是 SCL, SDA 為高,然后 SDA 為低。
  2. 每bit 都是 SCL 為低,SDA輸出,SCL 為高。 ACK 也是類似。
  3. STOP中先是 SCL 低,SDA低,然后 SCL 高, SDA 高。

第二種:

  1. START中先是 SCL, SDA 為高,然后 SDA 為低,然后 SCL 為低
  2. 每bit 都是 SDA輸出,SCL 為高,然后 SCL 為低。 ACK 也是類似。
  3. STOP中先是 SDA低,然后 SCL 高, SDA 高。

對於這兩種寫法,初看上去好像沒有什么效果是一樣的,但是實際上是有區別的,第一種有BUG,第二種沒有問題。網上很多I2C都是按照第二種方法來寫的。第一種的BUG就是在讀取數據的時候體現出來的。因為讀取數據首先需要寫入地址,然后不用STOP,直接RESTART,讀取數據。

按照第一種的寫法,ACK結束的時候 SCL 為高,SDA 為低,然后接上 START,SCL為高,SDA為高,然后SDA為低。
按照第一種的寫法,ACK結束的時候 SCL 為低,SDA 為低,然后接上 START,SCL為高,SDA為高,然后SDA為低。
相當於第一種寫法,在 RESTART的時候,吞掉了一個 SCL 為低的過程。而這種 BUG 在 STOP 的時候是正常的,ACK 的返回也是正常的,但就是讀取數據的時候, 因為 RESTART不對,導致讀取都是 0xFF.

找到問題了,那么有兩種解決方法,一種是直接按照第二種去寫,還有一種是直接增加一個 RESTART的函數,在這個函數里面先 SCL 為低,然后接上正常的START函數即可。

通過這次的調試,也能發現標准的重要性,很多規格書里面都是粗略的介紹,真正詳細的還是要找到通訊協議的標准。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM