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

📄 i2c.c

📁 遥控器编码的c51程序,包括遥控器编码,I2C操作编程等
💻 C
字号:
/********************************************************************************************
  通过I2C总线对EEPROM读写操作源程序。
********************************************************************************************/
#include <I2C.h> 

void SETSDA(uchar port)
{
 	if(port==I2C0) I2C0SDA=1;
	if(port==I2C1) I2C1SDA=1;
}

void CLRSDA(uchar port)
{
 	if(port==I2C0) I2C0SDA=0;
	if(port==I2C1) I2C1SDA=0;
}

void SETSCL(uchar port)
{
 	if(port==I2C0) I2C0SCL=1;
	if(port==I2C1) I2C1SCL=1;
}

void CLRSCL(uchar port)
{
 	if(port==I2C0) I2C0SCL=0;
	if(port==I2C1) I2C1SCL=0;
}
/*******************************************************************************************
                    启动I2C总线.
*******************************************************************************************/
void Start_I2c(uchar port)
{
    setSCL;
	   setSDA;
  	 delay(0);
  	 clrSDA;
   	delay(0);     
}

/*******************************************************************************************
                    结束I2C总线
********************************************************************************************/
void Stop_I2c(uchar port)
{
   setSCL;
	  clrSDA;	
  	delay(0);
  	setSDA;
  	delay(0);
}

/*******************************************************************
                发送一个字节
********************************************************************/
bit SendByte(uchar c, uchar port)
{
 	uchar BitCnt;
 	bit ack;
 
 	for(BitCnt=0;BitCnt<8;BitCnt++)   /*数据长度为8位*/
    {
     	clrSCL;
		    if((c<<BitCnt)&0x80) setSDA;  /*设置数据位*/
     	else  clrSDA;               
	     delay(0);
     	setSCL;                   /*置时线为高电平,通知接收方读数据*/
     delay(0);   
    }

   clrSCL;
   setSDA;	                         /*8位数据发送完毕,释放数据线,准备接收应答。*/
   delay(0);
   setSCL;	
	if(port==I2C0)
	{
    	if(I2C0SDA==1) ack=0;     /*检查是否收到了确认信号。ack==0,不确认*/
    	else ack=1;                /* ack==1,确认。*/
	}
	if(port==I2C1)
	{
    	if(I2C1SDA==1) ack=0;      /*检查是否收到了确认信号。ack==0,不确认*/
    	else ack=1;                 /*ack==1,确认。*/
	}
	delay(0);
    clrSCL;
	clrSDA;	
	delay(0);
	if(ack==1) return(1);             /*如果成功写入了数据,返回1*/
	else return(0);
}

/*******************************************************************
                 读一个字节,读完数据要应答
********************************************************************/	
uchar RcvByte(uchar port)
{
  	uchar retc;
  	uchar BitCnt;
  
  	retc=0; 
  	for(BitCnt=0;BitCnt<8;BitCnt++)
  	{
  		clrSCL;       /*准备接收数据*/
	  	setSDA;	      /*把数据线输出寄存器设为1,为输入数据作准备。*/
		  delay(0);
        setSCL;       /*置时钟线为高是平,使数据线上的数据有效*/
     	retc=retc<<1;
		  if(port==I2C0)
		  {
       	if(I2C0SDA==1)retc=retc+1;     /*读数据位 */
		   }
	  	if(port==I2C1)
		  {
     	if(I2C1SDA==1)retc=retc+1;      /*读数据位*/
		  }
 		 delay(0);
  	}
  	return(retc);                        /*返回收到的数据*/
}

/********************************************************************
                     应答函数
********************************************************************/
void Ack_I2c(bit a, uchar port)
{
  	clrSCL;
  	if(a==0)clrSDA;     /*确认信号*/
  	else setSDA;        /*不确认*/	
  	delay(0);    
  	setSCL;
  	delay(0);
}

/********************************************************************************************
                     多字节数据写函数               
功能: 通过"port"总线,向器件地址为"sla"的E2PROM从子地址"suba"开始写入"no"个数据,要发送的数据在指钟"s"所指向的地址中。返回值为1表示操作成功。
********************************************************************************************/
bit WriteStr(uchar sla,uchar suba,uchar *s,uchar no, uchar port)
{
   	uchar i;

   	Start_I2c(port);                             /*I2C Start*/
   	if(SendByte(sla, port)==0) return(0);            /*发送器件地址*/
   	if(SendByte(suba, port)==0) return(0);          /*发送子地址*/

   	for(i=0;i<no;i++)
   	{   
     	if(SendByte(*s, port)==0) return(0);          /*发送数据*/
     	s++;
   	} 
   	Stop_I2c(port);                            /*I2C Stop*/ 
   	return(1);
}

/********************************************************************************************
                    多字节数据读函数             
功能: 通过"port"总线,从器件地址为"sla"的E2PROM的子地址"suba"开始读取"no"个数据,读取的数据放在指钟"s"所指向的地址中。返回值为1表示操作成功。
********************************************************************************************/
bit ReadStr(uchar sla,uchar suba,uchar *s,uchar no, uchar port)
{
   	uchar i;

   	Start_I2c(port);                             /*I2C Start*/
   	if(SendByte(sla, port)==0) return(0);            /*发送器件地址*/
   	if(SendByte(suba,port)==0) return(0);           /*发送子地址*/

   	Start_I2c(port);                             /*ReStart*/
   	if(SendByte(sla+1, port)==0) return(0);

   	for(i=0;i<no-1;i++)
   	{   
     	*s=RcvByte(port);               /*接收最后一位数据*/
     	Ack_I2c(0, port);                /*发送应答位*/  
     	s++;
   	} 
   	*s=RcvByte(port);                /*接收最后一位数据*/
   	Ack_I2c(1, port);                 /*发送应答位*/
   	Stop_I2c(port);                   /*结束总线*/ 
   	return(1);
}

/********************************************************************************************
              延时函数,没有返回值。             
********************************************************************************************/
void delay(int us)
{
	int i;
	for(i=0;i<us;i++) _Nop();
}

bit Wait(uchar sla, uchar port)
{
	int i;
	bit ack;

	i=0;
	do
	{
		Start_I2c(port);
		i++;
		if(i>30000) return(0);	      /*如果等待时间超过30ms,结束等待,以免死循环*/
		ack=SendByte(sla, port);    /*发送器件地址*/
	} while(!ack);
	Start_I2c(port);
	Stop_I2c(port);
	return(1);
}

⌨️ 快捷键说明

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