i2c匯流排的通訊過程(見圖4-8)主要包含三個主要階段:起始階段、資料傳輸階段和終止階段。
1. 起始階段
在i2c匯流排不工作的情況下,sda(資料線)和scl(時鐘線)上的訊號均為高電平。如果此時主機需要發起新的通訊請求,那麼需要首先通過sda和scl發出起始標誌。當scl為高電平時,sda電平從高變低,這一變化表示完成了通訊的起始條件。
在起始條件和資料通訊之間,通常會有延時要求
,具體的指標會在裝置廠商的規格說明書中給出。
2. 資料傳輸階段
i2c匯流排的資料通訊是以位元組(8位)作為基本單位在sda上進行序列傳輸的。乙個位元組的傳輸需要9個時鐘週期。其中,位元組中每一位的傳輸都需要乙個時鐘週期,當新的scl到來時,scl為低電平,此時資料傳送方根據當前傳輸的資料位控制sda的電平訊號。如果傳輸的資料位為"1",就將sda電平拉高;如果傳輸的資料位為"0",就將sda的電平拉低。當sda上的資料準備好之後,scl由低變高,此時資料接收方將會在下一次scl訊號變低之前完成資料的接收。當8位資料傳送完成後,資料接收方需要乙個時鐘週期以使用sda傳送ack訊號,表明資料是否接收成功。當ack訊號為"0"時,說明接收成功;為"1"時,說明接收失敗。每個位元組的傳輸都是由高位(msb)到低位(lsb)依次進行傳輸。
i2c匯流排協議中規定,資料通訊的第乙個位元組必須由主機發出,內容為此次通訊的目標裝置位址和資料通訊的方向(讀/寫)。在這個位元組中,第1~7位為目標裝置位址,第0位為通訊方向,當第0位為"1"時表示讀,即後續的資料由目標裝置發出主機進行接收;當第0位為"0"時表示寫,即後續的資料由主機發出目標裝置進行接收。在資料通訊過程中,總是由資料接收方發出ack訊號。
3. 終止階段
當主機完成資料通訊,並終止本次傳輸時會發出終止訊號。當scl 是高電平時,sda電平由低變高,這個變化意味著傳輸終止。
下面給出了模擬i2c匯流排進行讀寫的偽**,用以說明如何使用gpio實現i2c通訊:
#define sda 254 //定義sda所對應的gpio介面編號
#define scl 255 //
定義scl所對應的gpio介面編號
#define outp 1 //
表示gpio介面方向為輸出
#define inp 0 //
表示gpio介面方向為輸入
/*i2c起始條件
*/int
i2c_start()
/*i2c終止條件
*/void
i2c_stop()
/*i2c讀取ack訊號(寫資料時使用)
返回值 :0表示ack訊號有效;非0表示ack訊號無效
*/unsigned
char
i2c_read_ack()
/*i2c發出ack訊號(讀資料時使用)
*/int
i2c_send_ack()
/*i2c位元組寫
*/void i2c_write_byte(unsigned char
b)
i2c_read_ack();
//檢查目標裝置的ack訊號
} /*
i2c位元組讀
*/unsigned
char
i2c_read_byte()
i2c_send_ack();
//向目標裝置傳送ack訊號
return
r;
} /*
i2c讀操作
buf:讀緩衝區
len:讀入位元組的長度
*/void i2c_read(unsigned char addr, unsigned char* buf, int
len)
/*i2c寫操作
buf:寫緩衝區
len:寫入位元組的長度
*/void i2c_write (unsigned char addr, unsigned char* buf, int
len)
使用GPIO模擬I2C匯流排進行通訊
下面給出了模擬i2c匯流排進行讀寫的偽 用以說明如何使用gpio實現i2c通訊 define sda 254 定義sda所對應的gpio介面編號 define scl 255 定義scl所對應的gpio介面編號 define outp 1 表示gpio介面方向為輸出 define inp 0 表示g...
普通IO模擬i2c匯流排
一 i2c匯流排協議 二.普通io模擬i2c匯流排 三.簡單i2c裝置驅動例項 下面簡單的微控制器程式,理解之後會讓你對i2c匯流排有更深的認識,思路 1.向eeprom中通過i2c匯流排寫入乙個位元組 2.通過i2c匯流排讀出寫入的位元組 3.如果寫入和讀出成功點亮發光二極體 執行結果 d1亮,程...
i2c匯流排時序
一心想踏入linux device driver的世界,想著i2c匯流排相對於usb等其他匯流排較為簡單,就以i2c作為切入點,希望可以逐步理解ldd的設計思想,並能理解其裝置模型的概念。在此對近期於i2c匯流排及驅動原始碼的理解做備忘,以免徒勞。平台友善之臂s70 tiny6410 cpusams...