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

📄 i2c_c51.c

📁 RA8806底层驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************************************
**  		MCS-51系列单片机模拟I2C软件包(V1.2)
** 文件名  :I2C_C51.C
** 相关文件:I2C_C51.H
** 功能说明:本模拟I2C软件包包含了I2C操作的底层函数,如发送数据及接收数据,应答位发送,并提供
             了几个直接面对器件的操作函数,它很方便的与用户程序连接并扩展.....  
** 注    意: 函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改....
             (本软件包是1us机器周期,即晶振频率要小于12MHZ)
** 总线时序符合I2C标准模式,100Kbit/S。
**                                          更新时间:2002.06.05
************************************************************************************************/
#include "INCLUDE.H"

sbit SDA = P0^1;            	    //模拟I2C数据传送位
sbit SCL = P0^0;            	    //模拟I2C时钟控制位

#define   SDA_InPut()    {P0MDOUT &= ~0x02; P0 |= 0x02;}
#define   SDA_OutPut()   {P0MDOUT |= 0x02; }

bit ack;	         	        //应答标志位
   


/*******************************************************************
**                   起动I2C总线函数               
** 函数原型: void  Start_I2c();  
** 功    能: 启动I2C总线,即发送I2C起始条件. 
**                  ________________
      SCL    ....    		 		\	   	0
	                		1	     \___________________
	              _________
	  SDA    ....	1	   \		 0
	                        \____________________________   
**
**----------------------------------------------------------------------------------------------------
** 作 者  : 严俊生
** 日 期  : 2007-07-15
**----------------------------------------------------------------------------------------------------
** 修改人  :
** 日 期  :							
********************************************************************/
static void Start_I2c(void)
{ 
  SDA_OutPut();                     
  SDA = 1; _nop_();	    //发送起始条件的数据信号
  SCL = 1; _nop_();     //起始条件建立时间大于4.7us,延时	
  _nop_(); _nop_();
  _nop_(); _nop_();    
  SDA = 0; _nop_();     //发送起始信号 
  _nop_(); _nop_();     //起始条件锁定时间大于4μs
  _nop_(); _nop_();         
  SCL = 0;              //钳住I2C总线,准备发送或接收数据 
  _nop_(); _nop_();
}

/********************************************************************************************************
**                    结束I2C总线函数               
** 函数原型: void  Stop_I2c();  
** 功    能: 结束I2C总线,即发送I2C结束条件. 
**                     ________________________________
      SCL    ....  0  /				
	              ___/	        	1	    
	              			  _________________________
	  SDA    ....		0	 /
	               _________/				 1
**
**----------------------------------------------------------------------------------------------------
** 作 者  : 严俊生
** 日 期  : 2007-07-15
**----------------------------------------------------------------------------------------------------
** 修改人  :
** 日 期  :							 
********************************************************************************************************/
void Stop_I2c()
{ 
  SDA_OutPut();
  SDA = 0; _nop_();      //发送结束条件的数据信号和发送结束条件的时钟信号
  SCL = 1; _nop_();      //结束条件建立时间大于4μs   
  _nop_(); _nop_();
  _nop_(); _nop_();
  SDA = 1; _nop_();     //发送I2C总线结束信号
  _nop_(); _nop_();
}




/******************************************************************************************************
**                               I2C字节数据发送函数               
** 函数原型: void  SendByte(uchar c);
** 功    能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对此状态位进行操作.(不应答或非应答
**           都使ack=0)。发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
** 入口参数:c 要发送到I2C总线上的数据或者是地址 
**
**----------------------------------------------------------------------------------------------------
** 作 者  : 严俊生
** 日 期  : 2007-07-15
**----------------------------------------------------------------------------------------------------
** 修改人  :
** 日 期  :							 
******************************************************************************************************/
void  SendByte(uchar c)
{  uchar BitCnt; 
   SDA_OutPut(); 
   for(BitCnt=0;BitCnt<8;BitCnt++)    //要传送的数据长度为8位
    {
       if((c<<BitCnt)&0x80) SDA = 1;  //判断发送位 
          else  SDA = 0;                
       _nop_();
       SCL=1;   _nop_();              //置时钟线为高,通知被控器开始接收数据位
       _nop_(); _nop_();              //保证时钟高电平周期大于4μs       
       _nop_(); _nop_();         
       SCL=0; 
     }     
     _nop_();  _nop_();
     SDA = 1;                         //8位发送完后释放数据线,准备接收应答位*/
     _nop_();  _nop_(); 
	 SDA_InPut();  
     SCL = 1;  _nop_();
     _nop_();  _nop_();
     if(SDA == 1)   ack = 0;     
        else ack = 1;                 //判断是否接收到应答信号*/
     SCL = 0;
     _nop_();  _nop_();
}






/******************************************************************************************************
**                 I2C字节数据接收函数               
** 函数原型: uchar  RcvByte();
** 功    能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数应答从机。
** 入口参数:无
** 返回参数:从I2C上接受到的数据 
**
**----------------------------------------------------------------------------------------------------
** 作 者  : 严俊生
** 日 期  : 2007-07-15
**----------------------------------------------------------------------------------------------------
** 修改人  :
** 日 期  :							  
******************************************************************************************************/	
#if IRcvStr_EN 
 uchar  RcvByte(void)
 {uchar retc=0,BitCnt;
  SDA = 1;             		           //置数据线为输入方式
  SDA_InPut();  
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        _nop_();  SCL = 0;             //置时钟线为低,准备接收数据位
        _nop_(); _nop_();              //时钟低电平周期大于4.7μs
        _nop_(); _nop_();
        _nop_();
        SCL = 1;                       //置时钟线为高使数据线上数据有效
        _nop_(); _nop_();
        retc = retc<<1;
        if(SDA == 1)  
		   retc = retc + 1;            //读数据位,接收的数据位放入retc中 
        _nop_(); _nop_(); 
      }
  SCL = 0;    
  _nop_(); _nop_();
  return(retc);
 } 
#endif
/******************************************************************************************************
**                     I2C应答子函数
** 函数原型:  void Ack_I2c(bit a);
** 功    能:  主控器进行应答信号(可以是应答或非应答信号,由位参数a决定)	
**
**----------------------------------------------------------------------------------------------------
** 作 者  : 严俊生
** 日 期  : 2007-07-15
**----------------------------------------------------------------------------------------------------
** 修改人  :
** 日 期  :					
******************************************************************************************************/
#if IRcvStr_EN 
 void Ack_I2c(bit a)
 {
    SDA_OutPut(); 
    if(a == 0)  SDA = 0;         //在此发出应答或非应答信号 
      else SDA = 1;
    _nop_(); 
    _nop_(); _nop_();      
    SCL = 1; _nop_();	 
    _nop_(); _nop_();            //时钟低电平周期大于4μs
    _nop_(); _nop_();	    
    SCL = 0;                     //清时钟线,钳住I2C总线以便继续接收
    _nop_(); _nop_();    
 }
#endif
/******************************************************************************************************
**
**                           I2C用户对外接口函数                                   
**
******************************************************************************************************/

			 /**=================== 以下为IIC写程序 ======================**/
																							  
/******************************************************************************************************
**                 向无子地址器件发送字节数据函数               
** 函数原型: bit  ISendByte(uchar sla,ucahr c);  
** 功    能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.如果返回1表示操作成功,否则
             操作有误。
** 入口参数:sla 器件从地址
             c   需要向器件中发送的字节数据
** 返回参数:操作成功与否标志
** 注意:    使用前必须已结束总线。

⌨️ 快捷键说明

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