I2C基本概念
I2C (芯片間)總線接口連接微控制器和串行I2C總線。它提供多主機功能,控制所有I2C總線特定的時序、協議、仲裁和定時。支持標准和快速兩種模式,同時與SMBus 2.0兼容。I2C模塊有多種用途,包括CRC碼的生成和校驗、 SMBus(系統管理總線—System Management Bus)和PMBus(電源管理總線—Power Management Bus)。根據特定設備的需要,可以使用DMA以減輕CPU的負擔。
I2C功能描述
I2C模塊接收和發送數據,並將數據從串行轉換成並行,或並行轉換成串行。可以開啟或禁止中斷。接口通過數據引腳(SDA)和時鍾引腳(SCL)連接到I2C總線。允許連接到標准(高達100kHz)或快速(高達400kHz)的I2C總線。
I2C采用一根雙向串行數據線SDA和一根雙向串行時鍾線SCL實現主/從設備間的多主串行通信。
I2C總線協議:
I2C協議規定,總線上數據的傳輸必須以一個起始信號作為開始條件,以一個結束信號作為傳輸的停止條件。起始和結束信號總是由主設備產生。I2C總線在傳輸數據的過程中一共有三種信號:開始信號、結束信號、應答信號。
- 開始信號:SCL為高電平而SDA由高到低的跳變,表示產生一個起始條件
- 結束信號:SCL為高電平而SDA由低到高的跳變,表示產生一個 停止條件
- 應答信號:接收數據的IC在接收到8bit的數據后,向發送數據的IC發出一個特定的低電平脈沖,表示已經接收到數據。例如CPU向受控單元發出一個信號后,等待受控單元發出一個應答信號,CPU接收到應答信號則再根據實際情況決定是否發送下一個信號;若沒有接收到應答信號,則可以判斷受控單元出現了故障。
總線在空閑狀態時,SCL和SDA都保持着高電平
這三種信號里,起始信號是必須需要的,而結束信號和應答信號都可以視情況不要。
在起始條件產生后,總線處於忙狀態,由本次數據傳輸的主從設備獨占,其他I2C器件無法訪問總線;而在停止條件產生后,本次數據傳輸的主從設備 將釋放總線,總線再次處於空閑狀態。
數據傳輸:
數據和地址按8位/字節進行傳輸,高位在前。主設備在SCL線上產生每個 時鍾脈沖的過程中將在SDA線上傳輸一個數據位,當一個字節按數據位從高位到低位的順序傳輸完后,緊接着從設備將拉低SDA線,回傳給主設備一個應答位, 此時才認為一個字節真正的被傳輸完成。
I2C總線上每個設備都對應唯一地址,主從設備的傳輸都是建立在地址之上的。也就是說,主設備在傳輸有效數據之前要先指定從設備的地址,地址指定的過程和上面數據傳輸的過程一樣,只不過大多數從設備的地址是7位的,然后協議規定再給地址添加一個最低位用來表示接下來 數據傳輸的方向,0表示主設備向從設備寫數據,1表示主設備向從設備讀數據
主模式下:跟在起始條件后的1或2個字節是地址(7位模式為1個字節, 10位模式為2個字節)。
I2C模式選擇:
接口可以下述4種模式中的一種運行:
- 從發送器模式
- 從接收器模式
- 主發送器模式
- 主接收器模式
該模塊默認地工作於從模式。接口在生成起始條件后自動地從從模式切換到主模式;當仲裁丟失或產生停止信號時,則從主模式切換到從模式。允許多主機功能。
I2C從模式
從發送器:
在接收到地址和清除ADDR位后,從發送器將字節從DR寄存器經由內部移位寄存器發送到SDA線上。從設備保持SCL為低電平,直到ADDR位被清除並且待發送數據已寫入DR寄存器。 (見下圖中的EV1和EV3)。
當收到應答脈沖時:
-
TxE位被硬件置位,如果設置了ITEVFEN和ITBUFEN位,則產生一個中斷。
如果TxE位被置位,但在下一個數據發送結束之前沒有新數據寫入到I2C_DR寄存器,則BTF位被置位,在清除BTF之前I2C接口將保持SCL為低電平;讀出I2C_SR1之后再寫入I2C_DR寄存器將清除BTF位。
從接收器:
在接收到地址並清除ADDR后,從接收器將通過內部移位寄存器從SDA線接收到的字節存進DR寄存器。 I2C接口在接收到每個字節后都執行下列操作:
-
如果設置了ACK位,則產生一個應答脈沖
-
硬件設置RxNE=1。如果設置了ITEVFEN和ITBUFEN位,則產生一個中斷。
如果RxNE被置位,並且在接收新的數據結束之前DR寄存器未被讀出, BTF位被置位,在清除BTF之前I2C接口將保持SCL為低電平;讀出I2C_SR1之后再寫入 I2C_DR寄存器將清除BTF位。(見下圖)。
關閉通信:
在傳輸完最后一個數據字節后,主設備產生一個停止條件, I2C接口檢測到這一條件時:
- 設置STOPF=1,如果設置了ITEVFEN位,則產生一個中斷。然后I2C接口等待讀SR1寄存器,再寫CR1寄存器。 (見上圖的EV4)。
I2C主模式
主發送器:
在發送了地址和清除了ADDR位后, 主設備通過內部移位寄存器將字節從DR寄存器發送到SDA線上。 主設備等待,直到TxE被清除, (見下圖的EV8)。
當收到應答脈沖時:
- TxE位被硬件置位,如果設置了INEVFEN和ITBUFEN位,則產生一個中斷。如果TxE被置位並且在上一次數據發送結束之前沒有寫新的數據字節到DR寄存器,則BTF被硬件置位,在清除BTF之前I2C接口將保持SCL為低電平;讀出I2C_SR1之后再寫入I2C_DR寄存器將清除BTF位。
關閉通信:
在DR寄存器中寫入最后一個字節后,通過設置STOP位產生一個停止條件(見圖245的EV8_2),然后I2C接口將自動回到從模式(M/S位清除)。
主接收器:
在發送地址和清除ADDR之后, I2C接口進入主接收器模式。在此模式下, I2C接口從SDA線接收數據字節,並通過內部移位寄存器送至DR寄存器。在每個字節后, I2C接口依次執行以下操作:
- 如果ACK位被置位,發出一個應答脈沖。
- 硬件設置RxNE=1,如果設置了INEVFEN和ITBUFEN位,則會產生一個中斷(見圖246的EV7)。如果RxNE位被置位,並且在接收新數據結束前, DR寄存器中的數據沒有被讀走,硬件將設置BTF=1,在清除BTF之前I2C接口將保持SCL為低電平;讀出I2C_SR1之后再讀出I2C_DR寄存器將清除BTF位。
關閉通信:
主設備在從從設備接收到最后一個字節后發送一個NACK。接收到NACK后,從設備釋放對SCL和SDA線的控制;主設備就可以發送一個停止/重起始條件。
- 為了在收到最后一個字節后產生一個NACK脈沖,在讀倒數第二個數據字節之后(在倒數第二個RxNE事件之后)必須清除ACK位。
- 為了產生一個停止/重起始條件,軟件必須在讀倒數第二個數據字節之后(在倒數第二個RxNE事件之后)設置STOP/START位。
- 只接收一個字節時,剛好在EV6之后(EV6_1時,清除ADDR之后)要關閉應答和停止條件的產生位。
- 在產生了停止條件后, I2C接口自動回到從模式(M/SL位被清除)。