- UID
- 852722
|
下面是用普通C51实现的I2C基本电平模拟函数和通用函数。 使用该程序,可以在51上用P1口模拟I2C。
/* 电平模拟函数和基本读写函数
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<String.H>
#Include<Reg52.H>
#Include<Intrins.H>
#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总线的函数,当SCL为高电平时使SDA产生一个负跳变
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SDA=0;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
Void IIC_Stop(Void)
{
//终止I2C总线,当SCL为高电平时使SDA产生一个正跳变
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SDA=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
Void SEND_0(Void)
{
//发送0,在SCL为高电平时使SDA信号为低
SDA=0;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
Void SEND_1(Void)
{
//发送1,在SCL为高电平时使SDA信号为高
SDA=1;
SCL=1;
DELAY(DELAY_TIME);
SCL=0;
DELAY(DELAY_TIME);
}
Bit Check_Acknowledge(Void)
{
//发送完一个字节后检验设备的应答信号
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总线写一个字节
Uchar I;
For(I=0;I<8;I++)
If((B<<I)&0x80)
SEND_1();
Else
SEND_0();
}
Bit Write_N_Bytes(Uchar *Buffer,Uchar N)Reentrant
{
//向I2C总线写N个字节
Uchar I;
IIC_Start();
For(I=0;I<N;I++)
{
Write_Byte(Buffer[I]);
If(!Check_Acknowledge())
{
IIC_Stop();
Return(I==N);
}
}
IIC_Stop();
Return TRUE;
}
Uchar Read_Byte(Void)Reentrant
{
//从I2C总线读一个字节
Uchar B=0,I;
For(I=0;I<8;I++)
{
SDA=1; //释放总线
SCL=1; //接受数据
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个字节
Uchar I;
IIC_Start();
Write_Byte(SlaveAdr); //向总线发送接收器地址
If(!Check_Acknowledge()) //等待接收器应答信号
Return FALSE;
For(I=0;I<N;I++)
{
Buffer[I]=Read_Byte();
If(I!=N)
SEND_0(); //发送应答
Else
SEND_1(); //发送非应答
}
IIC_Stop();
Return TRUE;
} |
|