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

📄 general.c

📁 江苏单相复费率电能表方案
💻 C
字号:
#include <Reg931.h>
#include <General.h>

#define GENERATE_STOP        0x54      // 置位 STO, 复位 STA 、 SI 
#define RELEASE_BUS_ACK      0x44      // 复位 STO,STA,SI 并置位 AA (ack)
#define RELEASE_BUS_NOACK    0x40      // 复位 STO,STA,SI 并置位 AA (noack)
#define RELEASE_BUS_STA      0x64      // 起动总线/重新起动总线, 置位 STA

bit AckBus(void);
bit GetBus(void);  
bit SendByte(uchar value);


//**********************************************************
//                  总线响应
//功能:
//入口参数:无
//**********************************************************
bit AckBus(void)
{
	uchar TimeOut;

	TimeOut = 0xFF;
	
	while(SI==0)
	{	 
	 	TimeOut--; 
		if( TimeOut==0x00 )	//100uS无响应,超时退出
		{
			I2CON = GENERATE_STOP;
			return(0);
		}
	}

	return(1);
}





//**********************************************************
//                  总线申请
//功能:进行I2C总线的初始化:包括时钟选择,I2C使能,发送起始信号等等。
//                      I2EN为1,设置为主机;
//                      CRSEL位为0,使用内部SCL发生器。
//入口参数:无
//**********************************************************
bit GetBus(void)       
{	
                                       	// CCLK为7.3728MHz,参数0x14 实际总线频率为 92KHz
    I2SCLH = 0x14;		       			// 设置SCL高电平的PCLK周期数
    I2SCLL = 0x14;                      // 设置SCL低电平的PCLK周期数
    I2CON  = RELEASE_BUS_STA;           // 申请成为主机,起动总线。使用内部SCL发生器,I2EN和AA置位  	
//  while( SI==0 );                     // 等待起始位的发送
	return(AckBus());
}



//**********************************************************
//                    发送数据函数
// 功能:    用于向总线发送数据 
// 入口参数:value 待发送的数据                   
//**********************************************************
bit SendByte(uchar value)
{ 
    I2DAT = value;
    I2CON = RELEASE_BUS_ACK;    	  	// 清除SI位等等   
//  while( SI==0 );        	            // 等待数据的发送 
	return(AckBus());
}




//**********************************************************
//                    向有子地址器件发送多字节数据函数                 
//功能:    从启动总线到发送地址,子地址,数据,结束总线的全过程。
//入口参数;AddrPtr	  	地址指针
//         	DataPrt    	数据指针
//         	Ptr_length	数据长度
// 出口参数:返回1表示操作成功,否则操作有误。
//**********************************************************
bit ISendStr(uchar idata *AddrPtr,uchar idata *DataPrt,uchar idata *Ptr_length)
{ 
  	uchar i;
  	uchar Addr_len;
  	uchar Data_len;
    
  	Addr_len = *Ptr_length;						//地址长度	
  	Ptr_length++;								//数据长度
  	Data_len = *Ptr_length;

  	if(GetBus()==0)				return(0); 		//启动总线
  
  	if(SendByte(*AddrPtr)==0)	return(0);     	//发送器件地址

  	if( I2STAT!=0x18 )
  	{ 
  		I2CON = GENERATE_STOP;
    	return(0);
  	} 

  	for(i=1;i<Addr_len;i++)
  	{
    	AddrPtr++; 

    	if(SendByte(*AddrPtr)==0)return(0); 	//发送器件子地址
    	
		if( I2STAT!=0x28 )
    	{	 
        	I2CON = GENERATE_STOP;
        	return(0);
    	} 
  	}   
     
  	for(i=0; i<Data_len; i++)
  	{ 
    	if(SendByte(*DataPrt)==0)return(0);		//发送数据 
   
    	if( I2STAT!=0x28 )
    	{
      		I2CON = GENERATE_STOP;
      		return(0);
    	}    	
    	DataPrt++;
  	} 

  	I2CON = GENERATE_STOP;            			//结束总线  
	return(1);
}




//**********************************************************
//                    向有子地址器件读取多字节数据函数                
//功能:    从启动总线到发送地址,子地址,读数据,结束总线的全过程。
//入口参数; AddrPtr	  	地址指针
//         DataPrt    	数据指针
//         Ptr_length	数据长度
//出口参数: 函数返回1表示操作成功,否则操作有误。
//**********************************************************
bit IRcvStr(uchar idata *AddrPtr,uchar idata *DataPrt,uchar idata *Ptr_length)
{ 
    uchar i;
    uchar Addr_len;
    uchar Data_len;
    uchar read;
  
    read     = *AddrPtr+1;             			//取从器件地址  
    Addr_len = *Ptr_length;
    Ptr_length++;
    Data_len = *Ptr_length;  
  
    if(GetBus()==0)				return(0);		// 启动总线
    
  	if(SendByte(*AddrPtr)==0)	return(0);     	//发送器件地址
  	
	if( I2STAT!=0x18 )
  	{ 
  		I2CON = GENERATE_STOP;
    	return(0);
  	}
 
  	for(i=1;i<Addr_len;i++)            			//发送器件子地址
  	{
    	AddrPtr++; 

    	if(SendByte(*AddrPtr)==0)return(0);           

    	if( I2STAT!=0x28 )
    	{ 
        	I2CON = GENERATE_STOP;
        	return(0);
    	} 
  	}
  	
  	I2CON = RELEASE_BUS_STA;           			//重新启动总线 
//	while( SI==0 );
  	if(AckBus()==0)				return(0);

	if(SendByte(read)==0)		return(0);  

  	if( I2STAT!=0x40 )
  	{ 
    	I2CON = GENERATE_STOP;
    	return(0);
  	} 
   
  
  	for(i=0; i<Data_len-1; i++)
  	{ 
    	I2CON = RELEASE_BUS_ACK;       //接收一字节数据并发送应答位
//    	while( SI==0 );                //等待接收数据
		if(AckBus()==0)	return(0);
    	
    	if( I2STAT!=0x50 )
    	{ 
      		I2CON = GENERATE_STOP;
      		return(0);
    	}
    
    	*DataPrt = I2DAT;              //读取数据
    	DataPrt++;
  	} 
  
  	I2CON = RELEASE_BUS_NOACK;         //接收最后一字节数据并发送非应答位
// 	while( SI==0 );
	if(AckBus()==0)	return(0);  
	    
  	*DataPrt = I2DAT;
  	I2CON    = GENERATE_STOP;         //结束总线
  	  	
  	return(1);
}






//**********************************************************
//名称:
//功能:
//说明:
//**********************************************************
void Watchdog_feed(void)
{  
  	EA     = 0;
  	WFEED1 = 0xA5;
  	WFEED2 = 0x5A;
  	EA     = 1;
}




//**********************************************************
//名称:DelayNmS
//功能:
//说明:延时NmS
//**********************************************************
void DelayNms(uchar value)
{
	uchar i;
	uchar j;

	while(value--)
	{	
		//1ms=10*100us
		for(i=0;i<10;i++)
		{		
			//100us
			j=184;
			while(--j);		
		} 
	}
}




//**********************************************************
//名称:
//功能:
//说明:
//**********************************************************
void  ArrayInit(uchar idata *ptr,uchar len)
{
	uchar i;

	i= 0x00;
	do
	{
		*ptr = 0x00;
		ptr++;
		i++;		
	}while(i<len);
}




//**********************************************************
//名称:BCD检查
//功能:
//说明:
//**********************************************************
bit BCDCHK(uchar idata *ptr,uchar len)
{	
	uchar i;
	uchar Temp;		

	i=0x00;
	do
	{		
		Temp = *ptr;		
		if( (Temp&0x0F)>0x09 || (Temp&0xF0)>0x90 ) return(0);		
		ptr++;
		i++;		
	}while(i<len);

	return(1);
}




//**********************************************************
//名称:BCD转HEX
//功能:
//说明:返回HEX值
//**********************************************************
uchar BCD2HEX(uchar BCDdata)
{
	uchar Temp;
	
	Temp  = (BCDdata>>4)*10;
	Temp +=  BCDdata&0x0F;
	
	return Temp;
}




//**********************************************************
//名称:SumCHK()
//功能:返回数据校验和
//说明:
//**********************************************************
uchar SumCHK(uchar idata *ptr, uchar len)
{
  	uchar i;
	uchar TmpData; 
	uchar SumData;

	TmpData = 0x00;
 	SumData = 0x00; 	
	i       = 0x00;
	do
  	{
  		TmpData  = *ptr;
		SumData += TmpData; 				
  		ptr++;
  		i++;
  	} while(i<len);

	return SumData;
}





//**********************************************************
//名称:BCD加法
//功能:
//说明:返回进位
//**********************************************************
uchar BCDINC(uchar idata *ptr,uchar len,uchar step)
{
  	uchar i;
  	uchar TCF;
  	uchar Temp;

   	i    = 0x00;
	TCF  = 0x00;
 	Temp = 0x00;
 	TCF  = step;
	do
  	{
  		Temp = BCD2HEX(*ptr)+TCF;
  		TCF  = Temp/100;  		
  		Temp = Temp%100;
  	    *ptr = (Temp/10)<<4;	
  		*ptr = *ptr+Temp%10;  		
  		ptr++;
		i++;
  	}while(i<len);

	return TCF;
}

⌨️ 快捷键说明

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