本應用筆記討論了通過I2C兼容接口讀取多字節數據時需要注意的問題。討論了一次讀取一個字節的陷阱,并提供了一些具體示例。本文還介紹了處理此類數據傳輸的正確方法。
介紹
I2C兼容的雙線接口是一種強大的機制,用于將微控制器或微處理器連接到低速外設,例如帶有集成模數轉換器(ADC)的外設。通過該總線進行通信的最基本形式(即一次從從站寄存器寫入/讀取單個字節)非常簡單。但是,為了簡單起見,將自己限制在這種方法上有一些陷阱。
通過 2 字節通道傳輸 1 字節數據
與外設(尤其是傳感器)的任何其他數字接口一樣,我們需要從設備的內部寄存器中讀取正確的數據。當寄存器中的數據在讀取過程中發生變化時,這一點尤其重要。如果ADC在數據傳輸時運行轉換或更新寄存器,則數據可能會發生變化。許多設備都有一個內部緩沖區(通常無法從外部訪問),其中包含最新的轉換結果。當沒有I2C活動時,該器件使用新數據更新所謂的“客戶可訪問”寄存器。
I2C協議一次傳輸1字節的數據。因此,如果感興趣的數據總量超過 8 位并且傳輸處理不當,則可能會出現問題。例如,MAX44000的環境光傳感器(ALS)數據寄存器可以有多達14位數據(加上1位表示溢出,這意味著應增加計數/勒克斯設置)。
注冊 | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | 注冊地址 |
ADC 高字節 (ALS) | 奧福 | 數據[13:8] | 0x04 | ||||||
模數轉換器低字節 (ALS) | 數據[7:0] | 0x05 |
我們無法通過I2C直接讀取所有ALSDATA[13:0],因此我們必須首先讀取寄存器0x04的內容,然后讀取寄存器0x05的內容,并在至少16位寄存器中連接數據。但是,我們必須注意如何讀取這些數據。可以簡單地執行兩個由STOP(P)條件終止的單次讀取,如圖1所示。
圖1.單字節讀取。
這種方法有一個致命的缺陷。具體而言,發送 STOP 條件會向設備發出信號,以返回更新“客戶可見”寄存器。因此,在從寄存器0x04獲取數據后,實際上可以在讀取寄存器14x0之前更新05位數據。在某些情況下,此缺陷可能會造成災難性后果。
例如,如果光照水平處于一定水平,MAX44000環境光傳感器處于10位、12位或14位模式。假設電平徘徊在一個區域中,因此寄存器14x0和04x0中的05位將處于255或256個總數,這可能是由于緩慢增加的光或一些少量的噪聲。考慮表 2 中的三種情況。
第一個字節讀取期間 的寄存器狀態(僅限讀0x04) |
第二次字節讀取期間 的寄存器狀態(僅限讀0x05) |
結果(14 位) |
在最后兩種情況下,我們不是讀取 255 或 256,而是讀取 0 或 511。這是一個巨大的問題。發生這種情況是因為寄存器中的數據在發送 STOP 條件后,在第一次和第二次讀取之間0x04和0x05更新。在第一種有問題的情況下,第一個字節被正確讀取。但是當讀取第二個字節時,數據總共讀取了 256 個計數,其中最低字節為零。因此,我們從設備中獲得了零讀數。在第二個問題情況下,數據也是總共256個計數。這似乎變成了 511 個計數,因為在發送 STOP 條件后但在讀取第二個字節之前,數據減少了一個計數。有關在多次讀取中發生這種情況的次數的示例,請參見圖 2。
圖2.單字節讀取多個樣本的實際讀數。
通過一次讀取 2 個字節可以輕松避免此問題,如圖 3 所示。這是通過在讀取第一個數據字節后發送 REPEAT START 而不是 STOP 條件來完成的,并且實現起來相當簡單。通過讀取2個字節,我們可以防止器件執行更多的I2C寄存器更新,即使我們在兩個器件之間發送相同數量的位。
圖3.2 字節讀取的圖示。
上述示例適用于MAX44000和MAX44009,它們在進行多次讀取時不會自動遞增寄存器指針。您的設備可能行為不同,但原理始終相同。這很容易擴展到讀取 N 個字節。
審核編輯:郭婷
-
傳感器
+關注
關注
2548文章
50686瀏覽量
752027 -
寄存器
+關注
關注
31文章
5318瀏覽量
120015 -
adc
+關注
關注
98文章
6438瀏覽量
544106
發布評論請先 登錄
相關推薦
評論