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

📄 i2c.c

📁 i2c仿真
💻 C
字号:
#include<at89x51.h>
#include<intrins.h>

#define uint  unsigned int 
#define uchar unsigned char

code uchar SenData[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                      0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10};

sbit SCL=P1^4;
sbit SDA=P1^5;

/***********************************************
**函数名称:DelayNms()
**函数功能:延时N毫秒
**入口参数:n
**出口参数:无
**说明    :无
***********************************************/
void DelayNms(uint n)
{
  uint i,j;
  for(i=0;i<n;i++)
  for(j=0;j<120;j++);
}


/***********************************************
**函数名称:I2C_Start()
**函数功能:发送起始条件
**入口参数:无
**出口参数:无
**说明    :时序按照标准模式建立
***********************************************/
void I2C_Start()
{
  SDA=1; 
  _nop_();//数据建立时间大于250ns
  _nop_();
  _nop_();
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  SDA=0;
  _nop_();
  _nop_();
  SCL=0; //SCL高电平时间大于4us,嵌住时钟总线
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

/***********************************************
**函数名称:I2C_Stop()
**函数功能:发送停止条件
**入口参数:无
**出口参数:无
**说明    :时序按照标准模式建立
***********************************************/
void I2C_Stop()
{
  SDA=0; 
  _nop_();//数据建立时间大于250ns
  _nop_();
  _nop_();
  SCL=1;
  _nop_();
  _nop_();
  _nop_();
  SDA=1;
  _nop_();
  _nop_();
  SCL=0; //SCL高电平时间大于4us,嵌住时钟总线
  _nop_();
  _nop_();
  _nop_();
  _nop_();
  _nop_();
}

/***********************************************
**函数名称:I2C_SendByte()
**函数功能:发送一个字节
**入口参数:待发送字节n
**出口参数:无
**说明    :时序按照标准模式建立
***********************************************/
void I2C_SendByte(uchar n)
{
	 char i;
	 for(i=7;i>=0;i--)
	 {
		  SDA=(n>>i)&0x01;
		  _nop_();
		  _nop_();
		  _nop_();
		  SCL=1;
		  _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
		  SCL=0;
	      _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
	 }
}


/***********************************************
**函数名称:I2C_RecByte()
**函数功能:接收一个字节
**入口参数:无
**出口参数:已接收字节
**说明    :时序按照标准模式建立
***********************************************/
 I2C_RecByte(void)
{
	 char i,j=0;
	 for(i=7;i>=0;i--)
	 {
		  j<<=1;
		  SDA=1;
		  _nop_();
		  _nop_();
		  _nop_();
		  SCL=1;
		  _nop_();
		  _nop_();
		  _nop_();
		  j|=SDA&0x01;
		  _nop_();
		  _nop_();
		  SCL=0;
	      _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
		  _nop_();
	 }
	 return (j);
}



/***********************************************
**函数名称:Check_Ack()
**函数功能:检测从机响应
**入口参数:无
**出口参数:从机响应则为'0',否则为'1'
**说明    :时序按照标准模式建立
***********************************************/
Check_Ack()
{
	uchar i=1;
	SDA=1;
	_nop_();
    _nop_();
	_nop_();
	SCL=1;
	_nop_();
	_nop_();
	_nop_();
	i=SDA;
	_nop_();
	_nop_();
	_nop_();
	SCL=0;
	_nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
	return (i);  
}

/***********************************************
**函数名称:Gen_Ack()
**函数功能:产生应答
**入口参数:i
**出口参数:无
**说明    :i=0产生应答,i=1产生非应答
***********************************************/
Gen_Ack(char i)
{	
	SDA=i;
	_nop_();
    _nop_();
	SCL=1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	SCL=0;
	_nop_();
    _nop_();
	SDA=1;
    _nop_();
    _nop_();
    _nop_();
}

/***********************************************
**函数名称:I2C_SendNByte()
**函数功能:发送N个字节
**入口参数:字节个数n,待发送数据队列首地址
**出口参数:无
**说明    :时序按照标准模式建立
***********************************************/
void I2C_SendNByte(uchar n,uchar *p)
{
  while(n--)
   {
	send:I2C_SendByte(*p);
		 if(Check_Ack()) goto send;
		 p++;
   }
   I2C_Stop();

}

/***********************************************
**函数名称:I2C_RecNByte()
**函数功能:接收N个字节
**入口参数:字节个数n,存放数据队列首地址
**出口参数:无
**说明    :时序按照标准模式建立
***********************************************/
void I2C_RecNByte(char n,uchar *p)
{
  while(n--)
   {
	*p=I2C_RecByte();
	if(n>0)
	    {Gen_Ack(0x00);//产生应答
		p++;
		}
    else
	    {Gen_Ack(0x01);//产生非应答
		 I2C_Stop();
		 }
	}
}



void main(void)
{
 uchar RecData[18]={0x00};
 
/***********************************************/
  start:I2C_Start();
	       I2C_SendByte(0xae);//发送从地址选择24c01

	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start;
	       }
		   I2C_SendByte(0x30);//发送子地址
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start;
	       }
           I2C_SendNByte(17,SenData);//在页写入模式下一次最多写一页,写的数据超过16个将覆盖前面所写的
           DelayNms(1000);//这个延时很有用,去掉试试看
/***********************************************/

/***********************************************/
  start2:I2C_Start();
	       I2C_SendByte(0xac);//发送从地址选择24c02

	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start2;
	       }
		   I2C_SendByte(0x80);//发送子地址
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start2;
	       }
           I2C_SendNByte(17,SenData);//在页写入模式下一次最多写一页,写的数据超过16个将覆盖前面所写的
           DelayNms(1000);//这个延时很有用,去掉试试看
/***********************************************/

/***********************************************/
  start3:I2C_Start();
	       I2C_SendByte(0xa0);//发送从地址,选择24c04,第0页

	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start3;
	       }
		   I2C_SendByte(0x80);//发送子地址
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start3;
	       }
           I2C_SendNByte(17,SenData);//在页写入模式下一次最多写一页,写的数据超过16个将覆盖前面所写的
           DelayNms(1000);//这个延时很有用,去掉试试看
	
  start4:I2C_Start();
	       I2C_SendByte(0xa2);//发送从地址,选择24c04,第1页

	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start4;
	       }
		   I2C_SendByte(0x70);//发送子地址
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start4;
	       }
           I2C_SendNByte(17,SenData);//在页写入模式下一次最多写一页,写的数据超过16个将覆盖前面所写的
           DelayNms(1000);//这个延时很有用,去掉试试看
/***********************************************/


/***********************************************/
 start1:    I2C_Start();
           I2C_SendByte(0xa0);//发送从地址
		   	 if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start1;
	       }
		   I2C_SendByte(0x08);//发送子地址
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start1;
	       }
		   I2C_Start();
		   I2C_SendByte(0xa1);//这一步不要忘记检测应答
	       if(Check_Ack())
	       {
		      I2C_Stop();
		      goto start1;
	       }
		   I2C_RecNByte(18,RecData);
/***********************************************/
}

⌨️ 快捷键说明

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