0.本文的內容目錄
本文一共接近一萬一千字,為了幫助大家閱讀,我把本文的內容目錄截圖如下,大家根據需要閱讀,或者一次閱讀不完,下次再讀的時候方便查閱。
1.I2C概述
I2C是Inter-Integrated Circuit(內部集成電路)的簡稱,是一種通用的總線協議。它是由Philips(飛利浦)公司,現NXP(恩智浦)半導體開發的一種簡單的雙向兩線總線協議標準。
I2C 總線是一種非常流行的串行總線,用于單個或多個主機與單個或多個從機之間的通信。下圖Figure 1 所示為嵌入式系統的典型 I2C 總線,其中使用多個從機。微控制器代表I2C 的主機,控制IO擴展器、各種傳感器、EEPROM、ADC/DAC等。所有這些都由主機的2個引腳SCL和SDA控制。
2.I2C的電氣特性
I2C使用漏極開路/集電極開路(open-drain/open-collector),在同一條線路上帶有輸入緩沖器(input buffer),允許將單條數據線用于雙向數據流。
SDA和SCL都是雙向線路,將所有設備的SDA線全部連在一起構成SDA總線,將所有設備的SCL線全部連在一起構成SCL總線,工作地線GND共用,每個設備都可以通過SDA和SCL線,向外傳輸信號(高低電平)或者從外面接收信號(高低電平),這些互連設備中至少需要一個主機。
SDA和SCL信號線上,必須通過電流源或上拉電阻連接到正電源電壓。因為I2C設備內部輸出電路已設計成開漏(OD)輸出或開集電極(OC)輸出(如圖1-14),所以要在總線上外接上拉電阻或電流源,用來給總線上提供高電平。
2.2為什么I2C接口內部是OD(OC)輸出
I2C設備內部為什么要設計成OD或OC結構,而不設計成推挽結構呢?其目的是防止總線上進行“線與”時發生短路現象造成設備過熱或損壞。因為如果設計成推挽結構(如圖1-15),在SDA或SCL總線上,同一時刻某些設備輸出高電平,某些設備輸出低電平時,連接電源的上拉開關管和連接地的下拉開關管之間就會短路,導致開關功耗過大(如有限流保護)或者燒壞器件。對于單個主機(一主多從)應用,如果從機也沒有延長時鐘的功能,那么控制器(主機)的SCL輸出可以設計為推挽驅動輸出。
2.3為什么I2C接口內部不集成上拉電阻
為什么不采用圖1-15那樣,把外部的上拉電阻集成到設備(芯片)內部去呢?上拉電阻集成到芯片內部,導致芯片結構復雜、芯片功耗增大以及無法兼容不同電源電壓的設備(如下圖所示)。
芯片內部不集成上拉電阻,共用外部的上拉電阻,其作用有三:①簡化芯片內部電路;②減小芯片內部功耗;③不同電源供電的設備可以做到高電平信號兼容(如下圖所示)。
2.4使用漏極開路(open-drain)進行雙向通信
漏極開路是指一種輸出類型,它可以將總線拉低到某個電壓(在大多數情況下為接地),或者“釋放”總線,讓它被上拉電阻拉起。如果總線被主機或從機釋放,線路上的上拉電阻 (RPU) 負責將總線電壓拉至電源軌(power rail:參考下面的注釋[1])。由于沒有任何設備可以在線路上強制設置高電平,這意味著總線永遠不會遇到,一個設備可能嘗試發送高電平,而另一個設備發送低電平,從而導致短路(電源軌對地)的通信問題。I2C 要求,如果多主機環境中的一個主機準備傳輸高電平,但看到線路為低電平(另一個設備正在將其拉低),這時由于另一個設備正在使用總線,因而將會停止通信。推挽式(push-pull,參考下面注釋)接口不允許這種類型的自由,這是 I2C 的優勢。
注:
[1]power rail, 電源軌是指上拉電阻所接入的電源電壓VCC,但由于上拉電阻(kohm)與FET關斷時候的超大阻抗(Mohm)分壓,導致總線上的電壓會略低于VCC。但是由于分壓電阻差距過大,一般是認為相等的。
[2]推挽輸出的是由兩個互補的三極管或者MOS管組成,始終保持一個導通,另一個截止的狀態,假如一個主機A使用推挽輸出高電平,另一個主機B使用推挽輸出低電平,這時候電流將通過VCC流過主機A的上管,主機B的下管到地,總線的電壓由兩個管子的導通電阻進行分壓,如果管子一致性較好,那么總線上的約為 VCC的一半。
[3]推挽輸出的特性決定了其不能用于多主機的環境中,但是由于推挽輸出的能力比漏極開路輸出的能力強太多(因為沒有上拉電阻的限流作用),在I2C 的超快速模式(5Mbit/s)中要求必須使用推挽輸出,才能滿足信號的時序要求,在這個模式下,只能沿一個方向傳輸數據,用于驅動 LED 控制器和其他不需要反饋的設備時,它最有用。
[4]漏極開路輸出允許線與(與門)的邏輯功能,導致某個設備輸出為低時,線路就是低電平,而輸出高電平時,可以通過輸入緩沖器來判斷總線的電平,就不需要再修改IO口的輸入輸出模式了,對于代碼編寫軟件模擬I2C 來說是極其方便低電平,而輸出高電平時,可以通過輸入緩沖器來判斷總線的電平,就不需要再修改IO口的輸入輸出模式了,對于代碼編寫軟件模擬I2C 來說是極其方便的。
Figure 2是SDA/SCL線上的主機或從機設備的內部結構簡化圖,它包含了用于讀取輸入數據的緩沖器和用于傳輸數據的下拉FET。設備只能將總線拉低(提供對地短路)或釋放總線(對地高阻抗),并允許上拉電阻升高電壓。這是在處理I2C設備時要實現的一個重要概念,沒有設備可以將總線一直保持在高位。這一特性允許進行雙向通信。
2.1.1 漏極開路拉低
如上所述,漏極開路設置可能只會將總線拉低,或“釋放”總線并讓電阻將其拉高。Figure 3顯示了將總線拉低時的電流流動。想要傳輸低電平的邏輯將激活下拉FET,這將提供對地短路,將線路拉低。
2.1.2 漏極開路釋放總線
當從設備或主設備希望傳輸邏輯高電平時,它只能通過關閉下拉FET來釋放總線。這使總線浮動,上拉電阻將電壓拉至電壓軌,這將被解釋為高。圖4顯示了通過上拉電阻將總線拉高的電流流動。
3.I2C接口
3.1接口概述
I2C總線很受歡迎,因為它使用簡單,可以有多個主機和多個從機,并且只需要兩條帶上拉電阻的導線就可以連接幾乎無限數量的I2C設備。I2C可以使用具有通用I/O引腳的更慢的微控制器,因為除了讀取和寫入字節的功能外,它們只需要生成正確的啟動和停止條件。
每個從機都有一個唯一的地址。傳輸是串行的,它被分成8位數據包。所有這些簡單的要求使得即使使用沒有特殊I2C硬件控制器的廉價微控制器,實現I2C接口也非常簡單。您只需要2個空閑的I/O引腳和幾個簡單的i2C例程就可以發送和接收命令。
I2C總線規范描述了雙向數據傳輸的五種操作速度類別:
基本的I2C通信使用8位或字節的傳輸。每個I2C從設備都有一個7位地址,需要在總線上唯一。還有一些設備具有規范允許的10位地址。7位地址表示第7位至第1位,而第0位用于向設備發出讀寫信號。如果位0(地址字節中)設置為1,則主設備將從從I2C設備讀取。主設備不需要地址,因為它生成時鐘(通過SCL)并尋址各個I2C從設備。在正常狀態下,兩條線路(SCL和SDA)均為高電平。通信由主設備發起。
兩個信號(SCL和SDA)都是雙向的。它們通過電阻器連接到正電源電壓。這意味著當總線空閑時,兩條線路都很高。總線上的所有設備必須具有集電極開路或漏極開路引腳。激活線路意味著將其下拉(線與)。單個總線上的設備數量幾乎是無限的。唯一的要求是總線電容不超過400 pF。由于邏輯1電平取決于電源電壓,因此沒有標準總線電壓。
大多數I2C設備支持重復起始條件。這意味著在通信以停止條件結束之前,主機可以用地址字節重復開始條件,并將模式從寫入更改為讀取。
3.2 I2C術語
【發送器】–這是將數據傳輸到總線的設備
【接收器】–這是從總線接收數據的設備
【主機】–這是生成時鐘、啟動通信、發送I2C命令和停止通信的設備
【從機】–這是偵聽總線并由主設備尋址的設備
【多主機】–I2C可以有多個主機,每個主機都可以發送命令
【仲裁】–當更多主機需要使用總線時,確定總線上哪些主機可以使用仲裁的過程
【同步】–同步兩個或多個設備的時鐘的過程
3.3 常規的I2C操作
I2C總線是一個標準的雙向接口,它使用一個控制器(稱為主控制器)與從設備通信。從設備不能傳輸數據,除非它已被主設備尋址。I2C總線上的每個設備都有一個特定的設備地址,以區分同一I2C總線中的其他設備。許多從設備在啟動時需要配置以設置設備的行為。這通常在主機訪問具有唯一寄存器地址的從機內部寄存器映射時完成。設備可以具有存儲數據的一個或多個寄存器,
物理I2C接口由串行時鐘(SCL)和串行數據(SDA)線組成。SDA和SCL線必須通過上拉電阻器連接到VCC。上拉電阻器的大小由I2C線路上的電容量決定。數據傳輸只能在總線空閑時啟動。如果在STOP條件后SDA和SCL線都為高電平,則總線被視為空閑。主設備訪問從設備的一般程序如下:
1主機要向從機發送數據:
[1]主機發送START條件并尋址從機(發送從機地址);
[2]主機向接收數據的從機發送數據;
[3]主機在STOP條件下終止傳輸。
2主機希望接收/讀取從機數據:
[1]主機發送START條件并尋址從機(發送從機地址);
[2]主機發送要訪問的寄存器地址(位于從機內)進行讀取;
[3]主機接收從機過來的數據;
[4]主機發送STOP條件終止傳輸。
3.3.1 開始/停止條件
I2C通信由主機發送START條件啟動,并由主機發送STOP條件終止。當SCL為高時,SDA線上的高到低轉換定義了START條件。當SCL為高時,SDA線上的低到高轉換定義STOP條件。
在啟動條件之后,總線被認為是繁忙的,只有在檢測到停止條件之后,才能由另一個主機使用。在“開始”條件之后,主機可以生成重復的“開始”。這相當于正常啟動,通常后跟從I2C地址。
具有專用I2C硬件的微控制器可以很容易地檢測總線變化,也可以作為I2C從設備。然而,如果I2C通信在軟件中實現,則總線信號必須在每個時鐘周期至少采樣兩次,以便檢測必要的變化。
3.3.2 重復起始條件
重復起始條件類似于開始條件,用于代替背靠背的先停止后啟動條件。它看起來與START條件相同,但其實與START條件不同,因為它發生在STOP條件之前(當總線不空閑時)。當主機希望啟動新的通信,但不希望在STOP條件下讓總線空閑時,這很有用,這可能會導致主機失去對另一主機的總線控制(在多主機環境中)。
3.3.3 位傳輸
對于每個時鐘脈沖,傳輸一位數據。SDA信號只能在SCL信號為低時發生變化。當時鐘為高時,數據應該是穩定的。
3.3.4 數據傳輸
I2C協議總線上的數據以8位數據包(字節)傳輸。對字節數沒有限制,但是,每個字節后面必須跟一個確認位ACK。該位指示設備是否準備好繼續下一個字節。對于包括確認位ACK在內的所有數據位,主機必須生成時鐘脈沖。如果從設備未確認傳輸,這意味著沒有更多數據或設備尚未準備好進行傳輸。主設備必須生成停止或重復啟動條件。
3.4 數據有效性和字節格式
在SCL的每個時鐘脈沖期間傳送一個數據位。SDA線上的一個字節由八位組成。字節可以是設備地址、寄存器地址,也可以是從設備寫入或讀取的數據。
數據首先傳輸最高有效位(MSB)。任何數量的數據字節都可以在START和STOP條件之間從主設備傳輸到從設備。SDA線上的數據必須在時鐘周期的高相位期間保持穩定,因為SCL為高時數據線的變化解釋為控制命令(START或STOP)。
3.5 ACK和NACK
每個數據字節(包括地址字節)后面跟著來自接收器的一個ACK位。ACK位允許接收機與發射機通信,表明字節已成功接收,并且可以發送另一個字節。在接收機發送ACK之前,發射機必須釋放SDA線路。為了發送ACK位,接收機應在ACK/NACK相關時鐘周期的低相位(周期9)期間下拉SDA線,以使SDA線在ACK/ACK相關時鐘時段的高相位期間穩定為低電平。必須考慮設置和保持時間。當SDA線在ACK/NACK相關時鐘周期(周期9)期間保持高電平時,這被解釋為NACK。有幾個條件導致NACK的產生:
[1]總線上不存在帶有發送地址的接收器,因此沒有設備做出應答。
[2]接收器無法接收或發送,因為它正在執行某些實時功能,并且尚未準備好與主機開始通信。
[3]在傳輸過程中,接收器接收到它不理解的數據或命令。
[4]在傳輸過程中,接收器無法接收更多的數據字節。
[5]主接收機完成數據讀取,并通過NACK向發送器發送傳輸結束的信號。
3.6 時鐘同步
在空閑總線時,兩個主機可以同時啟動傳輸,必須有一種方法來決定由哪一個主機來控制總線并完成傳輸。這是通過時鐘同步和仲裁兩個步驟來完成的。在一主多從的系統中,不需要時鐘同步和仲裁。
參考上圖,使用設備的SCL接口和SCL總線之間的“線與”連接來執行時鐘同步。主機一的SCL接口一旦檢測到SCL總線上由高電平到低電平的轉換時,主機一便拉低自己的SCL,并開始倒計數應有的SCL低電平保持時間,直到應有的低電平時間結束,便把SCL時鐘拉到高電平狀態。如果另一個主機二的SCL時鐘仍然處于低電平周期內,則主機一的SCL時鐘由低到高的轉換不會改變SCL總線為低電平的狀態,則主機一的SCL時鐘進入高電平等待狀態。因此,SCL總線被具有最長低電平周期的主機保持在低電平。
當所有相關的主機都已完成其低電平周期的計數時,SCL時鐘總線被釋放并變為高電平。主機SCL接口和SCL總線的狀態之間保持一致,都為高電平。所有主機開始計算它們的高電平周期。第一個完成高電平周期的主機再次將SCL線拉低。
這樣,就產生了同步的SCL總線時鐘,其低周期由具有最長時鐘低周期的主機確定,其高周期由具有最短時鐘高周期的主機確定。
3.7 時鐘拉伸(Clock stretching)
正如我們前面所說的,主機決定時鐘速度。然而在某些情況下,I2C從設備不能與主設備給出的時鐘速度協作,需要稍微減速。這是通過一種叫做時鐘拉伸的機制來完成的。
如果需要降低總線速度,I2C從機可以保持時鐘。另一方面,主機需要在將時鐘信號釋放到高狀態之后讀取時鐘信號,并等待直到線路實際變高。
在傳輸一個字節時,從機可能能夠快速接收數據字節,但需要更多時間來存儲接收到的字節或準備要傳輸的字節,如果基于以上原因無法立即進行下一個字節的傳輸時,那么從機在接收完一個字節并應答后,可以將SCL線(主機輸出)的低電平繼續拉低并保持,以強制主機進入等待狀態,直到從機做好了傳輸下一個字節的準備。
時鐘拉伸通過保持 SCL線路低電平來暫停事務。在該線路再次釋放為高電平之前,事務無法繼續。時鐘拉伸是可選的,實際上,大多數目標設備都不包含 SCL 驅動程序,因此它們無法拉伸時鐘。
3.8 總線仲裁
對于I2C總線上的正常數據傳輸,只能激活一個主設備。如果出于某種原因,兩個主機同時啟動I2C命令,則仲裁程序確定哪個主機獲勝并可以繼續執行該命令。當SCL信號為高時,對SDA信號執行仲裁。每個主機檢查總線上的SDA信號是否對應于生成的SDA。如果總線上的SDA信號為低電平,但應該為高電平,則該主機已失去仲裁。失去仲裁的主I2C設備可以生成SCL脈沖,直到字節結束,然后必須釋放總線并進入從屬模式。仲裁程序可以繼續,直到所有數據被傳輸。這意味著在多主機系統中,每個I2C主機必須監控I2C總線的沖突并相應地采取行動。
仲裁協議用于多主機的系統中,單主機系統不需要仲裁。仲裁程序發生在主機之間,從機不涉及仲裁。只有當總線空閑時,主機才可以啟動傳輸。兩個主機同時發起啟動后,總線需要對這兩個主機進行仲裁,以確定最終由哪個主機控制總線并完成其傳輸。
設備的SDA接口線每次輸出電平后,會立即回讀SDA總線電平,用來判斷自己的輸出是否與總線一致。SCL線和SDA一樣,也有這種回讀判讀機制。
仲裁由SCL線和SDA線一起配合來完成的,其分工如下:
SCL線負責時鐘同步:兩個主機在空閑狀態時,同時發起啟動,然后各自根據自己的時序要求拉低SCL總線輸出低電平,釋放SCL總線輸出高電平,根據前面章節介紹的SCL時鐘同步機制實現時鐘同步。
SDA線負責數據仲裁:仲裁是在SDA線上一位一位地進行的。在每一位傳輸期間,當SCL為高電平時,每個主機各自判斷自己SDA線輸出的電平是否與SDA總線電平一致(回讀判讀機制),如果某主機發現輸出電平和回讀電平不一致,則該主機仲裁失敗,失去對總線的控制權,隨即關閉自己SDA輸出驅動器,另一個主機贏得仲裁獲取對總線的控制權,繼續完成它的傳輸事務。這種仲裁過程可能需要進行很多位。
在仲裁過程中,贏得仲裁的主機不會丟失任何信息,仲裁失敗的主機可以繼續產生時鐘脈沖,直到其仲裁失敗的字節結束,并且可以在總線空閑時重新發起仲裁。
如果一個主機也具有從機的功能,并且在尋址階段仲裁失敗,那么獲勝的主機可能正在嘗試尋址它。因此,失敗的主機必須立即切換到其從機模式。根據連接到總線的主機數量,以上的仲裁方式也適合更多主機的系統。由于對I2C總線的控制完全由參與競爭的主機發送的地址和數據決定,所以總線上沒有中央控制器,也沒有任何優先級順序。
當一個主機發送重啟或停止信號,而另一個主機仍在發送數據時,如果仲裁程序仍在進行中,則會出現未定義(異常)的狀態。換句話說,以下組合會導致異常情況:
主機1發送重啟信號,主機2發送數據位(所以重啟前一定要判斷重啟建立時間)。
主機1發送停止信號,主機2發送數據位。
主機1發送重啟信號,主機2發送停止信號。
3.9 7位從機地址的讀寫
數據傳輸遵循下圖中所示的格式。主機在啟動后,發送從機地址,該地址為7位長度。后面第8位是數據傳輸方向位,邏輯“1”代表讀(R),表示接下來的數據由從機發送給主機,邏輯“0”代表寫(W),表示接下來的數據由主機發生給從機。
3.9.1 主機寫從機
如果主機僅寫入從機,則數據傳輸方向不會改變。
3.9.2 主機讀從機
如果主機只需要從從機讀取,那么它只需發送具有設置為讀取的R/W位的I2C地址。之后,主機開始讀取數據。
3.9.3 混合讀寫(傳輸過程中改變方向)
有時主機需要寫入一些數據,然后從從機讀取。在這種情況下,它必須首先寫入從機,改變數據傳輸方向,然后讀取設備。這意味著發送R/W位設置為寫的I2C地址,然后發送一些附加數據,如寄存器地址。在寫入完成之后,主設備生成重復的開始條件,并發送具有設置為讀取的R/W位的I2C地址。此后,數據傳輸方向改變,主設備開始讀取數據。
3.10 10位尋址
大多數兼容I2C總線的從機具有7位從機地址編碼,理論上可以在總線連接128個從機設備,為了在同一總線上連接更多的從機設備,I2C規范增加了10位地址編碼的從機,理論上從機可以擴展到1024個。目前10位尋址設備沒有被廣泛使用。具有7位和10位地址的設備可以連接到同一個I2C總線,可用于所有總線速度模式。
如下圖所示,10位從機地址由啟動(S)或重啟(Sr)信號后的前兩個字節構成:①第一個字節的前七位是組合1111 0XX,其中前五位(1111 0)是特殊規定且不可更改的;后兩位(XX)是10位地址的兩個最高有效位(MSB );第一個字節的第八位是決定信號方向的R/W位。②第二個字節是10位地址的低8位。
前面針對7位尋址設備描述的讀/寫格式的所有組合對于10位尋址也是適合的。這里舉2個例子來進一步說明10位地址的用法:
3.10.1 10位地址寫操作
如下圖所示,主機向具有10位從機地址的從機發送數據。傳輸方向不變。主機啟動發送第一個尋址字節,每個從機判讀第一個尋址字節的第八位(R/W方向位)是否為0,如果為0,每個從機將第一個尋址字節的前七位(1111 0XX)與其自身地址進行比較,這時前七位地址相同的從設備會同時產生應答(A1);接著主機發送第二個尋址字節(XXXXXXXX),所有從機將該地址(XXXXXXXX)的全部八位與它們自己的地址進行比較,但是只有一個從機找到匹配并產生應答(A2),找到匹配的從機繼續保持被尋址狀態,直到收到停止(P)或重啟(Sr)信號。
3.10.2 10位地址讀
主機從帶有10位從機地址的從機讀取數據。主機啟動后發送第一個尋址字節和第二個尋址字節后,只有一個從機被尋址。在重復的開始條件(Sr)之后,匹配的從機記得它以前被尋址過。然后,該從機檢查重啟(Sr)之后的主機第一個字地址節的前七位是否與自己的相同(此時無需第二個尋址字節),并測試第八個(R/W)位是否為1,如果前七位相同、第八位是1,從機認為它已經作為發送器被尋址,并產生應答A3。從機繼續保持被尋址,直到收到停止(P)或重啟(Sr)信號。由于重啟(Sr)后的第一個尋址字節的第八位(R/W)是R(1),所以其他從機都不會被尋址。
3.11 特殊保留地址
I2C地址的分配由負責分配的I2C總線委員會管理。保留兩組8個I2C地址供將來使用,一個地址用于10位I2C尋址。其特殊作用如下:
通用呼叫地址用于尋址從屬總線上的所有設備。如果任何從屬設備不需要響應此類呼叫或從屬設備不支持常規呼叫,則必須忽略該呼叫。如果設備支持普通呼叫并希望接收數據,則必須確認地址并作為從屬接收器讀取數據。
3.11.1 廣播尋址
廣播尋址(00000000)用于同時尋址連接到I2C總線的每個設備。
[1]如果設備不需要廣播提供的任何數據,它可以回復NACK來忽略廣播地址;
[2]如果設備需要來自廣播的數據,會對廣播地址進行ACK,并作為一個從接收設備;
[3]如果多個設備響應廣播地址ACK,主設備并不知道有多少個設備回應。每個能夠處理此數據的從接收設備第二個和后面的字節ACK。
一般廣播地址的含義總是在地址的第二個字節中指定,如下圖:
當LSB=0時,
當LSB=1時,
[1]當LSB=1時,2個字節的地址序列是一個硬件通用調用。
[2]這意味著地址序列是由硬件主設備傳輸的,例如鍵盤掃描器。第二個字節剩下的7位包含硬件主設備地址,這個地址會被一個連接到總線的智能設備(例如微控制器)識別,然后總線接受來自硬件設備的信息。
[3]由于硬件主設備實現不知道消息必須要傳輸到哪個設備,因此它只能生成這個硬件通用調用和他自己的地址,然后標識給系統。
3.11.2 起始字節(start byte)
微控制器有兩種方式連接到I2C總線上。有片上的硬件I2C總線接口的微控制器可以變成為只接收總線的中斷請求。當設備沒有這樣的接口,它必須要通過軟件手段來檢測總線。很明顯,微控制器檢測的時間或者輪詢總線的時間越多,實現自己功能的時間就越少。
因此快速硬件設備和依賴軟件輪詢的相對慢速微控制器是有速度差別的。在這種情況下,數據傳輸前有一個比正常時間長很多的起始過程。起始過程組成如下:
一個開始條件(S)& 一個開始字節(0000 0001)& 應答位(ACK)&重復的開始條件(Sr)
主機發送完開始條件后,發送開始字節(0000 0001)。另外的微控制器可以以低采樣率來采樣SDA線知道開始字節的7個0中的一個被偵測到。在偵測到SDA線的低電平后,微控制器可以切換到更高的采樣率來探測用于同步的重復開始條件。
在開始字節后一個應答相關的時鐘脈沖產生。設備不允許應答開始字節。
3.11.3 總線清除(bus clear)
總線清除指的是清除總線被卡死在低電平的故障,使其恢復正常狀態。
在極少數情況下,如果SCL時鐘總線被卡在低電平(長時間陷在低電平狀態),對其正確的處理方式為:①如果您的I2C設備有硬件復位輸入,那么首先使用硬件復位信號復位I2C總線。②如果I2C設備沒有硬件復位輸入,則重啟電源供電以強制激活設備內部硬件上電復位(POR)電路,實施開機復位I2C總線狀態機。
在極少數情況下,如果SDA數據總線被卡在低電平(長時間陷在低電平狀態),對其正確的處理方式為:①主機應發送9個時鐘脈沖,將SDA總線保持在低電平的設備應該會在這9個時鐘周期內的某個時間將其釋放。②如果9個時鐘周期內沒有釋放,則使用硬件復位或重啟電源復位來清除總線。
3.11.4 設備ID
在出廠前,芯片制造商將設備ID(身份編碼)存儲在芯片內部的只讀存儲空間,如下圖所示,設備ID包含內容如下:
[1] 12位芯片制造商名稱編碼,每個制造商都是唯一的(例如”0000 0000 0000”代表恩智浦)。
[2] 9位芯片器件標識碼,芯片制造商分配(例如AT24C02)。
[3] 3位芯片版本,由制造商指定(例如RevX)。
設備ID是只讀的,在設備中是硬連線的,可以通過以下方式訪問:
[1] 主機發送啟動(S)信號。
[2] 主機發送設備ID(特殊保留的)地址 “1111 1000”,最后一位R/W位一定要為“0”,表示“寫”操作;可能有多個從機應答。
[3] 主機發送從機設備地址。此時,代表傳輸方向LSB位無關緊要,“0”或“1” 均可。只有一個從機設備必須應答該字節。
[4] 主機發送重啟(Sr)信號。注意:啟動(S)信號會重置從機,并且無法執行設備ID讀取。此外停止(P)或重啟(Sr)后訪問另一個從機設備也會重置原來的從機,并且無法執行設備ID讀取。
[5] 主機發送設備ID(特殊保留的)地址 “1111 1001”,最后一位R/W位一定要為“1”,表示“讀”操作。
[6] 主機接收完設備ID第一個字節并應答,然后接收完設備ID第二字節并應答,最后接收設備ID第三個字節。注意:以上讀取的三個字節就是設備ID,包含 12個制造商位(第一個字節+第二個字節的4個MSB)、9個器件標識位(第二個字節的4個LSB+第三個字節的5個MSB)、3個芯片版本位(第三個字節的3個LSB)。
[7] 主機通過不應答最后一個字節來結束讀取操作,從而重置從機狀態機,從機轉為等待主機發送停止(P)信號的狀態。備注:主機通過發送NACK,可以隨時停止讀取設備ID的操作。如果主機在收到第三個字節后繼續應答,從機就回滾到第一個字節,并繼續重復發送設備ID序列,直到檢測到NACK。
4. I2C數據傳輸的例子
數據必須發送到從機或接收來自從機的數據,但實現這一點的方式是讀取或寫入從機中的寄存器。
寄存器是Slave‘s memory中包含信息的位置,無論是配置信息還是要發送回主機的一些采樣數據。主機必須將信息寫入這些寄存器,以便指示從機執行任務。
雖然I2C從設備中有寄存器是常見的,但請注意,并非所有從設備都有寄存器。有些設備很簡單,只包含一個寄存器,可以通過在從地址之后立即發送寄存器數據而不是尋址寄存器來直接寫入。單個寄存器設備的一個例子是一個8位I2C開關,它通過I2C命令進行控制。由于它有1位來啟用或禁用信道,所以只需要1個寄存器,而主機只需在從屬地址之后寫入寄存器數據,跳過寄存器號。
4.1通過I2C總線寫從機
要在I2C總線上寫入,主機將在總線上發送一個啟動條件,其中從機的地址以及設置為0的最后一位(R/W位)表示寫入。在從機發送確認位后,主機將發送它希望寫入的寄存器的地址。從機將再次確認,讓主機知道它已經準備好了。此后,主機將開始向從機發送寄存器數據,直到主機發送了所需的所有數據(有時這只是一個字節)主機將在STOP條件下終止傳輸。
下圖完整的展示了主機向從機寫一個字節的時序圖,需要注意的是:
[1]主機在開始信號之后,需要先發送尋址字節,其中第0位為0表示主機要向從機寫數據。
[2]從機在接收到每個數據之后,需要發送ACK信號,表示成功接收到數據。
[3]主機在發送完數據之后,發送停止信號。
4.2通過I2C總線讀從機
讀從機與寫非常相似,但需要額外的步驟。為了讀取從機,主設備必須首先指示從機它希望從哪個寄存器讀取數據。這是通過主機以與寫入類似的方式開始傳輸,發送R/W位等于0(表示寫入)的地址,然后是它希望讀取的寄存器地址來完成的。一旦從設備確認該寄存器地址,主設備將再次發送START條件,隨后是R/W位設置為1的從設備地址(表示讀取)。這一次,從設備將確認讀取請求,主設備釋放SDA總線,但將繼續向從設備提供時鐘。在事務的這一部分,主設備將成為主接收機,從設備將成為從發射機。
主設備將繼續發送時鐘脈沖,但將釋放SDA線路,以便從設備可以傳輸數據。在數據的每個字節結束時,主機將向從機發送ACK,讓從機知道它已經準備好接收更多數據。一旦主設備接收到預期的字節數,它將發送NACK,向從設備發出信號以停止通信并釋放總線。主機將使用STOP(停止)條件進行跟蹤。
下圖完整的展示了主機由從機讀取數據的時序圖,需要注意的是:
[1]主機在開始信號之后,需要先發送尋址字節,其中第1位為1,表示主機由從機讀取數據。
[2]主機在接收到每個數據之后,需要發送ACK信號,表示成功接收到數據。
[3]主機在接收完最后一個字節的數據之后,發送“NACK”表示接收完成,之后,從機放棄SDA的控制權,主機發送停止信號,數據接收過程結束。
5. 送apb_i2c工程和中英文協議
關注微信公眾號《芯片驗證日記》,后臺回復”i2c”,可得apb_i2c工程和中英文協議對應的百度鏈接。連接中的內容如下圖所示:
6. 參考文獻:
[1] https://baijiahao.baidu.com/s?id=1730544645451197232
[2] https://baijiahao.baidu.com/s?id=1732071884578858046
[3] https://blog.csdn.net/lhl_blog/article/details/107212413
[4] https://embetronicx.com/tutorials/tech_devices/i2c_1/
[5] https://blog.csdn.net/qq_38942623/article/details/123837341
[6] https://blog.csdn.net/qq_38942623/article/details/124386021
[7] Understanding the I2C Bus, TEXAS INSTRUMENTS
[8] UM10204 I2C-bus specification and user manual
[9] I2C Interface Technical Deep Dive
[10] THE I2C-BUS SPECIFICATION VERSION 2.1
[11] I2C總線規范
7. 同類文章推薦
SPI協議詳解+送apb_spi和ahb_spi工程
詳解SPI通信協議
uart協議詳解+送apb_uart項目
寫文章不易,如果覺得對您有幫助,麻煩一鍵三連,或者賞個雞腿也行!
-
上拉電阻
+關注
關注
5文章
360瀏覽量
30635 -
總線
+關注
關注
10文章
2890瀏覽量
88146 -
I2C
+關注
關注
28文章
1489瀏覽量
123911 -
推挽
+關注
關注
1文章
62瀏覽量
33688 -
漏極開路
+關注
關注
0文章
15瀏覽量
8400
發布評論請先 登錄
相關推薦
評論