下面是用普通C51實現(xiàn)的I2C基本電平模擬函數(shù)和通用函數(shù)。
/*電平模擬函數(shù)和基本讀寫函數(shù)
void IIC_Start(void);
void IIC_Stop(void);
void SEND_0(void);
void SEND_1(void);
bit Check_Acknowledge(void);
void Write_Byte(uchar b)reentrant;
bit Write_N_Bytes(uchar *buffer,uchar n)reentrant;
bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer);
uchar Read_Byte(void)reentrant;
*/
#include
#include
#include
#include"aiic_51.h"
sbit SCL=P1^6;
sbit SDA=P1^7;
void DELAY(uint t)
{
while(t!=0)
t--;
}
void IIC_Start(void)
{
//啟動I2C總線的函數(shù),當(dāng)SCL為高電平時使SDA產(chǎn)生一個負(fù)跳變
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SDA=0;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
void IIC_Stop(void)
{
//終止I2C總線,當(dāng)SCL為高電平時使SDA產(chǎn)生一個正跳變
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SDA=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
void SEND_0(void)
{
//發(fā)送0,在SCL為高電平時使SDA信號為低
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
void SEND_1(void)
{
//發(fā)送1,在SCL為高電平時使SDA信號為高
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
bit Check_Acknowledge(void)
{
//發(fā)送完一個字節(jié)后檢驗設(shè)備的應(yīng)答信號
SDA=1;
SCL=1;
DELAY(DELAY_TIME/2);
F0=SDA;
DELAY(DELAY_TIME/2);
SCL=0;
DELAY(DELAY_TIME);
if(F0==1)
return FALSE;
return TRUE;
}
void Write_Byte(uchar b)reentrant
{
//向IIC總線寫一個字節(jié)
uchar i;
for(i=0;i<8;i++)
if((b< SEND_1();
else
SEND_0();
}
bit Write_N_Bytes(uchar *buffer,uchar n)reentrant
{
//向I2C總線寫n個字節(jié)
uchar i;
IIC_Start();
for(i=0;i
Write_Byte(buffer);
if(!Check_Acknowledge())
{
IIC_Stop();
return(i==n);
}
}
IIC_Stop();
return TRUE;
}
uchar Read_Byte(void)reentrant
{
//從I2C總線讀一個字節(jié)
uchar b=0,i;
for(i=0;i<8;i++)
{
SDA=1; //釋放總線
SCL=1; //接受數(shù)據(jù)
DELAY(10);
F0=SDA;
DELAY(10);
SCL=0;
if(F0==1)
{
b=b<<1;
b=b|0x01;
}
else
b=b<<1;
}
return b;
}
bit Read_N_Bytes(uchar SlaveAdr,uchar n,uchar *buffer)
{
//從I2C總線讀n個字節(jié)
uchar i;
IIC_Start();
Write_Byte(SlaveAdr); //向總線發(fā)送接收器地址
if(!Check_Acknowledge()) //等待接收器應(yīng)答信號
return FALSE;
for(i=0;i
buffer=Read_Byte();
if(i!=n)
SEND_0(); //發(fā)送應(yīng)答
else
SEND_1(); //發(fā)送非應(yīng)答
}
IIC_Stop();
return TRUE;
}
使用上述代碼,你可以在51上用P1口模擬I2C