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

📄 i2c_div.c

📁 税控收款机源码:拼音输入法,LCD,VFD驱动,IC卡驱动,税控国标
💻 C
字号:
#include  "include.h"

//#define EEpromallbyte  32
#define  GCALL		0x80       // Gen. Call flag
#define  STOP		0x40       // Stop cond. flag
#define  INTR		0x20       // Interrupt cond flag
#define  TX_MODE	0x10       // I2C Tx mode flag
#define  BBUSY		0x08       // Bus Busy flag
#define  BLOST		0x04       // Bus Lost flag
#define  _ACKREP	0x02       // ACK response flag
#define  SLV		0x01       // Slave Mode flag

// S2CON Equates:
#define  CR2		0x80		// 
#define  ENI		0x40		// 
#define  STA		0x20		// 
#define  STO		0x10		// 
#define  ADDR		0x08		// 
#define  AA			0x04		// 
#define  CR1		0x02		// 
#define  CR0		0x01		//

//extern uchar time_mode_buf;
//extern uchar prt_mode;
//extern uchar write_data_flg;
 bit	I2C_Busy;
 bit	I2C_NoAck;
 bit	I2C_Lost;
 bit	I2C_Fault;
 //int  data  *Ptr;
 char idata *IBuffer;
 char xdata *XBuffer;
 char data I2C_SendLen;
 char data I2C_RcvLen;
 bit  First,Area;
 bit  I2C_master, I2C_xmit;
sbit PWROFF=P3^2;
//uchar read_eeprom(uint addr,uchar length,void *eprom_buf);
//extern void delayms(uint t1);
//extern void send_str(uint length,uchar xdata *buffer);       
//extern void send_char(uchar ch);
//extern uchar Write_FAU_data(uchar type,uchar result);                    

//extern void delay_ms(uchar ms);
//extern uchar testbuf[64];
//-------------------------------------------------- 
//	I2C Initialization Routine
//--------------------------------------------------
void I2C_Init(bit Mode)  //0,收。1,发   
{
    if(low_pwr)shut_bat(0);
  	P3SFS |= 0xC0;						// Enable P3.7 for SCL, P3.6 for SDA
	IEA	  |= 0x02;						// set EI2C I2C Int. Enable bit

	I2C_master = 1;
	I2C_xmit  = !Mode;	

	I2C_Busy  = 1;
	I2C_NoAck = 0;
	I2C_Fault = 0;  

}	


/*================================================*/      
BOOL I2C_Send(char SLAVE,bit type,int addr,char I2C_Num)
{
    
  	I2C_Init(0);
	if ((P3 & 0xc0) != 0xc0)
	{
		I2C_Fault = 1;
		return FALSE;
	}
		
	Area = type;
	IBuffer = addr;
	XBuffer = addr;
	I2C_SendLen=I2C_Num;	

	if (I2C_SendLen == 0) 
		return TRUE;

	I2C_SendLen--;

	S2DAT =SLAVE;

	S2CON = 0xe1;

	while(I2C_Busy);
	return TRUE;
   /*
	I2C_Init(0);
	if ((P3 & 0xc0) != 0xc0)
	{
      
		I2C_Fault = 1;
		return FALSE;

	}
		
	Area = type;
	//IBuffer = addr;
	XBuffer = addr;
	I2C_SendLen=I2C_Num;	

	if (I2C_SendLen == 0) 
		return TRUE;

	I2C_SendLen--;
       
	S2DAT =SLAVE;             //写SLAVE 0XA0 地址 启动中断
	S2CON = 0xe2;             //开启I2C模式置中断标志
	Area = type;
    //if((low_pwr)&&(SLAVE==0x64))return(POWER_OFF);
    while(I2C_Busy);
	 return TRUE;

//	while(I2C_Busy);
	//return TRUE;
 */
}

/*================================================*/      
BOOL I2C_Rcv(char SLAVE,bit type,int addr, char I2C_Num)
{
  	I2C_Init(1);

	if ((P3 & 0xc0) != 0xc0)
	{
		I2C_Fault = 1;
		return FALSE;
	}

	Area = type;
	IBuffer = addr;
	XBuffer = addr;
	I2C_RcvLen = I2C_Num;

	if (I2C_RcvLen == 0) 
		return TRUE;
	I2C_RcvLen--;

	First = 0;
		
        S2DAT = SLAVE | 0x01;
	S2CON = 0xe1;

	while(I2C_Busy);
	return TRUE; 
 /* I2C_Init(1);

	if ((P3 & 0xc0) != 0xc0)
	{
      
		I2C_Fault = 1;
		return FALSE;

	}

	Area = type;
	//IBuffer = addr;
	XBuffer = addr;
	I2C_RcvLen = I2C_Num;

	if (I2C_RcvLen == 0) 
		return TRUE;
	I2C_RcvLen--;
	First = 0;
	S2DAT = SLAVE | 0x01;
	S2CON = 0xe2;        //开启I2C模式置中断标志
   
	while(I2C_Busy);
	             
	return TRUE;
  */
}

/*================================================*/      
void I2C_Send_data(void)
 {
   	S2CON &= ~STA;	
  	if (I2C_SendLen == 0x00)
	{
		if ((S2CON & 0x10) != 0) 
			I2C_Busy=0;

		if (!Area)
		{
			S2DAT = *IBuffer;
		}
		else 
		{
			S2DAT = *XBuffer;
		}
		S2CON |= STO;
	}	
	else 
	{
		I2C_SendLen--;
		if (!Area)
		{
			S2DAT = *IBuffer;
			IBuffer++;
		}
		else 
		{
			S2DAT = *XBuffer;
			XBuffer++;
		}
	}	
  /* S2CON &= ~STA;	  //~0x20
  	if (I2C_SendLen == 0x00)
	{
		if ((S2CON & 0x10) != 0) 
			I2C_Busy=0;
//		I2C_SendLen--;
		/*if (!Area)
		{
			S2DAT = *IBuffer;
		}
		else 
		{
			S2DAT = *XBuffer;
			
		//}
		S2CON |= STO;
	}	
	else 
	{
		I2C_SendLen--;
		
		/*if (!Area)
		{
			S2DAT = *IBuffer;
			IBuffer++;
		}
		else 
		{
			S2DAT = *XBuffer;
           	XBuffer++;
			
			
		//}
	}
 */		
}    
/*================================================*/      
I2C_Rcv_data(void)
{
  if (!First)
	{
		First = 1;	
		S2CON &= ~STA;
		S2DAT = 0xff;
		S2CON |= AA;
	}
	else if (I2C_RcvLen == 0x00)
	{	
	
		
		if (!Area)
		{
			*IBuffer =  S2DAT;
		}
		else
		{
			*XBuffer =  S2DAT;
		}
	//	if ((S2CON & 0x10) != 0)
			I2C_Busy=0;
		    S2CON |= STO;

	}
	else 
	{ 
		I2C_RcvLen--;
		if (I2C_RcvLen == 0x00)
		{
			S2CON &= ~AA;
			S2CON |= STO;
		}
         
		if (!Area)
		{
			*IBuffer =  S2DAT;
			IBuffer++;
		}
		else
		{
			*XBuffer =  S2DAT;
			XBuffer++;
		}
	}
	
/*if (!First)
	{
		First = 1;	
		S2CON &= ~STA;
		S2DAT = 0xff;
		S2CON |= AA;
	}
else if (I2C_RcvLen == 0x00)
	{	
	
		
		/*if (!Area)
		{
			*IBuffer =  S2DAT;
		}
		else
		{
			*XBuffer =  S2DAT;
		//}
	//	if ((S2CON & 0x10) != 0)
			I2C_Busy=0;
		    S2CON |= STO;

	}
else 
	{ 
		I2C_RcvLen--;
		if (I2C_RcvLen == 0x00)
		{
			S2CON &= ~AA;
			S2CON |= STO;
		}
         
		/*if (!Area)
		{
			*IBuffer =  S2DAT;
			IBuffer++;
		}
		else
		{
			*XBuffer =  S2DAT;
			XBuffer++;
		//}
	}
 */	
}
//===================================================================================
/*******************************************************
 函数名称:initial_time                                                        
 函数描述:初始化时钟                                                        
 输入参数:              
 输出参数:
 返回值:                                     
 *******************************************************/
/*uchar initial_time(void)
{
  uchar I2C_SendBuffer[4];	
  I2C_SendBuffer[0] = 0x70; // addr
  I2C_SendBuffer[1] = 0x00;//set offset
	if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,2))
   return (1); 
  I2C_SendBuffer[0] = 0xe0; // addr
  I2C_SendBuffer[1] = 0x20;//set control1
  I2C_SendBuffer[2] = 0x20;//set control2
	if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,3)) 
   return (1);
 else
   return (0);  
}
*/
/*******************************************************
 函数名称:set_rtc                                                        
 函数描述:设置时钟                                                        
 输入参数:buf[0]-buf[6]=年、月、日、时、分、秒,格式为BCD码              
 输出参数:
 返回值:设置正确返回0,否则返回1                                        
 *******************************************************/
uchar set_rtc(uchar *rtc_buf)
{
	uchar I2C_SendBuffer[8];	
	I2C_SendBuffer[0] = 0x00; // addr
	I2C_SendBuffer[1] = rtc_buf[5];//秒
	I2C_SendBuffer[2] = rtc_buf[4]; //分
	I2C_SendBuffer[3] = rtc_buf[3]; //时
	I2C_SendBuffer[4] = rtc_buf[6]; //星期
	if(I2C_SendBuffer[4]>6)I2C_SendBuffer[4]=0;
	I2C_SendBuffer[5] = rtc_buf[2]; //日
	I2C_SendBuffer[6] = rtc_buf[1]; //月
	I2C_SendBuffer[7] = rtc_buf[0];//年
	//write_data_flg=1;
	//send_str(8,I2C_SendBuffer);
	if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,8)) 
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		//write_data_flg=0;
		return (1);
	}
	else    
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		return (0);
	}
}
//=======================================================
/*******************************************************
 函数名称:Writ_ctr_rtc                                                        
 函数描述:写时钟的设置数据                                                        
 输入参数:地址:rtc_add,数据:rtc_data              
 输出参数:
 返回值:设置正确返回0,否则返回1                                        
 *******************************************************/
uchar Writ_ctr_rtc(uchar rtc_add,uchar rtc_data)
{
	uchar I2C_SendBuffer[2];	
	I2C_SendBuffer[0] = rtc_add; // addr
	 I2C_SendBuffer[1] = rtc_data;//数据
	//write_data_flg=1;
	if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,2))
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		// write_data_flg=0;
		return (1);
	} 
	else   
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		//write_data_flg=0;
		return (0);
	}
}
/*******************************************************
 函数名称:read_rtc                                                        
 函数描述:读时钟                                                          
 输入参数:无                                                              
 输出参数:buf[0]-buf[5]=年、月、日、时、分、秒,格式为BCD码                                        
 返回值:   设置正确返回0,否则返回1              
 ******************************************************/
uchar read_rtc(uchar *rtc_buf)
{
	uchar I2C_SendBuffer[2];
	uchar I2C_RcvBuffer[8];
   
	I2C_SendBuffer[0] = 0x00;     	// ST85 secs=00	
	//if(low_pwr) return(POWER_OFF);
	//write_data_flg=1;
	if(!I2C_Send(0x64,1,(int)&I2C_SendBuffer,1)) 
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		//write_data_flg=0;
		return (1);
	}
	if(!I2C_Rcv(0x64,1,(int)&I2C_RcvBuffer,8))
	{
		IEA&= 0xfd;
		P3SFS&= 0x3f;
		S2CON&= 0xbf;
		//write_data_flg=0;
		return (1);
	}
	else  
	{
		rtc_buf[0]=I2C_RcvBuffer[7];   //年
		rtc_buf[1]=I2C_RcvBuffer[6];   //月
		rtc_buf[2]=I2C_RcvBuffer[5];   //日
		rtc_buf[3]=I2C_RcvBuffer[3];   //时
		//if(!time_mode_buf)rtc_buf[3]&=0xdf;//12小时制
		rtc_buf[4]=I2C_RcvBuffer[2];   //分
		rtc_buf[5]=I2C_RcvBuffer[1];  //秒
		rtc_buf[6]=I2C_RcvBuffer[4];
		if(rtc_buf[6]>6)rtc_buf[6]=0;
	}
	IEA&= 0xfd;  
	P3SFS&= 0x3f;
	S2CON&= 0xbf;
	//write_data_flg=0;
	return (0);
}
 
//======================================================================================
#define MAXLEN 32//24c64 为32 24C256为64
uchar write_eeprom(uint addr,uchar length,void *buf)
{  
   uchar I2C_SendBuffer[34];
   uchar temp_len;
   uint addrtemp;
   uchar len,j,i;

  
   if(length<255)
   {
    //write_data_flg=1;
     len=(MAXLEN-(uchar)(addr%MAXLEN));
	 j=1;
	//temp_len=(length>(MAXLEN-(uchar)(addr%MAXLEN)))?(MAXLEN-(uchar)(addr%MAXLEN)):length;//防止跨页
	 addrtemp=addr;
     temp_len=len;
	 if(length>temp_len)
	  {
       if((length-len)%MAXLEN)j+=((length-len)/MAXLEN)+1;
	   else          j+=((length-len)/MAXLEN);
	  }
	 else temp_len=length;
	 i=0;
	 //offset=0;
	 while(i<j)
	  {
      
      I2C_SendBuffer[0] = addrtemp/256; //高位地址
      I2C_SendBuffer[1] = addrtemp%256;//低位地址
	 
      memcpy(&I2C_SendBuffer[2],((uchar*)buf),temp_len);
	  if(!PWROFF)shut_bat(0);
	  if(!I2C_Send(0xa0,1,(int)&I2C_SendBuffer,temp_len+2))
       {
	   IEA&= 0xfd;
	   P3SFS&= 0x3f;
	   S2CON&= 0xbf;
	   return (1);
	   }
	  if((j==1)||(i==j))break; //写完退出
	  delayms(50) ;
	  addrtemp+=temp_len;
	  
      ((uchar*)buf)+=temp_len;
	  i++;
	  if(i!=j-1)temp_len=MAXLEN;
	  else      temp_len=length-len-MAXLEN*(i-1);
      
	 }
     //write_data_flg=0;
	 delayms(50) ;
	 IEA&= 0xfd;
     P3SFS&= 0x3f;						// disable P3.7 for SCL, P3.6 for SDA
	 S2CON&= 0xbf;                     //关I2C模式
    return 0;
	
   }
 
 else  return 1;
}


/**********************************
函数功能:向EPROM发读数据命令
函数参数:addr为起始地址,length为读取数据的长度,读出的数据存放在ack_data指向的单元
返回值:  0:正确		否则错误		
**********************************/
uchar read_eeprom(uint addr,uchar length,void *eprom_buf)
{
   uchar I2C_SendBuffer[2];
   
   I2C_SendBuffer[0] = addr/256; /*高位地址*/
   I2C_SendBuffer[1] = addr%256;/*低位地址*/
   //write_data_flg=1;
  if(!I2C_Send(0xa0,1,(int)&I2C_SendBuffer,2))        
   {
   IEA&= 0xfd;
   P3SFS&= 0x3f;
   S2CON&= 0xbf; 
  //write_data_flg=0;
   return 1;
   }
  if(!I2C_Rcv(0xa0,1,(int)((uchar*)eprom_buf),length))
   {
   IEA&= 0xfd;
   P3SFS&= 0x3f;
   S2CON&= 0xbf; 
   //write_data_flg=0;
   return 1;
   }
  else                       
   {   
    delayms(50) ;
    IEA&= 0xfd;
	P3SFS&= 0x3f;
	S2CON&= 0xbf;
	//write_data_flg=0;
	return 0;
	}
}

//===================================================================
/*uchar read_eepromZIKU(ulong addr,uchar length,uchar  *eprom_buf)
{
   uchar I2C_SendBuffer[2],i;
   
    if(addr>=0x18000)
   { 
    for(i=0;i<length;i++){eprom_buf[i]=xiao[i];}                     
    return (1);
    }          
   I2C_SendBuffer[0] = addr/256; /*高位地址
   I2C_SendBuffer[1] = addr%256;/*低位地址
   if(!I2C_Send(0xa2,1,(int)&I2C_SendBuffer,2))return (1);
   if(!I2C_Rcv(0xa2,1,(int)eprom_buf,length))  return (1);
   else                                        return (0);
}
*/

⌨️ 快捷键说明

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