關(guān)于IIC協(xié)議及代碼實現(xiàn)
IIC數(shù)據(jù)通信是通過兩根線實現(xiàn)通信的,即SDA和SCL,SDA是數(shù)據(jù)線,SCL是時鐘線,SCL控制SDA的工作時鐘,也就是說當SCL為高電平時SDA上面的數(shù)據(jù)才有效。
本文引用地址:http://cafeforensic.com/article/201611/319919.htm模擬IIC接口設(shè)置:
主要是選擇兩條I/O分別作為SCL和SDA線,在進行數(shù)據(jù)傳輸是確定其輸入輸出功能(配置IOxDIR寄存器)。
標準IIC接口設(shè)置:
以LPC2148為例
第一步:設(shè)置管腳功能選擇寄存器,選擇I/O為SCL,SDA功能
例如:PINSEL0 = (PINSEL0 & (~0xF0)) | 0x50;
第二步:設(shè)置IIC工作頻率,即SCL的時鐘
例如:
if(Mode == I2C_SPEED_400)
第三步:清除所有標志位
I2C0CONCLR = 0xFF;
第四步:設(shè)置主從模式,這里為主模式
I2C0CONSET = 0x40;
第五步:始能IIC接口(enable IIC)
I2C0CONSET |= I2C_FLAG_I2EN;
下面列出IIC進行數(shù)據(jù)通信時滿足的幾個條件:
1)起始條件:當SCL和SDA都為高電平時,如果SDA由高電平變低電平時就認為是起始條件。
IIC_Start()
{
SDA = 1;
delay(2);//這個時間有自己設(shè)定
SCL = 1;
delay(2);
SDA = 0;
delay(2);
SCL = 0;
}
這樣就可以開始進行數(shù)據(jù)通信了,PS:SCL高電平時SDA的數(shù)據(jù)才有效.
2)停止條件:當SCL為高電平時,如果SDA由低電平變?yōu)楦唠娖剑烧J為是一個停止條件,即停止數(shù)據(jù)傳輸,一般主發(fā)送機來控制。
IIC_Stop()
{
SCL = 0;
delay(2);
SDA = 0;
delay(2);
SCL = 1;
delay(2);
SDA = 1;
}
這樣就產(chǎn)生一個停止條件。
2)響應
當主設(shè)備發(fā)送完一字節(jié)數(shù)據(jù)時,從設(shè)備會產(chǎn)生一個響應ACK(一位,低電平),此時主設(shè)備釋放SDA線高,如果主設(shè)備接收到一位低電平,表示從設(shè)備產(chǎn)生了一個響應位,因此可以繼續(xù)向從設(shè)備發(fā)送數(shù)據(jù),反之則停止發(fā)送。
bit IIC_RecevAck()
{
CY = SDA;//單片機為例
delay(2);
SCL = 1;
delay(2);
SCL = 0;
delay(2);
return CY;
}
//------當主設(shè)備接收從設(shè)備的一字節(jié)數(shù)據(jù)時,主設(shè)備可以發(fā)送ACK也可以不發(fā)送ACK,如果不發(fā)送ACK表示停止讀取從設(shè)備數(shù)據(jù),反之則可以繼續(xù)接收數(shù)據(jù)。
IIC_SendAck(char ack)//ack=0有響應,ack=1表示不發(fā)送響應,停止接收。
{
if(ack == 0)
{
SDA = 0;
}
else
{
SDA = 1;
}
SCL = 1;
delay(2);
SCL = 0;
}
下面舉例說明IIC進行一字節(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拉低,等待響應位,也可以通過IIC_RecvAck()來拉低
}
//--------------------------------------------------------
BYTE IIC_ReadOneByte()//一般由主設(shè)備先發(fā)送一字節(jié)給從設(shè)備,讓從設(shè)備發(fā)送數(shù)據(jù)給主設(shè)備
{
BYTE
SDA = 1; //單片機當管腳作輸入時,寫入1,默認為輸出功能。
for(j = 0; j < 8; j++)
{
data <<= 1;
SCL = 1;
delay(2);
data = SDA;
SCL = 0;
delay(2);
}
return data;
}
評論