I2C 協議之軟體模擬時序

2021-08-04 17:16:58 字數 3025 閱讀 5772

i2c 匯流排時 philips 公司推出的一種序列匯流排,具備多主機系統所需的包括匯流排仲裁和高低速器件同步功能的高效能序列匯流排。它只需要兩跟雙向的訊號線,一根資料線 sda,乙個是時鐘線 scl。在 i2c 匯流排上面,每個器件都有自己相應的 i2c 位址,所以在兩個器件之間進行通訊的時候,都要首先呼叫你想要通訊的器件位址,然後等待相應的從器件進行應答之後才開始通訊。首先我們來看一下,乙個 i2c 訊號傳輸的乙個過程,如圖: 

從圖上我們可以看出在 i2c 上面乙個完整訊號的傳輸過程,一定要有乙個始訊號,還有一

個結束訊號,在每個位元組傳輸結束的時候,從機還要提供乙個應答訊號。乙個完整的訊號傳

輸就是這樣子。接下來我們來看一下,i2c 匯流排上面對起始訊號、應答訊號、結束訊號、還

有高低電平的協定是怎麼樣的呢?這裡有兩個要注意的要點: 

1、在匯流排空閒的時候,sda 和 scl 都是高電平的。 

2、在 scl 為高電平期間,sda 必須保持穩定。所以 sda 改變狀態最好在 scl 為低電

平的時候改變,如果在高電平改變的話回被認為是一種有效訊號(如:起始訊號或者結束信

號)1. 起始訊號

起始訊號簡介 scl 線為高電平期間,sda 線由高電平向低電平的變化表示起始訊號, 

訊號時序如圖:

這裡要注意的就是,在 i2c 匯流排上面,當匯流排空閒的時候,scl 和 sda 都是高電平

的。起始訊號,它是需要有一定的保持時間的,在 sda 從高電平向低電平跳變的時候,兩

個先必須至少保持 4.7us 的時間,而跳變之後,也要保持 scl 高電平和 sda 低電平要至

少保持 4us 的時間(從這裡我們看出 i2c 總高速率已經決定了) 。 

//io 口模擬起始訊號 

//產生起始訊號

void i2c_start(void)

2. 結束訊號結束訊號簡介 scl 線為高電平期間,sda 線由低電平向高電平的變化表示終止訊號。 

訊號時序如圖: 

注意的就是這裡保持時間也是有一定限制的。 

//io 口模擬結束訊號 

//產生停止訊號

void i2c_stop(void)

3. 應答訊號應答訊號 

應答,也叫響應。資料的傳輸必須要帶應答。在響應的時鐘脈衝期間(也就是 scl 在高電

平的時候) ,傳送器釋放 sda 線(釋放 sda 意思就是將 sda 拉為高電平,這裡要注

意的是,不能在 scl 為高電平的時候講 sda 從低電平拉到高電平,可以在在 scl 在低

電平的時候,將 sda 拉為高電平等待),然後等待應答,在應答時鐘脈衝器件,接收器 

必須將 sda 拉低,使它在這個時鐘脈衝的高電平期間保持穩定的低電平。而乙個位元組傳輸

完畢之後,接收器沒有應答則表示接收完畢。還有一種情況是,當主機作為接收器的時候,

接收完最後乙個位元組之後,必須向從機發出乙個結束傳送的訊號。這個訊號是由對從機「非 

應答」來實現的。(從上面的規則我們知道,當主機作為接收器的時候,如果是進行應答,

那麼在接收完乙個位元組的最後一位之後產生乙個低電平的時鐘,進行應答。而非應答呢,就

是產生乙個高電平的時鐘,進行應答) 。如果大家不是很理解呢,大家可以參考我們例程

裡面 i2c 的 io 模擬訊號裡面接收資料的函式,最後的應答和非應答。 

//io 口模擬應答訊號 

//主機產生應答訊號 ack

void i2c_ack(void)

//主機不產生應答訊號 nack

void i2c_nack(void)

//等待從機應答訊號

//返回值:1 接收應答失敗

// 0 接收應答成功

u8 i2c_wait_ack(void)

} i2c_scl_l;

return 0;

}

4. 邏輯「1」的表示要傳輸資料,那麼肯定要分傳輸「1」和「0」 ,而在 i2c 上面是怎麼表示這兩個邏輯變數

的呢?如圖: 

一般 i2c 讀取的時候,都是在 scl 的為高電平的時候進行讀取,所以在 scl 為高電平

的時候,需要保持 sda 穩定。而且注意的還有就是他們的保持時間要大於 4us。 

5. 邏輯「0」的表示

邏輯「0」和邏輯「1」的表示其實差不多,只是 sda 正好相反。如圖: 

注意的事項跟邏輯「1」的表示差不多。 

6. io 口模擬傳送乙個位元組資料

//i2c 傳送乙個位元組 

void i2c_send_byte(u8 txd)

}

7. io 口模擬接收乙個位元組資料

//i2c 讀取乙個位元組 

u8 i2c_read_byte(u8 ack)

if(ack==0)

i2c_nack();

else

i2c_ack();

return receive;

}

i2c匯流排時序

一心想踏入linux device driver的世界,想著i2c匯流排相對於usb等其他匯流排較為簡單,就以i2c作為切入點,希望可以逐步理解ldd的設計思想,並能理解其裝置模型的概念。在此對近期於i2c匯流排及驅動原始碼的理解做備忘,以免徒勞。平台友善之臂s70 tiny6410 cpusams...

I2C時序剖析

入門微控制器的同學,往往對時序有一種惶恐。其實,時序就是一張窗戶紙,捅破了,就懂了。今天,跟大家分享一下關於i2c的時序解讀,希望大家能夠舉一反三。基礎知識 i2c有兩根很重要的線 scl 時鐘匯流排 和sda 資料匯流排 scl負責的是節拍,給乙個節奏讓傳送和接收雙方能夠一起左手右手乙個慢動作的同...

協議理解之I2C協議

協議我們參考 eeprom 24c64的datasheet 速度 標準模式下可以達到100kbit s 快速模式下可以達到400kbit s 高速模式下可以達到3.4mbit s i2c匯流排術語 傳送器 傳送資料到匯流排的器件 接收器 從匯流排接收資料的器件 主機 初始化傳送 產生時鐘訊號和終止傳...