⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csmii2c.cpp

📁 24LC256完整的读完程序(长期产品中应用)
💻 CPP
字号:
#include "class.h"
/****************************************Copyright (c)**************************************************
**                                      终端产品
**             
**--------------文件信息--------------------------------------------------------------------------------
**文   件   名: CSMII2C.cpp
**创   建   人: 杨虎岳
**最后修改日期: 2006年6月7日
**描        述: 模拟II2C总线
**说    明:             
**--------------历史版本信息----------------------------------------------------------------------------
** 创建人: 杨虎岳
** 版  本: v1.0
** 日 期: 2006年6月7日
** 描 述: 原始版本
**
**--------------当前版本修订------------------------------------------------------------------------------
**创 建  人: 杨虎岳
**日     期: 2006年3月4日
** 描 述: 
**
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
CFGPIO_OUT SCL(I2C_SCL,0);
CFGPIO_OUT WP(I2C_WP,1);
CFGPIO_OUT SDA(I2C_SDA,1);
   
 //写EEPROM需要5MS的延时,写一页和一个字节 的时间是一样的。
/*void CSMII2C::Delay_EEProm_5ms()
{
  INT32U  i;
  for(i=0;i<150000;i++);
   
 }
void CSMII2C:: Delay5us(void)
{
  INT8U i;
  for(i=0;i<0xff;i++);

}*/

void  CSMII2C::WaitRcv(void)
{
  
 CFGPIO_IN SDA(I2C_SDA);
}
void  CSMII2C::WaitSend(void)
{
 CFGPIO_OUT SDA(I2C_SDA,1);

}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                     起动总线函数               
//函数原型: void    I2c_Start();  
//功能:       启动I2C总线,即发送I2C起始条件.
 
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void  CSMII2C::I2cStart()
{
  WaitSend();
  SDA.set();   //发送起始条件的数据信号 
  SCL.set();
  Xus(5);   //起始条件建立时间大于4.7us,延时
  SDA.clr();   //发送起始信号//
  Xus(5);     // 起始条件锁定时间大于4μs 
  SCL.clr();   ///钳住I2C总线,准备发送或接收数据 
  Xus(5);
  WaitRcv();
}


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                      结束总线函数               
//函数原型: void   I2c_Stop();  
//功能:       结束I2C总线,即发送I2C结束条件.
  
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void  CSMII2C::I2cStop()
{
  WaitSend();
  SDA.clr();  //发送结束条件的数据信号
 
  SCL.set();//结束条件建立时间大于4μs
  Xus(5);
  SDA.set();  //发送I2C总线结束信号
  WaitRcv(); 
  //SCL.clr();
}

/*INT8U CSMII2C:: CheckAck(void)
 { 
   INT8U ack;
   SDA.set(); //释放数据线,准备接收应答位,调试时可以在SDA=1和SCL=1之间加延时
   SCL.set();
   Xus(5);//时钟低电平周期大于4μs
   ack=SDA.value();
   Xus(5);
   SCL.clr();//清时钟线,钳住I2C总线以便继续接收
   Xus(5);
   if(ack==1)
     return FALSE;
   return TRUE;
 }
*/


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                 字节数据传送函数               
//函数原型: void  SendByte(INT8U c);
////功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
//     此状态位进行操作.(不应答或非应答都使ack=0 假)     
//     发送数据正常,ack=1; ack=0表示被控器无应答或损坏。

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
INT8U  CSMII2C::I2cSendByte(INT8U data)
{
 INT8U BitCnt;
 WaitSend(); 
 
  for(BitCnt=0;BitCnt<8;BitCnt++)  //要传送的数据长度为8位//
    { 
     if((data<<BitCnt)&0x80)
     {
      SDA.set();
      SDA.set();//防止线路延时
      }   //判断发送位//
       else 
       {
         SDA.clr();
         SDA.clr();                
        }
     SCL.set();               //置时钟线为高,通知被控器开始接收数据位//
     Xus(5);    //保证时钟高电平周期大于4μs//
     SCL.clr();
     Xus(5);
    }

    //SDA.set();
    WaitRcv();              //8位发送完后释放数据线,准备接收应答位//
    SCL.set();
    Xus(5);
    BitCnt=SDA.out_value();
    
    SCL.clr();
    Xus(5);
    if(BitCnt)  return(FALSE);     
       else     return(TRUE);        //判断是否接收到应答信号//
    
    
}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                 字节数据传送函数               
//函数原型: INT8U  I2c_RcvByte();
//功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
//     发完后请用应答函数。  

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&	
 INT8U  CSMII2C:: I2cRcvByte()
{
  INT8U retc=0;
  INT8U BitCnt;
  //SDA.set();             //置数据线为输入方式,因为默认是输入,所以不用变
 //WaitRcv();
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {           
        SCL.clr();     //置时钟线为低,准备接收数据位
        Xus(5);//时钟低电平周期大于4.7μs
        SCL.set();     //置时钟线为高使数据线上数据有效
        Xus(5); //时钟低电平周期大于4.7μs
        retc=retc<<1;
        if(SDA.out_value()==1)   retc=retc|0x01; //读数据位,接收的数据位放入retc中
      }
    
   SCL.clr(); 
   Xus(5);
    //WaitSend(); 
  return(retc);
}

void  CSMII2C::WriteEnable(void)
{
 WP.clr();

}

 void CSMII2C::WriteDisable(void)
{
 WP.set();

}

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                     应答子函数
//原型:  void I2c_Ack(bit a);
 
//功能:主控器进行应答信号,(可以是应答或非应答信号)

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void  CSMII2C::I2cAck(INT8U Ack)
{
   WaitSend();
  if(Ack==0)SDA.clr();     //在此发出应答或非应答信号 
        else SDA.set();
    Xus(5);          //时钟低电平周期大于4μs
    SCL.set();
    Xus(5);             //时钟低电平周期大于4μs  
   
    SCL.clr(); 
    Xus(5);               //清时钟线,钳住I2C总线以便继续接收 
     WaitRcv();//一定要在SCL为低时变为输入方式,如果在高时变为输入,则成了停止位
}





/*
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                    向无子地址器件发送字节数据函数               
//函数原型: bit  ISendByte(INT8U sla,ucahr c);  
//功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
//           如果返回1表示操作成功,否则操作有误。
//注意:    使用前必须已结束总线。

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
INT8U  CSMII2C::ISendByte(INT8U sla,INT16U addr,INT8U c)
{  
   INT8U ack;
   INT8U temp;
   I2cStart();               //启动总线//
    WP.clr();
   ack=I2cSendByte(sla); 
    if(ack==FALSE) return(FALSE);
   ack=I2cSendByte(0x00); 
    if(ack==FALSE)  return(FALSE);
   ack=I2cSendByte(addr);               //发送数据//
     if(ack==FALSE) return(FALSE);
    I2cSendByte(c);               //发送数据//
    I2cStop();                 //结束总线// 
    Delay_EEProm_5ms();
    WP.set();
    return(TRUE);
}  




//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//                    向有子地址器件发送多字节数据函数               
//函数原型: bit  ISendStr(INT8U sla,INT8U suba,ucahr /s,INT8U no);  
//功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
//          地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
//           如果返回1表示操作成功,否则操作有误。
//注意:    使用前必须已结束总线。
///如果《32字节,最好从页的起始地址开始,如果》32字节,必须,从页的中间开始差+32 
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
INT8U  CSMII2C::ISendStr(INT8U sla,INT16U suba,INT8U *s,INT8U no)
{
   INT8U i;
    WP.clr();
    I2cStart();              //启动总线
   ack=I2cSendByte(sla);            ///发送器件地址
     if(ack==FALSE)  return(FALSE);
   ack=I2cSendByte(FALSE); 
    if(ack==FALSE)  return(FALSE);
   ack=I2cSendByte(suba);            //发送器件子地址
     if(ack==FALSE)  return(FALSE);

   for(i=0;i<no;i++)
    {   
     ack=I2cSendByte(*s);               //发送数据
       if(ack==FALSE) return(FALSE);
     s++;
    } 
    I2cStop();                 //结束总线
    Delay_EEProm_5ms();
    WP.set();
    return(TRUE);
}






//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
 //                   向无子地址器件读字节数据函数               
//函数原型: bit  II2c_RcvByte(INT8U sla,ucahr /c);  
//功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
//          址sla,返回值在c.
//           如果返回1表示操作成功,否则操作有误。
//注意:    使用前必须已结束总线。

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
INT8U  CSMII2C:: IRcvByte(INT8U sla,INT16U addr,INT8U *outdata)
{
    INT8U ack;
  I2cStart();              //启动总线//
  ack=I2cSendByte(sla&0xfe);            //发送器件地址//
     if(ack==FALSE)return(FALSE);
   ack=I2cSendByte(0x00); 
    if(ack==FALSE)  return(FALSE);
   ack=I2cSendByte(addr);
    I2cStart();
   ack=I2cSendByte(sla);
     if(ack==FALSE) return(FALSE);
   *outdata=I2cRcvByte();               //读取数据//
    I2cAck(1);               //发送非就答位//
   I2cStop();                  //结束总线// 
  return(1);
}




//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
 //                   向有子地址器件读取多字节数据函数               
//函数原型: bit  ISendStr(INT8U sla,INT8U suba,ucahr /s,INT8U no);  
//功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
//          地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
 //          如果返回1表示操作成功,否则操作有误。
//注意:    使用前必须已结束总线。

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
INT8U  CSMII2C::IRcvStr(INT8U sla,INT16U suba,INT8U *s,INT8U no)
{
   INT8U i;
   INT8U ack;
   I2cStart();               //启动总线//
   ack=I2cSendByte(sla&0xfe);            //发送器件地址//
   if(ack==0)return(0);
   ack= I2cSendByte(0x00); 
   ack=I2cSendByte(suba);            //发送器件子地址//
   if(ack==0)return(0);
   I2cStart();
   ack=I2cSendByte(sla);
   if(ack==0)return(0);

   for(i=0;i<no-1;i++)
    {   
     *s=I2cRcvByte();               //发送数据//
     I2cAck(0);                //发送就答位//  
     s++;
    } 
  *s=I2cRcvByte();
   I2cAck(1);                 //发送非应位//
  I2cStop();                    //结束总线// 
  return(1);
}


*/

 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -