采用C51编写,程序通过测试,现已成功用于项目中.适用于所有的51内核单片机,可以移植到别的单片机上,修改很少,我已经移植到430单片机上.
声明:本代码为个人原创,若要转载请注明出处!
sbit bI2C_SDA = P0^4; // SDA
sbit bI2C_SCL = P1^0; // SCL
#define T1 5
#define T2 10
#define T3 15
#define T5 25
//----------------------------------------------------------------------------
void I2CInit (void)
{
bI2C_SCL = 0;
I2CDelay(T2);
bI2C_SDA = 1;
I2CDelay(T2);
bI2C_SCL = 1;
I2CDelay(T2);
bI2C_SCL = 0;
I2CDelay(T2);
bI2C_SDA = 0;
I2CDelay(T2);
bI2C_SCL = 1;
I2CDelay(T2);
bI2C_SCL = 0;
I2CDelay(T2);
I2CStop();
}
//----------------------------------------------------------------------------
//名称:I2CDelay
//功能:I2C中的延时
//入口:无
//出口:无
//----------------------------------------------------------------------------
void I2CDelay ( uint i )
{
while(i)
{
i--;
}
}
void msDelay (uint ms)
{
while(ms)
{
I2CDelay(9000);
ms--;
}
}
//----------------------------------------------------------------------------
//名称:I2CStart
//功能:I2C的启动
//入口:无
//出口:无
//----------------------------------------------------------------------------
void I2CStart (void)
{
bI2C_SDA = 1;
I2CDelay(T2);
bI2C_SCL = 1;
I2CDelay(T2);
bI2C_SDA = 0;
I2CDelay(T2);
bI2C_SCL = 0;
I2CDelay(T2);
}
//----------------------------------------------------------------------------
//名称:I2CStop
//功能:I2C的停止
//入口:无
//出口:无
//----------------------------------------------------------------------------
void I2CStop (void)
{
bI2C_SDA = 0;
I2CDelay(T2);
bI2C_SCL = 1;
I2CDelay(T2);
bI2C_SDA = 1;
I2CDelay(T2);
bI2C_SCL = 0;
I2CDelay(T2);
}
//----------------------------------------------------------------------------
//名称:SendACK
//功能:主机给出ACK信号
//入口:无
//出口:出
//----------------------------------------------------------------------------
void SendACK ( void )
{
bI2C_SDA = 0;
I2CDelay(T3);
bI2C_SCL = 1;
I2CDelay(T3);
bI2C_SCL = 0;
I2CDelay(T3);
}
//----------------------------------------------------------------------------
//名称:SendNoACK
//功能:主机不给出ACK信号,而将SDA拉高
//入口:无
//出口:出
//----------------------------------------------------------------------------
void SendNoACK ( void )
{
bI2C_SCL = 0;
I2CDelay(T3);
bI2C_SDA = 1;
I2CDelay(T3);
bI2C_SCL = 1;
I2CDelay(T3);
bI2C_SCL = 0;
}
//----------------------------------------------------------------------------
//名称:WaitACK
//功能:等待接收ACK信号
//入口:无
//出口:返回值为0,代表接收失败;返回值为1,代表接收成功
//----------------------------------------------------------------------------
/*
void WaitACK ( void )
{
bI2C_SDA = 1;
I2CDelay();
I2CDelay();
bI2C_SCL = 1;
I2CDelay();
I2CDelay();
bI2C_SCL = 0;
I2CDelay();
I2CDelay();
}
*/
//----------------------------------------------------------------------------
//名称:I2CWrByte
//功能:主机发送一个字节的数据
//入口:ucSendData,要发送的数据
//中间寄存器:ACC
//出口:无
//----------------------------------------------------------------------------
void I2CWrByte ( uchar ucSendData )
{
uchar i = 8;
while ( i-- )
{
bI2C_SCL = 0;
I2CDelay(T1);
bI2C_SDA = (ucSendData&0x80);
ucSendData <<= 1;
I2CDelay(T1);
bI2C_SCL = 1;
I2CDelay(T1);
}
bI2C_SCL = 0;
I2CDelay(T2);
bI2C_SCL = 1;
I2CDelay(T2);
bI2C_SCL = 0;
}
//----------------------------------------------------------------------------
//名称:I2CRdByte
//功能:主机从I2C总线上接收一个字节的数据
//入口:无
//中间寄存器:ACC
//出口:ucReceiveData,接收到的数据
//----------------------------------------------------------------------------
uchar I2CRdByte ( void )
{
uchar i = 8;
uchar ucRecivData = 0;
bI2C_SCL = 0;
I2CDelay(T2);
bI2C_SDA = 1;
while(i--)
{
ucRecivData <<= 1;
bI2C_SCL = 1;
I2CDelay(T3);
if(bI2C_SDA)
ucRecivData = 0x01;
else
ucRecivData &= 0xFE;
bI2C_SCL = 0;
I2CDelay(T3);
}
return ucRecivData;
}
//----------------------------------------------------------------------------
//名称:EnableWrite1226
//功能:向X1226的状态寄存器写初始置,以允许对其他寄存器写
//入口:无
//出口:无
//----------------------------------------------------------------------------
void EnableRTC ( bit bFlag )
{
I2CStart();
I2CWrByte(0xde);
I2CDelay(T2);
I2CWrByte(0x00);
I2CDelay(T2);
I2CWrByte(0x3f);
I2CDelay(T2);
I2CWrByte(0x02);
I2CDelay(T2);
I2CStop();
if(bFlag==1)
{
I2CStart();
I2CWrByte(0xde);
I2CDelay(T2);
I2CWrByte(0x00);
I2CDelay(T2);
I2CWrByte(0x3f);
I2CDelay(T2);
I2CWrByte(0x06);
I2CDelay(T2);
I2CStop();
}
}
//----------------------------------------------------------------------------
//名称:DisableWrite1226
//功能:将X1226的状态寄存器清零,以禁止对其他寄存器写
//入口:无
//出口:无
//----------------------------------------------------------------------------
void DisableWrite1226 ( void )
{
I2CStart();
I2CWrByte(0xde);
I2CDelay(T2);
I2CWrByte(0x00);
I2CDelay(T2);
I2CWrByte(0x3f);
I2CDelay(T2);
I2CWrByte(0x00);
I2CDelay(T2);
I2CStop();
}
//----------------------------------------------------------------------------
// 读E2PROM
//E2PAddr---要访问的首地址
//ByteNum---要读取的字节个数
//pFistData--从E2PROM主读出的数据在内存中存放的首地址
//----------------------------------------------------------------------------
void RdE2p (uint E2PAddr,uchar ByteNum,uchar *pFistData)
{
uchar i;
// EnableRTC ( 0 );
I2CStart();
I2CWrByte(0xae);
I2CDelay(T2);
I2CWrByte((uchar)(E2PAddr>>8));
I2CDelay(T2);
I2CWrByte((uchar)E2PAddr);
I2CStart();
I2CWrByte(0xaf);
I2CDelay(T2);
for( i=0;i
{
*pFistData = I2CRdByte();
pFistData++;
if( i+1
SendACK();
}
SendNoACK();
I2CStop();
}
//----------------------------------------------------------------------------
// 写E2PROM
//E2PAddr---要访问的首地址
//ByteNum---要写入的字节个数
//pFistData--从写入的数据在内存中存放的首地址
//----------------------------------------------------------------------------
void WrE2p (uint E2PAddr,uchar ByteNum,uchar *pFistData)
{
uchar i;
EnableRTC ( 1 );
I2CStart();
I2CWrByte(0xae);
I2CDelay(T5);
I2CWrByte((uchar)(E2PAddr>>8));
I2CDelay(T5);
I2CWrByte((uchar)E2PAddr);
I2CDelay(T5);
for( i=0;i
{
I2CWrByte(*pFistData++);
}
I2CStop();
}
//----------------------------------------------------------------------------
|