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

📄 i2c.c

📁 51的IIC源码,修改一下就可以用了! 51的IIC源码,修改一下就可以用了!
💻 C
字号:
#include <reg52.h>
#include <stdio.h>
#include "I2C.h"
#include "Uart.h"
#include "Reg.h"
#include "debug.h"


#define DELAY_TIME 2
#define TryTimes 5

/************* Wait ************/
void Wait(uchar t)
{ 
  while(t!=0) 
   {
     t--; 
   }
}
/**************启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变
********************************************************************/
void IIC_Start(void) 
{  
   SCL = 1;  //SDA=1;SCL=1; 
   SDA = 1;
   Wait(DELAY_TIME); 
   SDA=0;      
   Wait(DELAY_TIME);
   SCL=0; 
   Wait(DELAY_TIME); 
}
/**************终止I2C总线,当SCL为高电平时使SDA产生一个正跳变 
*************************************************************/
void IIC_Stop(void) 
{
   SDA=0;
   Wait(DELAY_TIME);
   SCL = 1;
   Wait(8);
   SDA=1; 
} 
/************发送0,在SCL为高电平时使SDA信号为低*************/ 
void SEND_0(void) 
{
   SDA=0;
   Wait(DELAY_TIME);
   SCL=1;
   Wait(DELAY_TIME);
   SCL=0; 
   Wait(DELAY_TIME);  
}
/************发送1,在SCL为高电平时使SDA信号为高*************/ 
void SEND_1(void) 
{ 
   SDA=1;
   Wait(DELAY_TIME); 
   SCL=1; 
   Wait(DELAY_TIME);
   SCL = 0; 
   Wait(DELAY_TIME); 
}
/**************发送完一个字节后检验设备的应答信号************/
bit Check_Ack(void) 
{
   bit F0;
   SCL = 1;
   Wait(DELAY_TIME);  
   F0 = SDA;          //读入SDA的值
   Wait(DELAY_TIME); 
   SCL = 0; 

   Wait(DELAY_TIME); 
   if( F0==1 ) 
    { 
       SCL=1;
	   IIC_Stop();  	    
	   return FALSE; 
	}
   return TRUE;    
}
/**************向IIC总线写一个字节************/
void Write_Byte(uchar b)
{ 
   uchar i; 
   for(i=0;i<8;i++) 
     {
	    if((b<<i)&0x80) 
		SEND_1(); 
		else SEND_0();
		Wait(4); 
	 }
}
/**************向I2C总线写n个字节 page write 模式************/
bit Write_N_Bytes(uchar slave,uchar dataAddr,uchar *buffer,uchar n)
{  
   uchar i; 
   uchar ucCount; 
   for(ucCount=0; ucCount<TryTimes; ucCount++)
     {
	   IIC_Start(); 
	   Write_Byte(slave);
	   if(!Check_Ack()) 
	    {
			IIC_Stop();
		    #ifdef _DEBUG_ON_
             printf("I2C write slave NoAck!"); 
            #endif
		    continue;
		} 
	
	   Write_Byte(dataAddr);
	   if(!Check_Ack()) 
	    {
			IIC_Stop(); 
		    #ifdef _DEBUG_ON_
             printf("I2C write addr NoAck!"); 
            #endif			              			 
			continue;
		}
	
	   for(i=0;i<n;i++) 
	     { 
		     Write_Byte(buffer[i]); 
	         Wait(4);
			 if(!Check_Ack()) 
			    {
					IIC_Stop();               			 
					continue;
				}
	     } 
		IIC_Stop();
		Wait(100); 
		return TRUE;
	 } 
	#ifdef _DEBUG_ON_
	printf("I2C write N Bytes is wrong!"); 
	#endif
	return FALSE;
} 
/**************从I2C总线读一个字节************/
uchar Read_Byte(void)
{  
   uchar b=0;
   uchar i;
   bit F0; 
   for(i=0;i<8;i++) 
     { 
	   SDA=1;
	   SCL=1; 
	   Wait(4); 
	   		    
	   F0 = SDA; 
	   Wait(4);
	   SCL=0;
	   if(F0==1) 
	     { 
		    b=b<<1;   //左移一位
			b=b|0x01; //SDA为1,则低位为1
		 } 
	   else b=b<<1; 
	 } 
   return b; 
}
/**************从I2C总线读n个字节 随机读取方式************/
bit Read_N_Bytes(uchar slave,uchar dataAddr,uchar *buffer,uchar n) 
{  
   uchar i,ucCount; 
   for(ucCount=0; ucCount<TryTimes; ucCount++)
     {
	   IIC_Start(); 
	   Write_Byte(slave);
	   if(!Check_Ack()) 
	    {
			IIC_Stop();
		    #ifdef _DEBUG_ON_
             printf("I2C read slave NoAck!"); 
            #endif
		    continue;
		} 
		
		Write_Byte(dataAddr); //向eeprom发数据addr
		if(!Check_Ack())      //等待接收器应答信号
			{ 
			  IIC_Stop();
			    #ifdef _DEBUG_ON_
	             printf("I2C read addr NoAck!"); 
	            #endif
			  continue; 
			}
		
		IIC_Start();
		slave = slave|0x01;
		Write_Byte(slave); //向总线发送接收器地址 
		if(!Check_Ack())      //等待接收器应答信号
			{ 
			  IIC_Stop();
			    #ifdef _DEBUG_ON_
	             printf("I2C read slave NoAck!"); 
	            #endif
			  continue;//printf("IIC read SlaveAdr2 is wrong!");
			} 
		
		for(i=0;i<n;i++) 
		  { 
		     buffer[i]=Read_Byte(); 
			 if(i!=n-1) //最后一个数据是n-1,而不是n
			   {  
			      SEND_0(); //发送应答
			   } 
			 else 
			   {
			      SEND_1();     //发送非应答 
			   }
		     Wait(4);
		  } 

		IIC_Stop();	
		return TRUE;
	 } 
	#ifdef _DEBUG_ON_
	printf("I2C read is wrong!"); 
	#endif
	return FALSE;
} 

/**************从I2C总线读n个字节 随机读取方式************/
bit Read_Char(uchar SlaveAdr,uchar dataAddr,uchar *Data) 
{  
   uchar ucCount; 
   for(ucCount=0; ucCount<TryTimes; ucCount++)
     {

	   IIC_Start(); 
	   Write_Byte(SlaveAdr);
	   if(!Check_Ack())      //等待接收器应答信号
		{ 
		  IIC_Stop();
		  	#ifdef _DEBUG_ON_
             printf("I2C read slave NoAck!"); 
            #endif
		  continue;	   		   
		} 
		
		Write_Byte(dataAddr); //向eeprom发数据addr
		if(!Check_Ack())      //等待接收器应答信号
			{ 
			  IIC_Stop();
			  	#ifdef _DEBUG_ON_
	             printf("I2C read addr NoAck!"); 
	            #endif
			  continue; 
			}
		
		IIC_Start();
		SlaveAdr = SlaveAdr|0x01;
		Write_Byte(SlaveAdr); //向总线发送接收器地址 
		if(!Check_Ack())      //等待接收器应答信号
			{ 
			  IIC_Stop();
			  continue;
			} 
		
		Data[0] = Read_Byte();
        SEND_1(); //发送应答
		Wait(4);

		IIC_Stop();
		return TRUE;
	 } 
	#ifdef _DEBUG_ON_
	printf("I2C read is wrong!"); 
	#endif
	return FALSE;
} 
 
/*****************************/
bit Write_int(uchar slave,uchar dataAddr,uint Data)
{  
   uchar ucCount; 
   for(ucCount=0; ucCount<TryTimes; ucCount++)
     { 
		IIC_Start(); 
		Write_Byte(slave);
		if(!Check_Ack()) 
		    {
				IIC_Stop();               			 
				continue;
			} 
		
		Write_Byte(dataAddr);
		if(!Check_Ack()) 
		    {
				IIC_Stop();
				continue; 
			}
	
		
		Write_Byte(Data/256); 
		Wait(4);
		if(!Check_Ack()) 
			{
				IIC_Stop();
				continue; 
			} 
		Write_Byte(Data%256); 
		Wait(4);
		if(!Check_Ack()) 
			{
				IIC_Stop();
				continue; 
			}
		 		    
		IIC_Stop(); 
		Wait(4); //启动内部写电路  

		return TRUE; 
	 }

	#ifdef _DEBUG_ON_
	printf("I2C Int write is wrong!"); 
	#endif	   	
	return FALSE; 
}
/*****************************/
bit Write_char(uchar slave,uchar dataAddr,uchar Data)
{  
   uchar ucCount; 
   for(ucCount=0; ucCount<TryTimes; ucCount++)
     {
		IIC_Start(); 
		Write_Byte(slave);
		if(!Check_Ack()) 
			{
				IIC_Stop();
				continue; 
			} 
		
		Write_Byte(dataAddr);
		if(!Check_Ack()) 
			{
				IIC_Stop();
				continue; 
			}
			
			
		Write_Byte(Data); 
		Wait(4);
		if(!Check_Ack()) 
			{
				IIC_Stop();
				continue; 
			} 
			
		Wait(4);
		
		IIC_Stop();
		Wait(4); //启动内部写电路  
		
		return TRUE; 
	 }

	#ifdef _DEBUG_ON_
	printf("I2C Char write is wrong!"); 
	#endif	   	
	return FALSE; 
}					 


/******************************
* 0对应的EEPROM slave地址 0--7*
******************************/
unsigned char E2PROM_Bank(unsigned char n)
{
	return( 0xa8+n*2 );
}

⌨️ 快捷键说明

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