大家知道,I2C 寫的時序是(截圖來自友晶科技Terasic書 《DE2-115實戰寶典》):
讀的時序是:
也就是讀的過程是:
-
發送起始位;
-
發送slave地址+write bit set;
-
發送內部寄存器地址;
-
重新發送起始位,即restart;
-
重新發送slave地址+read bit set;
-
讀取數據
主機接收器在接收到最后一個字節后,也不會發出ACK信號。於是,從機發送器釋放SDA線,以允許主機發出P信號結束傳輸。
-
發送停止位
但我很好奇為啥讀的時候這么麻煩, 要發送好幾次地址呢?后來查資料才知道,這里存在一個叫做啞寫(Dummy Write )的操作,目的是為了 更新 I2C 從設備的微控制器 的內部字節地址計數器( internal address counter)。
為什么會有啞寫的操作呢?跟字節地址計數器有什么關系?
這就要先了解I2C 從設備的一些特性。拿DE2-115 開發板的 EEPROM器件 24LC32來說, 它支持當前地址讀和隨即地址讀, 以及 連續讀操作 這三種模式。 I2C 從設備的微控制器 的內部字節地址計數器 會根據每讀一個數據或者寫一個數據就累加1,直到累加到31(寫操作) 或者是累加到頁尾(讀操作)。
如果直接發送器件地址(也就是進行當前地址讀),那么它讀出來的是當前計數器所指的地址:(因為只要不斷電,the internal address counter 就會保持之前的值, 比如之前先對計數器0指的地址寫了一個數據,此時計數器會累加到1, 然后接着進行當前地址讀操作,此時讀出的數據將是計數器1所指的地址的數據。)
那為了能直接讀取指定地址的數據, 可以先對字節地址計數器進行歸零操作,也就是先進行啞寫操作:
-
發送起始位;
-
發送slave地址+write bit set;
-
發送內部寄存器地址;
此時字節地址計數器為0,那么讀取的數據就是指定地址的數據了,這種方式也就是 24LC32的 隨機地址讀 模式: