14 玩轉STM32之IIC通訊(軟體模擬篇)

14。1 IIC協議詳細說明

IIC有模擬和晶片自帶的兩種方式。軟體模擬方式具有引腳可以任意分配,軟體修改靈活對PCB設計也有一定的優點,但是

缺點也是非常明顯的,因為採用的是軟體進行會產生較長時間的延時,對於一些要求較高的場合並不適用

,比如汽車電子方向、充電樁等這些就不適合用類比電子還有就是一些醫療裝置。因

此建議在設計時優先晶片之中提供的IIC

這章我們先來說說軟體模擬這部分,硬體IIC下一章節會講。

IIC(Inter-Integrated Circuit BUS) 積體電路匯流排,該匯流排NXP(原PHILIPS)公司設計,多用於主控制器和從器件間的一種主從資料互動通訊,在小資料量場合使用,傳輸距離短。

I2C可以支援0kHz~5MHz裝置的多種模式:普通模式(100kHz)、快速模式(400kHz)、快速模式(1MHz)、高速模式(3。4MHz)和超高速模式(5MHz)。

14。1。1 I2C物理層

在I2C通訊總線上,可連線多個I2C通訊裝置,支援多個通訊主機和多個通訊從機。I2C通訊只需要2條雙向匯流排:一條資料線SDA(Serial Data Line,序列資料線),一條時鐘線SCL(Serial Clock Line,序列時鐘線)。

其中:

SDA:用於資料傳輸(傳輸方式:大端傳輸(MSB),一次8bit,即1位元組)

SCL:用於資料同步收發

IIC支援多主控,任何時間點都只有一個主控。每個連線到匯流排的裝置都只有一個獨立的地址,共7bit(也有10bit的,不過用的少點而已)主機正式利用該地址對裝置進行訪問。

先來看個圖:

IIC中SDA和SCL引腳是開開漏電路形式,所以SDA和SCL都要接上拉電阻,當匯流排空閒,SDA和SCL都是高電平。

14 玩轉STM32之IIC通訊(軟體模擬篇)

a.只要求兩條匯流排線路,一條是序列資料線SDA,一條是序列時鐘線SCL。(IIC是半雙工,而不是全雙工)。

b。每個連線到匯流排的器件都可以透過唯一的地址和其它器件通訊,主機/從機角色和地址可配置,主機可以作為主機發送器和主機接收器。

c。IIC是真正的多主機匯流排,(而類似的SPI匯流排協議在每次通訊前都需要把主機定死,IIC可以在通訊過程中,改變主機),如果兩個或更多的主機同時請求匯流排,可以通過沖突檢測和仲裁防止匯流排資料被破壞。但是任意時刻只能有一個主機。

d。傳輸速率在標準模式下可以達到100kb/s,快速模式下可以達到400kb/s。

e。連線到匯流排的IIC裝置數量只是受到匯流排的最大負載電容400pf限制。

14 玩轉STM32之IIC通訊(軟體模擬篇)

14。2。1 I2C協議層

一個完整的IIC資料傳輸含有開始訊號、器件地址、讀寫控制、器件內地址訪問、資料的有效性、訊號應答、停止訊號。

1.I2C匯流排的位傳輸

資料傳輸 :SDA的資料在SCL高電平期間被寫入從機。所以SDA的資料變化要發生在SCL低電平期間。

在時鐘的高電平週期內,SDA線上的資料必須保持穩定,SDA上傳輸1位資料(資料線僅可以在時鐘SCL為低電平時改變)。

14 玩轉STM32之IIC通訊(軟體模擬篇)

2.I2C匯流排的開始訊號和結束訊號

起始條件:當SCL為高電平的時候,SDA線上由高到低的跳變被定義為起始條件。

結束條件:當SCL為高電平的時候,SDA線上由低到高的跳變被定義為停止條件。

匯流排空閒狀態 :SDA :高電平 SCL : 高電平

14 玩轉STM32之IIC通訊(軟體模擬篇)

根據上圖我們分開進行分析:

當SCL為高電平的時候。SDA從高電平到低電平,這就是開始訊號(中間會有極小的延時這點要注意,具體的請參考資料手冊),如下圖:

14 玩轉STM32之IIC通訊(軟體模擬篇)

當SCL為高電平的時候。SDA從低電平到高電平,這就是停止訊號(中間會有極小的延時這點要注意,具體的請參考資料手冊),如下圖:

14 玩轉STM32之IIC通訊(軟體模擬篇)

3.I2C匯流排的位元組格式

14 玩轉STM32之IIC通訊(軟體模擬篇)

傳送到SDA上的每個位元組必須是8位

,每次傳輸可以傳送的位元組數量不受限制,資料從量高有效位(MSB)開始傳輸。接收器在每成功接收一個位元組後都會返回傳送器一個應答位。如果從機要完成一些其他功能(如一個內部中斷服務程式)才能接收或傳送下一個完整的位元組,則可以使SCL保持低電平,從而迫使主機進入等待狀態。當從機準備好新的位元組資料傳輸時,釋放SCL,資料傳輸便繼續進行。

總結:

當IIC主機(不一定是傳送端還是接受端)將8位資料或命令傳出後,會將SDA訊號設定為輸入,等待從機應答( 等待SDA由高電平拉為低電平 )。

若從機正確應答,表明資料或者命令傳輸成功,否則傳輸失敗,注意,

應答訊號是資料接收方傳送給資料傳送方的。

4.I2C應答訊號

在主機發送完每一個位元組資料後,釋放SDA(保持高電平),被定址的接收器在成功接收到每個位元組後,必須產生一個應答ACK(從機將SDA拉低,使它在這個時鐘脈衝的高電平期間保持穩定的低電平)。當從機接收不到資料或通訊故障時,從機必須使SDA保持高電平。主機產生一個結束訊號終止傳輸或者產生重複開始訊號開始新的傳輸。

SDA上傳送的每個位元組必須為8位,其後必須跟一個應答位。12C總線上的所有數量都是以8位位元組傳送的,傳送器每傳送一個位元組,就在時鐘脈衝9期間釋放資料線,由接收器反一個應答訊號。

當應答訊號為低電平時,規定為有效應答位(ACK),表示接收器已經成功地接收了該位元組:當應答訊號為高電平時,規定為非應答位(NACK),一般表示接收器接收該位元組沒有成功。

應答ACK要求接收器在第9個時鐘脈衝之前的低電平期間將SDA拉低,並且確保在該時鐘的高電平期間為穩定的低電平。如果接收器是主機,則在它收到最後一個位元組後,傳送一個NACK訊號,以通知從機發送器結束資料傳送,並釋放SDA,以便主機接收器傳送一個結束訊號。傳輸過程中每次可以傳送的位元組數量不受限制。首先傳輸的是資料的最高有效位(MSB)。

如果從機要在完成一些其他功能之後才能接收或傳送下一個完整的資料位元組,則可以使SCL保

持低電平,從而迫使主機進入等待狀態。當從機準備好接收下一個資料位元組,並且釋放SCL後,資料傳輸繼續。

12C匯流排必須由主器件控制,即必須由主機產生開始訊號、結束訊號和時鐘訊號。在時鐘信

號為高電平時,SDA上的資料必須保持穩定,SDA上的資料狀態僅在時鐘訊號為低電平時才可

以改變,而當SCL為高電平時,SDA上資料的改變被用來表示開始條件和停止條件。需要說明

的是,當主機接收資料時,在最後一個數據位元組,必須傳送一個非應答訊號(NACK),使從機

釋放SDA,以便主機產生一個結束訊號來終止匯流排的資料傳送,

總結下來就這兩句話:

每當主機向從機發送完一個位元組的資料,主機總是需要等待從機給出一個應答訊號,以確認從機是否成功接收到了資料。

從機應答主機所需要的時鐘仍是主機提供的,應答出現在每一次主機完成8個數據位傳輸後緊跟著的時鐘週期,低電平0表示應答,1表示非應答。

5.I2C匯流排的仲裁機制

多主機 - 多個主機能夠在沒有衝突下的情況下,同時共存於總線上,能夠透過匯流排仲裁避免碰撞或資料丟失。

仲裁 - 預先安排的時序,一次只授權一個主機控制匯流排。當SCL線是高電平時,仲裁在SDA線上發生。在其他主機發送低電平時,傳送高電平的主機將會斷開它的資料傳輸級,因為總線上的電平與它自己的電平不同(線與連線)。(也就是地址越小,競爭力越強)。

6.從機地址和子地址

在開始條件(S)後,主機發送一個從機地址(或叫作器件地址),指該器件在I2C總線上被主機定址的地址,地址共有7bit,緊接著的第8bit是資料的讀寫標誌位(0表示寫,1表示讀)。

從機地址構成:

14 玩轉STM32之IIC通訊(軟體模擬篇)

14 玩轉STM32之IIC通訊(軟體模擬篇)

7.主機發送資料流程

(1)主機在檢測到匯流排為空閒狀態(即SDA、SCL均為高電平)時,傳送一個開始訊號(S),開始一次通訊。

(2)主機接著傳送一個命令位元組。該位元組由7位的器件地址和l位讀寫控制位R/W組成(此

時R/W=0)。

(3)相對應的從機收到命令位元組後向主機回饋ACK訊號(ACK=0)。

(4)主機收到從機的ACK訊號後,開始傳送操作器件內部儲存空間的子地址或子地址的高8位。

例如,AT24C02 EEPROM器件內部儲存空間訪問只需要8位地址。而AT24C256EEPROM器件內部容量較大,子地址需要16位,那麼這一個子地址就是16位子地址的高8位。

(5)從機成功接收後,返回一個ACK訊號。

(6)主機收到ACK訊號後再發送下一個資料位元組或子地址的高8位。

(7)從機成功接收後,返回一個ACK訊號。

(8)主機的一次傳送通訊,其傳送的資料數量不受限制,當主機發送完最後一個數據位元組並收到從機的ACK訊號後,透過向從機發送一個結束訊號(P)結束本次通訊並釋放匯流排。從機收到結束訊號後也退出與主機之間的通訊。

I2C匯流排主機發送資料流程(8位從機地址)如圖所示。

14 玩轉STM32之IIC通訊(軟體模擬篇)

I2C匯流排主機發送資料流程(16位從機地址)如圖所示。

14 玩轉STM32之IIC通訊(軟體模擬篇)

8.主機接收資料流程

(1)主機在檢測到匯流排為空閒狀態(即SDA、SCL均為高電平)時,傳送一個開始訊號,開始一次通訊。

(2)主機接著傳送一個命令位元組。該位元組由7位的器件地址和1位讀寫控制位R/W組成(此時R/w=0)。

(3)相對應的從機收到命令位元組後向主機回饋ACK訊號(ACK=0)。

(4)主機收到從機的ACK訊號後開始傳送操作器件內部儲存空間的子地址。

(5)從機成功接收後,返回一個ACK訊號。

(6)主機收到應答訊號後,重新產生一個起始訊號。

(7)主機接著傳送一個命令位元組。該位元組由7位的器件地址和1位讀寫控制位R/W組成(此時R/W=1)。

(8)相對應的從機收到命令位元組後向主機回饋ACK訊號。

(9)接著,主機開始接收從機發送過來的資料,在主機成功接收資料後,如果需要再次接收資料的話,則主機需要向從機發送一個ACK訊號。接收資料的數量不限。

(10)主機接收到最後一個數據的話,主機向從機發送一個NACK訊號。

(11)從機發送一個結束訊號結束本次通訊並釋放匯流排。從機收到結束訊號後也退出與主機

之間的通訊。

12C匯流排主機接收資料流程如圖所示。

14 玩轉STM32之IIC通訊(軟體模擬篇)

14。2 軟體模擬I2C協議程式分析

14。2。1 模擬IIC協議簡要說明

這點在開頭已經說過這裡再說一下:

由於I2C匯流排佔用的I/O僅需要2根,在很多的實際使用過程中,會使用GPIO引腳來模擬I2C的SDA引腳和SCL引腳,並使用程式來實現I2C協議時序。

軟體模擬I2C協議的優點如下。

(1)不需要專門的硬體I2C的控制器。

(2)引腳可以任意分配,方便PCB佈線。

(3)軟體修改靈活。

缺點:由於採用軟體指令會產生時間的延時,不能用於一些時間要求較高的場合。

14。2。2 I2C引腳配置

說明:I2C引腳配置和普通IO配置的過程是一樣的。

1.引腳工作模式初始化

將SDA設定為輸出模式void SDA_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);GPIO_InitStructure。GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure。GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure。GPIO_OType = GPIO_OType_OD;GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure。GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(GPIOH, &GPIO_InitStructure);}

對於IIC主機來說,SCL在整個通訊過程中都是作為輸出模式的、

//將SCL設定為輸出模式void SCL_OUT(void)//PA1{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SCL_GPIO_CLK,ENABLE);GPIO_InitStructure。GPIO_Pin = EEPROM_I2C_SCL_PIN; GPIO_InitStructure。GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure。GPIO_OType = GPIO_OType_OD;GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure。GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);}

對IIC主機,SDA在整個通訊過程中,輸出資料的時候位輸出模式,接収資料或檢查ACK訊號時為輸入模式。

//將SDA設定為輸入模式void SDA_IN(void) //PA0{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SDA_GPIO_CLK,ENABLE);GPIO_InitStructure。GPIO_Pin = EEPROM_I2C_SDA_PIN; GPIO_InitStructure。GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);} //將SDA設定為輸出模式void SDA_OUT(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(EEPROM_I2C_SDA_GPIO_CLK,ENABLE);GPIO_InitStructure。GPIO_Pin = EEPROM_I2C_SDA_PIN; GPIO_InitStructure。GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure。GPIO_OType = GPIO_OType_OD;GPIO_InitStructure。GPIO_PuPd = GPIO_PuPd_UP;GPIO_InitStructure。GPIO_Speed = GPIO_Speed_25MHz; GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);} //初始化IICvoid IIC_Init(void){ SDA_OUT();SCL_OUT();IIC_SCL_Hi ;IIC_SDA_Hi;}

2.I2C引腳讀寫控制

IO操作函式#define IIC_SCL_ Hi GPIO_SetBits(GPIOH,GPIO_Pin_4) //SCL輸出高電平#define IIC_SCL_ Lo GPIO_ResetBits(GPIOH,GPIO_Pin_4) //SCL輸出低電平#define IIC_SDA_ Hi GPIO_SetBits(GPIOH,GPIO_Pin_5) //SDA輸出高電平#define IIC_SDA_ Lo GPIO_ResetBits(GPIOH,GPIO_Pin_5) //SDA輸出低電平#define IIC_SDA_In GPIO_ReadInputDataBit (GPIOH,GPIO_Pin_5) //輸入SDA狀態

主機產生IIC起始訊號

起始訊號:當SCL為高電平時,SDA由高電平轉向低電平,開始進行資料的傳輸工作。開始訊號由主機產生。

14 玩轉STM32之IIC通訊(軟體模擬篇)

主機產生IIC停止訊號

停止訊號:當SCL為高電平時,SDA由低電平轉高向電平,結束資料的傳輸工作。停止訊號由主機產生。

14 玩轉STM32之IIC通訊(軟體模擬篇)

3 模擬檢測ACK訊號

主機每傳送一個數據到匯流排,而且從機每成功收到資料後,都會有一個響應(ACK訊號0)給主機,主機根據檢測到的總線上的電平,判斷通訊是否成功(0成功,1失敗)。

14 玩轉STM32之IIC通訊(軟體模擬篇)

4 軟體模擬產生ACK訊號和NACK訊號

當主機成功接收到從機發送過來的資料,若主機需要接収繼續接收資料,則主機需要返回給從機一個應答訊號,若接収的是最後一個數據,主機會返回給從機一個非應答訊號。

14 玩轉STM32之IIC通訊(軟體模擬篇)

5 軟體模擬傳送一個位元組資料

資料傳輸的時候,若SCL為高,則SDA必須保持穩定,SDA上傳輸1位資料。若SCL為低電平時,SDA才可以改變電平。

14 玩轉STM32之IIC通訊(軟體模擬篇)

6 軟體模擬接收一個位元組資料

讀一個位元組,當ACK=1,傳送ACK訊號,ACK=0,傳送NACK。

14 玩轉STM32之IIC通訊(軟體模擬篇)

7 軟體模擬I2C完整寫操作(以AT24xx為例子)

完整的IIC寫操作:開始訊號、傳送器件地址+寫控制、傳送器件子地址(器件內定址用)、寫資料、檢測ACK訊號、訊號停止。

14 玩轉STM32之IIC通訊(軟體模擬篇)

8 軟體模擬I2C完整讀操作

完整的IIC讀操作:開始訊號、傳送器件地址+寫控制、傳送器件子地址(器件內定址用)、重啟匯流排、讀資料、檢測ACK訊號、訊號停止。

14 玩轉STM32之IIC通訊(軟體模擬篇)