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

📄 iic.h

📁 电磁波产生控制原理
💻 H
字号:
#ifndef _IIC_H_
#define _IIC_H_
              
#include <reg52.h>
#include <intrins.h>

#define  uchar unsigned char 
#define  uint  unsigned int

#define  _Nop()  _nop_()	//定义空指令

sbit SDA=P1^5;				//模拟I2C数据传送位
sbit SCL=P1^4;            	//模拟I2C时钟控制位

bit ack;	         		//应答标志位

void Start_I2c();			//I2C起始信号
void Stop_I2c();			//I2C停止信号
void SendByte(uchar c);		//写1个字节
uchar RcvByte();			//读1个字节
void Ack_I2c(bit a);		//发送应答信号
							//写I2C地址
bit ISendStr(uchar sla,uchar high,uchar suba,uchar s);
							//读I2C地址
unsigned char IRcvStr(uchar sla,uchar high,uchar suba);
   
#endif


void Start_I2c() 			//I2C起始信号
{
  	SDA=1;					//发送起始条件的数据信号
  	_Nop();
  	SCL=1;
  	_Nop();    				//起始条件建立时间大于4.7us,延时
  	_Nop();
  	_Nop();
  	_Nop();
  	_Nop();    
  	SDA=0;   				//发送起始信号
  	_Nop();    				//起始条件锁定时间大于4μs
  	_Nop();
  	_Nop();
  	_Nop();
  	_Nop();       
  	SCL=0;   				//钳住I2C总线,准备发送或接收数据 
  	_Nop();
  	_Nop();
}

void Stop_I2c() 			//I2C停止信号
{
  	SDA=0;  				//发送结束条件的数据信号
  	_Nop();   				//发送结束条件的时钟信号
  	SCL=1;  				//结束条件建立时间大于4μs
  	_Nop();
  	_Nop();
  	_Nop();
  	_Nop();
  	_Nop();
  	SDA=1;  				//发送I2C总线结束信号
  	_Nop();
  	_Nop();
  	_Nop();
  	_Nop();
}

void SendByte(uchar c)		//写1个字节
{
 	uchar BitCnt;
 	SCL=0;
 	for(BitCnt=0;BitCnt<8;BitCnt++)
    {
	 	SCL=0;
	 	_Nop();
     	if(c&0x80)SDA=1;	//判断发送位
       	else  SDA=0;                
     	_Nop();
	 	_Nop();
	 	_Nop();
     	SCL=1;				//置时钟线为高,通知被控器开始接收数据位
     	_Nop(); 
     	_Nop();          	//保证时钟高电平周期大于4μs
     	_Nop();
     	_Nop();
     	_Nop();         
     	SCL=0; 
	 	c=c<<1;
    }
    SDA=1;               	//8位发送完后释放数据线,准备接收应答位
    _Nop();
    _Nop();   
    SCL=1;
    _Nop();
    _Nop();
    _Nop();
    if(SDA==1)ack=0;     
       else ack=1;        	//判断是否接收到应答信号
    SCL=0;
    _Nop();
    _Nop();
}
	
uchar RcvByte() 			//读1个字节
{
  	uchar retc;
  	uchar BitCnt;
  
  	retc=0; 
  	SDA=1;             		//置数据线为输入方式
  	_Nop();
  	_Nop();
  	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中
	  	SCL=0;
      	_Nop();
      	_Nop(); 
	}
	SCL=0;    
	_Nop();
	_Nop();
	return(retc);
}

void Ack_I2c(bit a) 		//发送应答信号
{ 
 	if(a==0) SDA=0;     	//在此发出应答或非应答信号 
    else SDA=1;
  	_Nop();
  	_Nop();
  	_Nop();      
  	SCL=1;
    _Nop();
    _Nop();             	//时钟低电平周期大于4μs
    _Nop();
    _Nop();
    _Nop();  
 	SCL=0;                	//清时钟线,钳住I2C总线以便继续接收
    _Nop();
    _Nop();    
}

/*******************************************************************
                    向有子地址器件发送多字节数据函数               
函数原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
功能:     从启动总线到发送地址,子地址,结束数据,总线的全过程,从器件
          地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit ISendStr(uchar sla,uchar high,uchar suba,uchar s)
{
   Start_I2c();               //启动总线
   SendByte(sla);             //发送器件地址
     if(ack==0)return(0);
   SendByte(high);            //发送器件子地址
     if(ack==0)return(0);
   SendByte(suba);            //发送器件子地址
     if(ack==0)return(0);

   SendByte(s);               //发送数据
     if(ack==0)return(0);

   Stop_I2c();                //结束总线
   return(1);
}


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

  Start_I2c();				 //启动总线
  SendByte(sla);             //发送器件地址
    if(ack==0)return(0);
  SendByte(high);            //发送器件子地址
    if(ack==0)return(0);
  SendByte(suba);            //发送器件子地址
    if(ack==0)return(0);

  Start_I2c();
  SendByte(sla+1);
    if(ack==0)return(0);

  d=RcvByte();               //发送数据
  Ack_I2c(1);                //发送就答位 
    
  Stop_I2c();                //结束总线 
  return(d);
}

                        /*/    完毕      /*/

⌨️ 快捷键说明

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