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