標(biāo)題: I2C通信協(xié)議簡(jiǎn)介 [打印本頁(yè)]
作者: CWKQL 時(shí)間: 2018-2-22 09:54
標(biāo)題: I2C通信協(xié)議簡(jiǎn)介
I2C通信協(xié)議簡(jiǎn)介
摒棄復(fù)雜的情況,這里只對(duì)I2C做簡(jiǎn)單的介紹。
一、I2C 總線的一些特征:
• 只要求兩條總線線路一條串行數(shù)據(jù)線SDA 一條串行時(shí)鐘線SCL
• 每個(gè)連接到總線的器件都可以通過(guò)唯一的地址和一直存在的簡(jiǎn)單的主機(jī)從機(jī)關(guān)系軟件設(shè)定地址主機(jī)可以作為主機(jī)發(fā)送器或主機(jī)接收器
• 它是一個(gè)真正的多主機(jī)總線如果兩個(gè)或更多主機(jī)同時(shí)初始化數(shù)據(jù)傳輸可以通過(guò)沖突檢測(cè)和仲裁防止數(shù)據(jù)被破壞
• 串行的8 位雙向數(shù)據(jù)傳輸位速率在標(biāo)準(zhǔn)模式下可達(dá)100kbit/s 快速模式下可達(dá)400kbit/s 高速模式下可達(dá)3.4Mbit/s
• 片上的濾波器可以濾去總線數(shù)據(jù)線上的毛刺波保證數(shù)據(jù)完整
• 連接到相同總線的IC 數(shù)量只受到總線的最大電容400pF 限制
二、I2C總線在傳送數(shù)據(jù)過(guò)程中共有三種類(lèi)型信號(hào):開(kāi)始信號(hào)、結(jié)束信號(hào)和應(yīng)答信號(hào)。
開(kāi)始信號(hào):SCL為高電平時(shí),SDA由高電平向低電平跳變,開(kāi)始傳送數(shù)據(jù)。
結(jié)束信號(hào):SCL為高電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)。
應(yīng)答信號(hào):接收數(shù)據(jù)的IC在接收到8bit數(shù)據(jù)后,向發(fā)送數(shù)據(jù)的IC發(fā)出特定的低電平脈沖,表示已收到數(shù)據(jù)
起始和結(jié)束:
bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; // SDA線為低電平則總線忙,退出
SDA_L; // 拉低SDA線(當(dāng)SCL為高電平時(shí),SDA由高電平向低電平跳變表示開(kāi)始信號(hào))
I2C_delay();
if(SDA_read) return FALSE; // SDA線為高電平則總線出錯(cuò),退出
SDA_L; //數(shù)據(jù)為準(zhǔn)備好時(shí),拉低SCL線
I2C_delay();
return TRUE;
}
發(fā)出開(kāi)始信號(hào)之后,設(shè)備在數(shù)據(jù)未準(zhǔn)備好時(shí),拉低SCL線,這樣主設(shè)備可知從設(shè)備未發(fā)送數(shù)據(jù),從設(shè)備在數(shù)據(jù)準(zhǔn)備好,可以發(fā)送的時(shí)候,停止拉低SCL線,這時(shí)候才開(kāi)始真正的數(shù)據(jù)傳輸
void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H; // SCL為高電平時(shí),SDA由低電平向高電平跳變,結(jié)束傳送數(shù)據(jù)
I2C_delay();
SDA_H;
I2C_delay();
}
STOP在單主環(huán)境下非必要,但在多主環(huán)境就非常必要,主控總線的設(shè)備發(fā)送STOP后,通知總線其他設(shè)備總線已經(jīng)閑置.
void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}
當(dāng)主機(jī)作為接收設(shè)備時(shí),主機(jī)對(duì)最后一個(gè)字節(jié)不應(yīng)答,以向發(fā)送設(shè)備(從設(shè)備)標(biāo)識(shí)數(shù)據(jù)傳送結(jié)束。這是因?yàn)槊看蝹鬏敹紤?yīng)得到應(yīng)答信號(hào)后再進(jìn)行下一個(gè)字節(jié)傳送。如果此時(shí)接收機(jī)應(yīng)答了,那它就接收的不是最后一個(gè)字節(jié)了。如果是最后一個(gè)字節(jié),第9個(gè)時(shí)鐘周期發(fā)送的是非應(yīng)答信號(hào)(此時(shí)發(fā)送的不是應(yīng)答信號(hào)就是非應(yīng)答信號(hào)),最后發(fā)送停止信號(hào)。
1)主發(fā)從收:主START->主發(fā)地址->從ACK->(主發(fā)數(shù)據(jù)->從ACK(循環(huán)))->主STOP或主 START啟動(dòng)下一次傳輸
這一過(guò)程中,主控SCL線,從只在ACK時(shí)控SDA線,其他時(shí)刻主控SDA線。
2)主收從發(fā):主START->從發(fā)地址->主ACK->(從發(fā)數(shù)據(jù)->主ACK(循環(huán)))->接受至最后一個(gè)字節(jié)時(shí),主 NACK->主 STOP 或主START啟動(dòng)下一次傳輸
并非每傳輸8位數(shù)據(jù)之后,都會(huì)有ACK信號(hào),有以下3中例外
- 當(dāng)從機(jī)不能響應(yīng)從機(jī)地址時(shí)(例如它正忙于其他事而無(wú)法響應(yīng)IIC總線的操作,或者這個(gè)地址沒(méi)有對(duì)應(yīng)的從機(jī)),在第9個(gè)SCL周期內(nèi)SDA線沒(méi)有拉低,即沒(méi)有ACK信號(hào)。這時(shí),主機(jī)發(fā)出一個(gè)P信號(hào)終止傳輸或者重新發(fā)出一個(gè)S信號(hào)開(kāi)始新的傳輸。
- 如果從機(jī)接收器在傳輸過(guò)程中不能接收更多的數(shù)據(jù)時(shí),它不會(huì)發(fā)出ACK信號(hào)。這樣,主機(jī)就可以意識(shí)到這點(diǎn),從而發(fā)出一個(gè)P信號(hào)終止傳輸或者重新發(fā)出一個(gè)S信號(hào)開(kāi)始新的傳輸。
- 主機(jī)接收器在接收到最后一個(gè)字節(jié)后,也不會(huì)發(fā)出ACK信號(hào)。于是,從機(jī)發(fā)送器釋放SDA線,以允許主機(jī)發(fā)出P信號(hào)結(jié)束傳輸。
位傳輸:
主機(jī)向從機(jī)發(fā)送一字節(jié)數(shù)據(jù)
void I2C_SendByte(u8 SendByte) //數(shù)據(jù)從高位到低位
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H;
else
SDA_L;
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}
三、7位尋址
在起始條件S 后發(fā)送了一個(gè)從機(jī)地址,這個(gè)地址共有7 位,緊接著的第8 位是數(shù)據(jù)方向位R/W ,0表示發(fā)送寫(xiě)、1表示請(qǐng)求數(shù)據(jù)讀:
數(shù)據(jù)傳輸一般由主機(jī)產(chǎn)生的停止位P終止,但是如果主機(jī)仍希望在總線上通訊它可以產(chǎn)生重復(fù)起始條件Sr和尋址另一個(gè)從機(jī),而不是首先產(chǎn)生一個(gè)停止條件。
完整的數(shù)據(jù)傳輸:

stm32如何建立與EEPROM的通訊
1、 配置I/O端口,確定并配置I2C的模式,使能GPIO和I2C時(shí)鐘。
2、 寫(xiě):
檢測(cè)SDA是否空閑;
->按I2C協(xié)議發(fā)出起始訊號(hào);
->發(fā)出7位器件地址和寫(xiě)模式;
->要寫(xiě)入的存儲(chǔ)區(qū)首地址;
->用頁(yè)寫(xiě)入方式或字節(jié)寫(xiě)入方式寫(xiě)入數(shù)據(jù);
3、 讀:
檢測(cè)SDA是否空閑;
->按I2C協(xié)議發(fā)出起始訊號(hào);
->發(fā)出7位器件地址和寫(xiě)模式(偽寫(xiě));
->發(fā)出要讀取的存儲(chǔ)區(qū)首地址;
->重發(fā)起始訊號(hào);
->發(fā)出7位器件地址和讀模式;
->接收數(shù)據(jù);
| 歡迎光臨 (http://www.raoushi.com/bbs/) |
Powered by Discuz! X3.1 |