iic.c

来自「基于STC12C5410AD单片机的IIC总线读写C语言程序」· C语言 代码 · 共 297 行

C
297
字号
/********************************************************
*	文件名称:
*               IIC.c
*       文件说明:
*		使用口线模拟IIC
*********************************************************/                                                    
/****************声明引用的外部变量***********************/
extern unsigned char  Intake_Grade;         //进风等级
extern unsigned char  Exhaust_Grade;        //出风等级
extern unsigned char  Tempture_Targ;        //目标温度
extern unsigned char  Humidity_Targ;        //目标湿度
/*********************************************************
*	数据定义
*********************************************************/
bit bdata ack;

unsigned char SlvAdr;          //被控器地址
unsigned char SubAdr;          //被控器单元地址
unsigned char ByteCnt;         //待发送字节数
unsigned char addr_Buf;        //高地址缓冲
unsigned char Ack_Flag;        //应答标识

unsigned char eep_rcvbuf[EEP_DATBUF];   //定义接收数据缓冲
unsigned char eep_sndbuf[EEP_DATBUF];   //定义发送数据缓冲

/*端口定义*/
sbit SDA = P1^5;         //模拟数据传送位
sbit SCL = P1^6;         //模拟时钟控制位
sbit WP  = P1^7;          //芯片写保护控制位	

/*********************************************************
*	启动IIC
*********************************************************/
void start_iic(void)
{
   WP = 0;		 //取消芯片写保护
   _Nop();
   _Nop();	
   _Nop();
   _Nop();
   SDA = 1;      //发送起始条件的数据信号
   _Nop();
   SCL = 1;
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   SDA = 0;
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   SCL = 0;
   _Nop();
   _Nop();
}

/*********************************************************
*	结束IIC
*********************************************************/
void stop_iic(void)
{
   SDA = 0;
   _Nop();
   SCL = 1;
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   SDA = 1;
   _Nop();
   _Nop();
   _Nop();
   _Nop();
   //WP = 1;		//芯片写保护
}

/**********************************************
名称:void SendByte(unsigned c)
描述:字节数据传送函数
功能:将数据c发送出去,可以是地址也可以是数据,发送完毕等待应答
	  发送数据正常ack=1, ack=0表示被控器无应答或损坏
***********************************************/
void SendByte(unsigned char c)
{
   uchar bitcnt;
   uchar tmp=0x80;
   for(bitcnt=0;bitcnt<8;bitcnt++)
   	   {
         if(c&tmp)SDA = 1;
	        else SDA = 0;
         _Nop();
         SCL = 1;
         _Nop();
         _Nop();
         _Nop();
         _Nop();
         _Nop();
         SCL = 0;
		 tmp = tmp>>1;
	   }
	_Nop();
    _Nop();
	SDA = 1;   //8位发送完毕后释放数据线,准备接收应答位
	_Nop();
    _Nop();
    SCL = 1;
	_Nop();
    _Nop();
	_Nop();
	if(SDA == 1)ack = 0;     //判断是否接收到应答信号
	  else 	
	  {ack = 1;//Flash_InSetFlag = 1;	
	   }
	SCL = 0;
	_Nop();
	_Nop();
}

/***************************************
名称:RcvByte()
描述:字节数据传送函数
功能:用来接受从器件传来的数据,并判断总线错误
******************************************/
unsigned char RcvByte()
{
   uchar retc;
   uchar bitcnt;

   retc = 0;
   SDA = 1;			//置数据线为输入方式
   for(bitcnt=0;bitcnt<8;bitcnt++)
        {
		   _Nop();
		   SCL = 1;		//置时钟线为高使数据线上数据有效
		   _Nop();
		   _Nop();
		   _Nop();
		   _Nop();
		   retc = retc<<1;
		   if(SDA==1)retc = retc+1;
		   _Nop();
		   _Nop();
		   SCL = 0;		//置时钟线为低准备接收数据
		   _Nop();
		   _Nop();
		   _Nop();		//时钟低电平周期大于4.7μs
		   _Nop();								
		}
	SCL = 0;
   _Nop();
   _Nop();
   return(retc);
}
/****************************************
名称:Ack_iic(bit a)
描述:应答子程序
功能:主控器进行应答信号(可以是应答或非应答信号)
*****************************************/
void Ack_iic(bit a)
{
  	if(a==0)SDA = 0;	   //在此发出应答或非应答信号
	     else SDA = 1;
	_Nop();
    _Nop();
	_Nop();
	SCL = 1;
	_Nop();
    _Nop();
	_Nop();
	_Nop();
	_Nop();
   SCL = 0;
   _Nop();
   _Nop();
}

/*****************************************
名称:ISendByte
描述:向无子地址器件发送字节数据函数
功能:从启动总线到发送地址,数据,总线结束的全过程,

bit ISendByte(uchar sla,uchar c)
{
   start_iic();		      //启动总线
   SendByte(sla);
     if(ack==0)return(0);	  //发送器件地址
   SendByte(c);
     if(ack==0)return(0);	  //发送数据
   stop_iic();
   return(1);
}
*****************************************/
/************************************************
名称:ISendStr
描述:向有子地址器件发送多字节数据
功能:
入口参数:sla 器件地址,suba  子地址,s 指向发送的内容,num 发送的字节数
出口参数:1表示操作成功,否则操作有误
************************************************/
bit ISendStr(uchar sla, uchar suba, uchar *s, uchar num)
{
   	 uchar i;
	 
	 start_iic();		   //启动总线
	 SendByte(sla);		   //发送器件地址
	   if(ack==0){return(0);}
	 SendByte(suba);	   //发送器件子地址
	   if(ack==0){return(0);}
	 for(i=0;i<num;i++)
		 {
		    SendByte(*s);
			   if(ack==0) {return(0);}
			s++;
		 }
	 stop_iic();
	 return(1);
}

/***********************************************
名称:IRcvByte(unsigned char sla,unsigned char *c)
描述:向无子地址器件读字节数据函数
说明:从启动总线到发送地址,读数据,结束总线的全过程,从器件地址sla
      返回值在c.如果返回1表示成功,否则操作有误

bit IRcvByte(unsigned char sla,unsigned char *c)
{
   start_iic();	  //启动总线
   SendByte(sla+1);	
	 if(ack==0)return(0);
   *c = RcvByte();
      Ack_iic(1);
   stop_iic();
   return(1);
}
***********************************************/
/***********************************************
名称:IRcvByte(unsigned char sla,unsigned char *c)
描述:向有子地址器件读取多字节数据函数
说明:从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件地址sla
      子地址suba,读出的内容放入s指向的存储区.读num个字节,如果返回1表示成功,否则操作有误
***********************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar num)
{
   uchar i;
   start_iic();		//启动总线
   SendByte(sla);		//发送器件地址和写命令
	 if(ack==0)return(0);
   SendByte(suba);		//写子地址
	 if(ack==0)return(0);
   start_iic();			  //启动总线
   SendByte(sla+1);		  //发送器件地址和读命令
	 if(ack==0){return(0);Flash_InSetFlag = 1;}
   for(i=0;i<num-1;i++)
      {
	     s[i]=RcvByte();
		   Ack_iic(0);
	  }
   s[i]=RcvByte();	   //接受最后一个字节后发送非应答信号
     Ack_iic(1);
   stop_iic();
   return(1);
}


void ReadSysPara(void)		 //读取系统参数
{
   IRcvStr(at24c02,0x00,eep_rcvbuf,4);
   Intake_Grade = eep_rcvbuf[0];
   Exhaust_Grade = eep_rcvbuf[1];
   Tempture_Targ = eep_rcvbuf[2];
   Humidity_Targ = eep_rcvbuf[3];

}




















⌨️ 快捷键说明

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