本應用筆記討論了通過I2C兼容接口讀取多字節(jié)數據時的注意事項。討論了一次讀取一個字節(jié)的陷阱,并給出了一些具體示例。本文還介紹了處理此類數據傳輸的正確方法。**
I2C是嵌入式系統(tǒng)中使用的串行數據傳輸協(xié)議之一。它用于將低速外圍設備連接到嵌入式微處理器。它還用于中低數據速率通信。EPROM,實時時鐘系統(tǒng)存儲設備,遠程溫度傳感器和I / O端口擴展器是慢速外圍設備的一些示例。
兼容I2C的兩線式接口是一種強大的機制,可用于將微控制器或微處理器與低速外圍設備接口,例如具有集成模數轉換器(ADC)的外圍設備。通過該總線進行通信的最基本形式(即一次向/從從寄存器寫入/讀取單個字節(jié))非常簡單。但是,為簡單起見,將自己限制在這種方法上存在一些陷阱。
通過1字節(jié)通道傳輸2字節(jié)數據
與其他任何與外圍設備(尤其是傳感器)的數字接口一樣,我們需要從設備的內部寄存器中讀取正確的數據。當寄存器的數據在讀取過程中發(fā)生變化時,這一點尤其重要。如果在數據傳輸時ADC運行其轉換或更新寄存器,則數據可能會發(fā)生變化。許多設備具有內部緩沖區(qū)(通常不能從外部訪問),該緩沖區(qū)包含轉換的最新結果。當沒有I2C活動時,設備使用新數據更新所謂的“客戶可訪問”寄存器。
I2C協(xié)議一次傳輸1個字節(jié)的數據。因此,如果感興趣的總量數據長于8位并且傳輸處理不正確,則可能會出現(xiàn)問題。例如,MAX44000的環(huán)境光傳感器(ALS)數據寄存器最多可包含14位數據(加上1位表示溢出,這意味著應增加計數/照度設置)。
我們無法直接通過I2C讀取所有ALSDATA [13:0],因此我們必須首先讀取寄存器0x04的內容,然后讀取寄存器0x05的內容,并將數據連接到至少一個16位寄存器中。但是,我們必須注意如何讀取此數據??梢院唵蔚貓?zhí)行兩個以STOP(P)條件終止的單次讀取,如圖1所示。

這種方法有一個致命的缺陷。具體來說,發(fā)送STOP條件會向器件發(fā)出信號,要求其返回以更新“客戶可見”寄存器。因此,從寄存器0x04獲取數據后,實際上14位數據可以在讀取寄存器0x05之前進行更新。在某些情況下,此缺陷可能會造成災難性的后果。
一個例子是,如果光照水平在一定水平,MAX44000環(huán)境光傳感器處于10位,12位或14位模式。假設電平徘徊在某個區(qū)域內,則寄存器0x04和0x05中的14位計數總計為255或256,這可能是由于光線緩慢增加或少量噪聲引起的??紤]圖2所示表中的三種情況。

單字節(jié)讀取。
在最后兩種情況下,我們讀取0或511,而不是讀取255或256。這是一個很大的問題。發(fā)生這種情況的原因是在發(fā)送STOP條件之后,在第一次讀取和第二次讀取之間更新了寄存器0x04和0x05中的數據。在第一種有問題的情況下,正確讀取了第一個字節(jié)。但是到讀取第二個字節(jié)時,數據讀取的總數為256,其中最低字節(jié)為零。因此,我們從該設備獲得零讀數。在第二個有問題的情況下,數據也總計為256個計數。由于在發(fā)送STOP條件之后但在讀取第二個字節(jié)之前數據減少了一個計數,因此該計數似乎變?yōu)?11個計數。有關在多次讀取中發(fā)生這種情況的次數的示例,請參見圖3。

單字節(jié)的實際讀數可讀取許多樣本。
如圖4所示,通過一次讀取2個字節(jié)可以輕松避免此問題,這是通過在讀取第一個數據字節(jié)之后發(fā)送REPEATED START而不是STOP條件來完成的,并且非常容易實現(xiàn)。通過讀取2個字節(jié),即使我們在兩個器件之間總體上發(fā)送了相同數量的位,也阻止了該部分執(zhí)行更多的I2C寄存器更新。

2字節(jié)讀取的插圖。
上面的例子適用于MAX44000和MAX44009,它們在進行多次讀取時不會自動遞增寄存器指針。您的設備的行為可能有所不同,但是原理始終相同。這很容易擴展為讀取N個字節(jié)。
編輯:hfy
-
微控制器
+關注
關注
49文章
8833瀏覽量
165609 -
寄存器
+關注
關注
31文章
5618瀏覽量
130389 -
模數轉換器
+關注
關注
26文章
4099瀏覽量
130252 -
時鐘系統(tǒng)
+關注
關注
1文章
133瀏覽量
13010
發(fā)布評論請先 登錄
量水堰計是如何實現(xiàn)數據傳輸和遠程監(jiān)控的?
天碩(TOPSSD)技術深解:TBW(總寫入字節(jié)數)的工程實現(xiàn)
I2C的總線協(xié)議
CW32單片機I2C接口來讀寫EEPROM芯片
使用fal api 來讀寫1024 字節(jié)數據,需要需要考慮被高優(yōu)先級線程打斷嗎?
為什么rt_device_read()只能讀取到兩個字節(jié)數據?
嵌入式接口通識知識之I2C接口
數據傳輸卡頓?工控一體機接口兼容性問題與線纜選型聚徽全解析
Android14在BLE中,當MTU超過 517時,如何處理數據傳輸?
淺談I2C兼容接口讀取多字節(jié)數據時數據傳輸方法
評論