i2c匯流排是由
philips
公司開發的一種簡單、雙向二線制同步序列匯流排。它只需要兩根線即可在連線於匯流排上的器件之間傳送資訊。
一般是用於連線微控制器及其外圍裝置,由兩根線組成,分別是:時鐘線sda和資料線scl ,在cpu和被控ic或是ic與ic之間雙向傳遞,高速的ic匯流排一般可以達到400kbps以上。
事實上,i2c匯流排通訊實際上是一種通訊協議,通過一種已經制定好的約束關係在兩個儲存器之間來回的傳輸需要的資料。那麼這種協議或者說這種約束的具體內容是怎麼樣的呢,在有了資料線scl和時鐘線scl之後是如何進行資料的傳輸的呢?
我們知道有時鐘線也就相當於有了總指揮,而資料線是需要在時鐘線處於不同的電平的時候做出不同的反應來表示幾種資料傳輸中需要的標誌,比如說,傳輸乙個資料,什麼時候開始呢,什麼時候結束呢,資料來了,如何告訴對方做好準備呢?這些都是傳輸資料時需要明確規定的訊號。下面是這幾種訊號的簡單介紹。
(1)開始訊號:
scl
為高電平時,
sda
由高電平向低電平跳變,開始傳送資料。
(2)結束訊號:
scl
為高電平時,
sda
由低電平向高電平跳變,結束傳送資料。
(3)應答訊號:接收資料的
ic 在接收到
8bit
資料後,向傳送資料的
ic 發出特定的低電平脈衝,
表示已收到資料。
cpu
向受控單元發出乙個訊號後,等待受控單元發出乙個應答訊號,
cpu
接收到應答訊號後,根據實際情況作出是否繼續傳遞訊號的判斷。若未收到應答訊號,由判斷為
受控單元出現故障。
這些訊號中,起始訊號是必需的,結束訊號和應答訊號,都可以不要。
除了這些訊號標誌外,下面對幾種i2c的狀態做簡單的介紹:
(1) 空閒狀態:當沒有資料需要傳輸的時候,也就是說這個時候i2c匯流排是處於空閒的,那就讓它休息就好不需要工作,這時,sda和scl兩根訊號線同時處於高電平就規定為匯流排的空閒狀態。
(2) 起始訊號:也就是前面所說的開始訊號,它是一種電平跳變的時序訊號,當scl為高電平期間,sda由高跳變到低,這就代表著資料傳輸的開始。
(3)停止訊號:具體敘述如上中的結束訊號,這裡不再重複。
(4)應答訊號:傳送器每傳送乙個位元組,就會在時鐘脈衝的第九個脈衝期間釋放資料線sda,然後由接收器反饋乙個應答訊號給傳送器,如果這個應答訊號為低電平,就為有效應答位(ack簡稱應答位),表示接收器已經成功的接受了了這個位元組;如果這個應答訊號為高電平,就為非應答位(nack),一般表示接收器沒有成功接受這個位元組。具體來說,對於反饋回來的有效應答位(ack)的要求是:接收器在第九個時鐘脈衝之前的低電平期間將sda拉低,並且確保在該時鐘的高電平期間為穩定的低電平。 如果接收器是主控器,則在他接受的最後乙個位元組之後,傳送乙個nack訊號,來通知被控傳送器結束資料傳送,並釋放sda線,以便主控接收器傳送乙個停止訊號p。
(5)資料有效性:在i2c匯流排進行資料傳輸時,在時鐘訊號為高電平的期間,資料線上的資料必須保持穩定,也就是說,比如第乙個時鐘脈衝時要傳輸的資料時1,那麼在第乙個時鐘高電平到來之前以及過去之後的這個時間內,資料線上的1(也就是高電平)都要保持為高。只有在時鐘線為低電平期間,資料線上的高電平或低電平才允許變化。
(6)資料的傳輸:在i2c匯流排上傳送的每一位資料都有乙個時鐘脈衝相對應,即在scl序列時鐘的配合下,在sda上逐位的序列傳送每一位資料,資料位的傳輸是邊沿觸發。
void iic_init(void) // (1)本函式的作用很簡單,就是配置兩個io口分別作為時鐘線scl和資料線sda,
//產生 iic 起始訊號
void iic_start(void)
// (2)函式作用已經標出來了,產生起始訊號,具體步驟看函式
//產生 iic 停止訊號
void iic_stop(void) //
(3)函式作用已經標出來了,產生停止訊號,具體步驟看函式
//等待應答訊號到來 //(4)這是當傳輸乙個位元組之後等待應答訊號ack的到來
//返回值: 1,接收應答失敗
// 0,接收應答成功
u8 iic_wait_ack(void)
}iic_scl=0; //時鐘輸出 0
return 0;
}
//產生 ack 應答 // (5)產生ack應答
void iic_ack(void)
//不產生 ack 應答 (6)不產生應答
void iic_nack(void)
//(7)iic 傳送乙個位元組
//返回從機有無應答
//1,有應答
//0,無應答
void iic_send_byte(u8 txd)
}
//(8)讀 1 個位元組, ack=1 時,傳送 ack, ack=0,傳送 nack
u8 iic_read_byte(unsigned char ack)
if (!ack)
iic_nack(); //傳送 nack
else
iic_ack(); //傳送 ack
return receive;
}
以上部分是參考原子的程式,上面列出了在使用i2c通訊所用到的各個函式,包括產生起始訊號,停止訊號,應答,不應答,傳送乙個位元組和讀取乙個位元組等函式的封裝。使用方便!
下面開始正式介紹i2c通訊的具體實踐內容:
理解:首先無論我們是要讀取還是寫入資料,我們都需指定位址,然後在這個位址裡面讀取或者寫入資料。
寫入資料的具體過程遵從i2c的通訊協議,前面已經介紹過就不再重複說明了。
這裡以24c02(eeprom)這個儲存器為例: (以後學習或者需要使用到其他的儲存器時再新增)
如上圖,以24c02的寫時序為例,(1)傳送乙個start的開始訊號;
(2)傳送寫的命令給24c02(上圖中的device address);
(3)等待應答訊號ack;
(4)傳送需要寫入的位址 (word address);
(5)等待應答訊號ack;
(6)寫入資料(date);
(7)等待應答訊號ack;
(8)傳送停止訊號;
以上是對上面時序圖的解讀,也是主控晶元(stm32f103)對被控晶元寫入資料時的具體步驟(這裡的被控晶元是以24c02為例)。
下面是上述操作的**:
void at24cxx_writeonebyte(u16 writeaddr,u8 datatowrite)
else iic_send_byte(0xa0+((writeaddr/256)<<1)); //傳送器件位址 0xa0,寫資料
iic_wait_ack();
iic_send_byte(writeaddr%256); //傳送低位址
iic_wait_ack();
iic_send_byte(datatowrite); //傳送位元組
iic_wait_ack();
iic_stop(); //產生乙個停止條件
delay_ms(10);
}
總結:至此,i2c的初探學便結束了,總的來說,這種通訊方式還是相對比較簡單的,也只占用了兩個io口。實際的使用效果如何目前還不敢妄下定論。這只是一種在兩個ic之間通行的手段,依據其規定好的方式,對資料進行傳輸。它是乙個完整的資料傳輸過程。有開始,傳輸 ,應答,結束等不同的訊號進行指示。以後還將學到spi,485,can 等通訊方式,屆時再做專門的比較和學習。
本篇部落格其實是本人在學習i2c中的理解和筆記。如此敘述出來,一是加深自己對i2c通訊的理解,二是也希望與各位同學交流,共同進步。當然如果還能對大家有所幫助那更是意外收穫了。本篇部落格也會在以後深入學習中進行補充和加深。本人也只是初學,如果文中有不當或錯誤的地方,還請指正。謝謝!
I2C通訊技術
對於嵌入式開發的朋友來說,i2c協議實在是再熟悉不過了,有太多的器件,採用的都是通過i2c來進行相應的設定。今天,我們就隨便聊聊這個i2c協議。i2c協議中最重要的一點是i2c位址。這個位址有7位和10位兩種形式。7位能夠表示127個位址,而在實際使用中基本上不會掛載如此多的設定,所以很多裝置的位址...
I2C匯流排通訊
uart 屬於非同步通訊,比如電腦傳送給微控制器,電腦只負責把資料通過txd 傳送出來即可,接收資料是微控制器自己的事情。而 i2c 屬於同步通訊,scl 時鐘線負責收發雙方的時鐘節拍,sda 資料線負責傳輸資料。i2c 的傳送方和接收方都以 scl 這個時鐘節拍為基準進行資料的傳送和接收。i2c匯...
i2c通訊的詳細講解 I2C匯流排簡介
本文介紹了內部積體電路 aka i2c 序列通訊協議的基本特性和突出優點。元件之間的通訊 通訊協議 毫無疑問,電子系統的共同特徵是需要在兩個或三個或十個單獨的元件之間共享資訊。工程師已經開發出許多標準協議,可以幫助不同的晶元成功通訊 當您在微控制器或數字訊號處理器的功能列表中 通訊 下面對縮略語時,...