黃忠良
(沙洲職業(yè)工學(xué)院,江蘇 張家港 215600)
在微機控制領(lǐng)域,作為外圍芯片的I2C總線器件因結(jié)構(gòu)簡單,可靠性高,得到了廣泛應(yīng)用。例如存儲芯片24C02,用于記錄密碼及公里數(shù)等,廣泛用于汽車儀表系統(tǒng)。I2C(Inter-Integrated Circuit)總線又稱IIC總線或I2C總線,是PHLIPS公司推出的一種高性能串行總線。采用I2C串行總線技術(shù)可以精簡系統(tǒng)硬件設(shè)計,提高系統(tǒng)可靠性,同時,系統(tǒng)也易于擴充與升級。24C02作為I2C總線接口存儲芯片,屬串行EEPROM,容量2 kbit,斷電后數(shù)據(jù)不會丟失,常用于記錄密碼及公里數(shù)等場合。
24C02引腳圖如圖1所示,24C02與51單片機接口電路如圖2所示。
圖1 24C02引腳
應(yīng)用I2C總線器件進行編程時,由單片機主機完成I2C總線初始化、數(shù)據(jù)傳送、產(chǎn)生時鐘信號和終止發(fā)送功能,從機24C02接收主機發(fā)送的數(shù)據(jù)。I2C總線具有總線裁決功能,主要依靠從機設(shè)備地址實現(xiàn)。對于24C02,8位從機設(shè)備地址的高4位固定為1010,后3位為A2、A1、A0,最后1位是數(shù)據(jù)傳送的方向位 (R/W),主機將數(shù)據(jù)寫入從機為“0”,主機從從機讀出數(shù)據(jù)為“1”。
圖2 24C02與單片機接口電路
只有在起始條件滿足后才能進行數(shù)據(jù)傳送,起始條件與停止條件如圖3所示。
圖3 起始條件與停止條件
從圖3可看出,當SCL處于高電平期間,SDA從高電平向低電平跳變時產(chǎn)生起始條件。當SCL處于高電平期間時,SDA從低電平向高電平跳變時產(chǎn)生停止條件。
位數(shù)據(jù)的有效性及應(yīng)答信號時序如圖4所示。
圖4 位數(shù)據(jù)的有效性及應(yīng)答信號時序
主機進行數(shù)據(jù)傳送時,從最高位開始逐位傳送,時鐘信號線為高電平期間,位數(shù)據(jù)必須保持不變。另外,每傳送8位數(shù)據(jù) (即一個字節(jié))后,從機都必須產(chǎn)生一個應(yīng)答信號。
從機讀操作有3種不同的方式:讀當前地址內(nèi)容、讀隨機地址內(nèi)容、讀順序地址內(nèi)容。圖5為24C02讀隨機地址內(nèi)容操作時序。
圖5 24C02字節(jié)讀時序
隨機讀操作允許主機對存儲器的任意字節(jié)進行讀操作,主機首先通過發(fā)送起始信號、從機設(shè)備地址和它想讀取的字地址執(zhí)行一個偽寫操作。在從機應(yīng)答之后,主機重新發(fā)送起始信號和從機設(shè)備地址,注意此處R/W位為1,從機響應(yīng)并發(fā)送應(yīng)答信號,然后輸出所要求的一個8位字節(jié)數(shù)據(jù),主機不發(fā)送應(yīng)答信號但產(chǎn)生一個停止信號。
24C02字節(jié)寫操作時序如圖6所示。
圖6 24C02字節(jié)寫時序
主機先發(fā)送起始命令,然后發(fā)送從機設(shè)備地址數(shù)據(jù),主機在收到從機產(chǎn)生的應(yīng)答信號后,再發(fā)送一個字的地址數(shù)據(jù),主機再次收到從機的應(yīng)答信號后,最后發(fā)送數(shù)據(jù)到相應(yīng)存儲單元。從機再次應(yīng)答,并在主機產(chǎn)生停止信號后開始內(nèi)部數(shù)據(jù)的擦寫,在內(nèi)部擦寫過程中,從機不再應(yīng)答主機的任何請求。
下列代碼完成24C02字節(jié)寫入。
void write_byte (uchar add,uchar dat )
{
void init ();//I2C總線初始化
void start (void);//起始條件
I2Cwr_byte (0xa0);//寫24C02地址
void ack (void);//從機24C02應(yīng)答
I2Cwr_byte (add);//寫單元地址
void ack (void);//從機24C02應(yīng)答
I2Cwr_byte (dat);//寫數(shù)據(jù)
void ack (void);//從機24C02應(yīng)答
void stop (void);//結(jié)束條件
}
說明:上述用到的幾個被調(diào)用函數(shù)定義如下。
①void init ();//I2C總線初始化
{
sda=1;
scl=1;
}
②void start (void);//起始條件
{
scl=0;//拉低SCL再改SDA以防誤操作
delay ();
sda=1;
delay ();
scl=1;
delay ();
sda=0;
delay ();
}
③I2Cwr_byte(uchar dat) /*單字節(jié)傳送操作*/
{
uchar i;
scl=0;//時鐘線上的信號為低電平期間,數(shù)據(jù)線上電平狀態(tài)允許變化
for (i=0;i<8;i++) //采用逐位傳送方式
{
if (dat&0x80);//為先傳最高位狀態(tài)作準備
{
sda=1;
}
else
{
sda=0;
}
dat=dat<<1;//準備傳送后面一位
delay ();
scl=1;//總線數(shù)據(jù)傳送
delay ();
scl=0;
delay ();
}
sda=1;//主機釋放總線
delay ();
}
④void stop (void);//停止條件
{
scl=0;//先拉低SCL,再改變SDA
delay ();
sda=0;
delay ();
scl=1;
delay ();
sda=1;
delay ();
}
⑤void ack (void) //從機應(yīng)答
{
uchar I;
scl=1;
delay ();
while ((sda==1) && (i<200)) i++;//等待接收應(yīng)答或作超時處理
scl=0;
delay ();
}
另外,有關(guān)24C02字節(jié)的讀取編程見圖5。
24CXX芯片目前已廣泛應(yīng)用在斷電后仍然需要保持存儲數(shù)據(jù)的場合。上述I2C總線存儲單元讀寫編程方法已在Proteus上仿真調(diào)試成功。就I2C總線器件編程開發(fā)而言,正確理解操作時序至關(guān)重要,否則會導(dǎo)致通信失敗。