|
采用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<ByteNum;i++) { *pFistData = I2CRdByte(); pFistData++; if( i+1<ByteNum ) 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<ByteNum;i++ ) { I2CWrByte(*pFistData++); } I2CStop(); } //----------------------------------------------------------------------------
|