新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 關(guān)于IIC協(xié)議及代碼實(shí)現(xiàn)

關(guān)于IIC協(xié)議及代碼實(shí)現(xiàn)

作者: 時(shí)間:2016-11-22 來(lái)源:網(wǎng)絡(luò) 收藏
最近學(xué)了下IIC協(xié)議,這里想把模擬IIC接口和標(biāo)準(zhǔn)IIC接口總結(jié)一下。(這里只介紹一主一從的情況)

IIC數(shù)據(jù)通信是通過(guò)兩根線實(shí)現(xiàn)通信的,即SDA和SCL,SDA是數(shù)據(jù)線,SCL是時(shí)鐘線,SCL控制SDA的工作時(shí)鐘,也就是說(shuō)當(dāng)SCL為高電平時(shí)SDA上面的數(shù)據(jù)才有效。

本文引用地址:http://www.2s4d.com/article/201611/319919.htm

模擬IIC接口設(shè)置:

主要是選擇兩條I/O分別作為SCL和SDA線,在進(jìn)行數(shù)據(jù)傳輸是確定其輸入輸出功能(配置IOxDIR寄存器)。

標(biāo)準(zhǔn)IIC接口設(shè)置:

LPC2148為例

第一步:設(shè)置管腳功能選擇寄存器,選擇I/O為SCL,SDA功能

例如:PINSEL0 = (PINSEL0 & (~0xF0)) | 0x50; //p0.2,p0.3 iic

第二步:設(shè)置IIC工作頻率,即SCL的時(shí)鐘

例如:

if(Mode == I2C_SPEED_400)
{
//--- I2C Timing for 58 MHz (t = 16.954 ns) ---
I2C0SCLH = 47; //-- more then 0.6 us - 0.8
I2C0SCLL = 93; //-- more then 1.3 us - 1.4
}
else //Slow
{
I2C0SCLH = 47*4;
I2C0SCLL = 93*4;
}

第三步:清除所有標(biāo)志位

I2C0CONCLR = 0xFF;

第四步:設(shè)置主從模式,這里為主模式

I2C0CONSET = 0x40;

第五步:始能IIC接口(enable IIC)

I2C0CONSET |= I2C_FLAG_I2EN;

下面列出IIC進(jìn)行數(shù)據(jù)通信時(shí)滿足的幾個(gè)條件:

1)起始條件:當(dāng)SCL和SDA都為高電平時(shí),如果SDA由高電平變低電平時(shí)就認(rèn)為是起始條件。

IIC_Start()

{

SDA = 1;

delay(2);//這個(gè)時(shí)間有自己設(shè)定

SCL = 1;

delay(2);

SDA = 0;

delay(2);

SCL = 0;

}

這樣就可以開(kāi)始進(jìn)行數(shù)據(jù)通信了,PS:SCL高電平時(shí)SDA的數(shù)據(jù)才有效.

2)停止條件:當(dāng)SCL為高電平時(shí),如果SDA由低電平變?yōu)楦唠娖剑烧J(rèn)為是一個(gè)停止條件,即停止數(shù)據(jù)傳輸,一般主發(fā)送機(jī)來(lái)控制。

IIC_Stop()

{

SCL = 0;

delay(2);

SDA = 0;

delay(2);

SCL = 1;

delay(2);

SDA = 1;

}

這樣就產(chǎn)生一個(gè)停止條件。

2)響應(yīng)

當(dāng)主設(shè)備發(fā)送完一字節(jié)數(shù)據(jù)時(shí),從設(shè)備會(huì)產(chǎn)生一個(gè)響應(yīng)ACK(一位,低電平),此時(shí)主設(shè)備釋放SDA線高,如果主設(shè)備接收到一位低電平,表示從設(shè)備產(chǎn)生了一個(gè)響應(yīng)位,因此可以繼續(xù)向從設(shè)備發(fā)送數(shù)據(jù),反之則停止發(fā)送。

bit IIC_RecevAck()

{

CY = SDA;//單片機(jī)為例

delay(2);

SCL = 1;

delay(2);

SCL = 0;

delay(2);

return CY;

}

//------當(dāng)主設(shè)備接收從設(shè)備的一字節(jié)數(shù)據(jù)時(shí),主設(shè)備可以發(fā)送ACK也可以不發(fā)送ACK,如果不發(fā)送ACK表示停止讀取從設(shè)備數(shù)據(jù),反之則可以繼續(xù)接收數(shù)據(jù)。

IIC_SendAck(char ack)//ack=0有響應(yīng),ack=1表示不發(fā)送響應(yīng),停止接收。

{

if(ack == 0)

{

SDA = 0;

}

else

{

SDA = 1;

}

SCL = 1;

delay(2);

SCL = 0;

}

下面舉例說(shuō)明IIC進(jìn)行一字節(jié)數(shù)據(jù)的傳輸

IIC_SendOneByte(unsigned char data)//主設(shè)備向從設(shè)備發(fā)送一字節(jié)數(shù)據(jù)

{

unsigned char i;

for (i = 0; i < 8; i++)

{

if (data & 0x80)

{

SDA = 1;

}

else

{

SDA = 0;

}

delay(2);

SCL = 1;

delay(2);

SCL = 0;

delay(2);

data <<= 1;

}

SDA = 0;//可以把SDA拉低,等待響應(yīng)位,也可以通過(guò)IIC_RecvAck()來(lái)拉低

}

//--------------------------------------------------------

BYTE IIC_ReadOneByte()//一般由主設(shè)備先發(fā)送一字節(jié)給從設(shè)備,讓從設(shè)備發(fā)送數(shù)據(jù)給主設(shè)備

{

BYTEj,data = 0;

SDA = 1; //單片機(jī)當(dāng)管腳作輸入時(shí),寫(xiě)入1,默認(rèn)為輸出功能。

for(j = 0; j < 8; j++)

{

data <<= 1;

SCL = 1;

delay(2);

data = SDA;

SCL = 0;

delay(2);

}

return data;

}



評(píng)論


技術(shù)專(zhuān)區(qū)

關(guān)閉