×
单片机 > 单片机程序设计 > 详情

软件模拟I2C读写X1226程序

发布时间:2020-08-26 发布时间:
|

采用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();
}
//----------------------------------------------------------------------------

 
关键字:软件模拟  I2C  读写X1226程序 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
如何为单片机选择合适的负载电容