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

C51单片机模拟I2C总线驱动程序设计(2)

发布时间:2020-06-08 发布时间:
|
/************************************ I2C_RcvB ******************************** 
函数名:uchar I2C_RcvB() 
入口: 
出口:uchar 型数据 
功能描述: 
接收从器件传来的数据,并判断总线错误(不发应答信号),收完后需要调用应答函数。 
调用函数: 
全局变量: 
******************************************************************************* 
uchar I2C_RcvB() 
     uchar retc; 
     uchar BitCnt; //位 
     retc = 0; 
     SDA = 1; //置数据总线为输入方式,作为接收方要释放 SDA. 
     for(BitCnt=0;BitCnt<8;BitCnt++) 
     
          _nop_(); 
          SCL = 0; //置时钟线为低准备接收数据位 
          SomeNOP();  //时钟低电平周期大于 4.7us 
          SCL = 1; //置时钟线为高使数据有效 
          _nop_(); 
          _nop_(); 
          retc = retc<<1; 
          if(SDA==1) 
          { 
               retc = retc + 1;//读数据位,接收的数据放入 retc 中 
          } 
          _nop_(); 
          _nop_(); 
     
     SCL = 0; 
     _nop_(); 
     _nop_(); 
 
     return(retc); 
 
/************************************ I2C_Ackn ******************************** 
函数名:void I2C_Ackn(bit a) 
入口:0 或 1 
出口: 
功能描述:主控制器进行应答信号(可以是应答或非应答信号) 
说明:作为接收方的时候,必须根据当前自己的状态向发送器反馈应答信号
调用函数: 
全局变量: 
******************************************************************************* 
void I2C_Ackn(bit a) 
     if(a==0) //在此发送应答或非应答信号 
     
          SDA = 0; 
     
     else 
     
          SDA = 1; 
     
     SomeNOP(); 
     SCL = 1; 
     SomeNOP();  //时钟电平周期大于 4 us 
     SCL = 0; //清时钟线钳住 I2C 总线以便继续接收 
     _nop_(); 
     _nop_(); 
 
/******************************** I2C_ISendB ********************************** 
函数名:bit I2C_ISendB(uchar sla, uchar suba,uchar c) 
入口:从器件地址 sla,子地址 suba, 发送字节 c 
出口:0(操作有误),1(操作成功) 
功能描述:从启动总线到发送地址、数据,结束总线的全过程, 
     如果返回1:表示操作成功,否则操作有误。 
调用函数:I2C_Start(),I2C_SendB(uchar c),I2C_Stop() 
全局变量:I2C_Ack 
******************************************************************************* 
bit I2C_ISendB(uchar sla, uchar suba, uchar c) 
     I2C_Start(); //启动总线 
     I2C_SendB(sla); //发送器件地址 
     if(!I2C_Ack) 
     
          return(0); 
     
     I2C_SendB(suba); //发送器件子地址 
     if(!I2C_Ack) 
     
          return(0); 
     
     I2C_SendB(c); //发送数据 
     if(!I2C_Ack) 
     
          return(0); 
     
     I2C_Stop(); //结束总线 
     return(1); 
 
/********************************** I2C_IRcvB ********************************* 
函数名:bit I2C_IRcvB(uchar sla, uchar suba, uchar *c) 
入口:从器件地址 sla, 子地址 suba, 收到的数据在 c 
出口:1(操作成功),0(操作有误) 
功能描述:从启动总线到发送地址、读数据,结束总线的全过程。 
调用函数: 
I2CS_tart(), 
I2C_SendB(uchar c), 
I2C_RcvB(), 
I2C_Ackn(bit a), 
I2C_Stop() 
全局变量:I2C_Ack 
******************************************************************************* 
bit I2C_IRcvB(uchar sla, uchar suba, uchar *c) 
     I2C_Start(); //启动总线 
     I2C_SendB(sla); 
     if(!I2C_Ack) 
     
          return(0); 
     
     I2C_SendB(suba); //发送器件子地址 
     if(!I2C_Ack) 
     
          return(0); 
     
     I2C_Start(); //重复起始条件 
     I2C_SendB(sla+1); //发送读操作的地址 
     if(!I2C_Ack) 
     
          return(0); 
     
     *c = I2C_RcvB(); //读取数据 
     I2C_Ackn(1); //发送非应答位 
     I2C_Stop(); //结束总线 
 
     return(1); 



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

热门文章 更多
单片机的抗干扰措施有哪些