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

📄 rtc_dsp.c

📁 江苏单相复费率电能表方案
💻 C
📖 第 1 页 / 共 3 页
字号:
	//读有效时段数
	Addr[0] = 0xA2;	
    Addr[1] = 0xCE;
    Len[1]  = 0x02;    
    do
    {
        ReadData(Num);
    } while((Num[0]!=~Num[1])&&(Addr[0]<=0xA6));
		
	TFlag = 0x00;		
	if((Num[0]!=~Num[1])||(Num[0]<2)||(Num[0]>12)) TFlag = 0x01;//有效时段数错误	
	else
	{	
		ErrorModify(0xA6,Num);
		Num[0] *= 0x03;   
 				
		Addr[0] = 0xA2;	
    	Addr[1] = 0xD0;    
    	Len[1]  = Num[0]+1;//长度:数据+校验和    	
    	do
    	{
        	ReadData(ComBuf);
      	    Num[1]   = SumCHK(ComBuf,Num[0]);//校验和      		        				
    	} while((Num[1]!=~ComBuf[Num[0]])&&(Addr[0]<=0xA6));	
		
		if(Num[1]!=~ComBuf[Num[0]])	TFlag=0x01;		//时段数据错误
		else
		{			
			TFee    = 0x00;				
			Num[1]  = 0x00;
			Num[0]--;

			if((Hour<ComBuf[2])||(Hour>ComBuf[Num[0]]))	TFee=ComBuf[Num[0]-2];//跨零点区域费率判断
			else
			{	
				do					
				{					
					if(Num[1]==(Num[0]-2))	TFee=ComBuf[Num[0]-2];//时段表末尾
					else
					{
						if(Hour>=ComBuf[Num[1]+2])
						{
							if(Hour<ComBuf[Num[1]+5])
							{
								TFee = ComBuf[Num[1]];
							}					
							else
							{
								if((Hour==ComBuf[Num[1]+2])&&(Hour==ComBuf[Num[1]+5]))
								{
									if(Min<0x30)	TFee = ComBuf[Num[1]];
									else			TFee = ComBuf[Num[1]+3];
								}
							}				
						}
					}

					Num[1] += 0x03;

				}while( (TFee==0x00)&&(Num[1]<Num[0]));//后条件为冗余条件
				
				if(TFee==0x00)	TFlag=0x01;//冗余代码,时段费率查找失败
			}
		}
	}
	
	if(TFlag!=0x00)
	{
		//默认有效时段数 
    	Num[0] =  0x02;
    	Num[1] = ~0x02;
    	
		Addr[0] = 0xA2;
		Addr[1] = 0xCE;		   		
    	Len[1]  = 0x02;
		WriteEPMData(Num);
		
		//默认时段值
    	ComBuf[0] = 0x02;//峰时段8:00~21:00
    	ComBuf[1] = 0x00;
    	ComBuf[2] = 0x08;
    	
    	ComBuf[3] = 0x04;//谷时段21:00~8:00
    	ComBuf[4] = 0x00;
    	ComBuf[5] = 0x21;
    	
    	ComBuf[6] = 0xD0;//校验和反码
    	
		Addr[0] = 0xA2;
		Addr[1] = 0xD0;		 
    	Len[1]  = 0x07; 
		WriteEPMData(ComBuf);
	
		Num[1]=BCD2HEX(Hour);

		TFee=0x04;								//谷费率		
		if((Num[1]>=8)&&(Num[1]<21))TFee=0x02;	//峰费率		
	}
	
	LED_F = 1;
	LED_G = 1;
	
	if(TFee==0x04)		//谷
	{
		Fee1=1;
		Fee0=1;
		LED_G = 0;		//谷时段指示亮 		
	}
	else if(TFee==0x03)	//平
	{
		Fee1=1;
		Fee0=0;	               
	}
	else				//峰
	{
		Fee1=0;
		Fee0=1;
		LED_F = 0;		//峰时段指示亮 
	}
	
	Fee_Flag = 0;
	
	ArrayInit(ComBuf,RS_MaxSize);
		
	ES = 1;	
	KBMASK    = 0x40;
}



//**********************************************************
// 名称:RTC参数设置
// 功能:
// 说明:
//**********************************************************
void RTC_Init(void)
{
   	uchar Temp[2];

  	//温度补偿偏移量
	Temp[0] = 0x00;
	RTC_Set(0x70,Temp,1);
	
	//RTC控制寄存器刷新
	Temp[0] = 0x23;//00100011:Alarm_W和Alarm_D无效,24小时制,1秒方波输出
	RTC_Set(0xE0,Temp,1);
}




//**********************************************************
// 名称:RTC_Set(uchar staddr,uchar idata *ptr,uchar len)
// 功能:RTC设置
// 说明:
//**********************************************************
void RTC_Set(uchar staddr,uchar idata *ptr,uchar len)
{
	Addr[0] = RX_8025;           //器件地址 		
    Addr[1] = staddr; 	         //子地址	
  	Len[0]  = 0x02;              //地址长度
  	Len[1]  = len;               //数据长度

  	ISendStr(Addr,ptr,Len);      //发送数据
}




//**********************************************************
// 名称:RTC_Read()
// 功能:时间读取
// 说明:
//**********************************************************
void RTC_Read(void)
{  	
  	uchar Temp;

  	Addr[0] = RX_8025;    		
  	Addr[1] = 0x00;
  	Len[1]  = 0x07;   	
  	
	if(ReadData(RTC)==1)	 	//取当前时间 	
	{
		if(	(TimeCHK(RTC)==0)||(Week>0x06)||(DateCHK(&RTC[4])==0))//时间数据错误  		
  		{
       		Addr[0] = 0xA0;
        	Addr[1] = Ptr[5]; 
        	Len[1]  = 0x08;        	
        	do
        	{
        		ReadData(RTC);
       			Temp = SumCHK(RTC,7);        		    
        	}while((Temp!=RTCCHK)&&(Addr[0]<=0xA4));
        	
        	if(Temp!=RTCCHK )//默认时间值
        	{ 
        		Sec   = 0x00;//秒
        		Min   = 0x00;//分
        		Hour  = 0x00;//时
        		Week  = 0x04;//周
        		Day   = 0x01;//日        	
        		Month = 0x01;//月
        		Year  = 0x04;//年        	
        	}
        	RTC_Init();
        	RTC_Set(0x00,RTC,0x07);        	
        }	
		RTCCHK =SumCHK(RTC,7);
	}
}



//**********************************************************
// 名称:RTC_BAK()
// 功能:时钟缓存备份
// 说明:
//**********************************************************
void RTC_BAK(void)
{
	uchar DataTime[8];
	
	Addr[0] = 0xA0;
 	Addr[1] = Ptr[5];        	       	        	
    Len[1]  = 0x08; 	
	WriteEPMData(RTC);			
	
	//============================================
    //实时时间缓存校对
    //============================================
    Addr[0] = 0xA0;  
    ReadData(DataTime);	
	        		
    if( DataTime[7]!=SumCHK(DataTime,7)||DataTime[7]!=RTCCHK )
    {
    	EC = 0;
    	
    	Addr[0] = 0xA0;  
    	WriteEPMData(RTC);
    	
		Addr[0] = 0xA0;  
    	ReadData(DataTime);

    	if( DataTime[7]!=SumCHK(DataTime,7)||DataTime[7]!=RTCCHK )
    	{     	
        	Ptr[5] += 0x08; 
        	if(Ptr[5]>=0x30)Ptr[5]=0x10;
        	Ptr[7] =SumCHK(Ptr,7);
          		
        	DataTime[0] = Ptr[5];
        	DataTime[1] =~Ptr[5];
          	
        	Addr[0] = 0xA0;
        	Addr[1] = 0xBA; 
        	Len[1]  = 0X02;
        	WriteEPMData(DataTime);  		
  		          	
        	Addr[0] = 0xA0;
        	Addr[1] = Ptr[5];
       		Len[1]  = 0x08;  
       		WriteEPMData(RTC);
    	}
    	EC = 1;   		
    } 
}





//**********************************************************
//秒加1
//**********************************************************
void SECINC(void)
{
   BCDINC(RTC,1,1);						               //Sec加1
   RTCCHK = SumCHK(RTC,7);    	 				       //重置检验和    	 
}





//**********************************************************
//读取温度值
//**********************************************************
uchar Temp_Read(void)
{
	uchar Temp[2];
	
	Temp[0] = 0x00;
	
	//工作方式配置
	Addr[0] = LM75;
	Addr[1] = 0x01;//配置地址
	Len[0]  = 0x02;
	Len[1]  = 0x01;
	ISendStr(Addr,Temp,Len);

	Temp[0] = 0xFF;
	while(Temp[0]--);	
//	for(Temp[0]=0x00;Temp[0]<0xFF;Temp[0]++);  //延时400uS   
    
    //读取温度值 
   	//Addr[0] = 0x90;
	Addr[1] = 0x00;//温度值地址   
   	//Len[0]  = 0x02;
	Len[1]  = 0x02; 

    if(ReadData(Temp)==0) Temp[0] = 20;	//年平均温度
 
    return Temp[0];
}



//**********************************************************
//温度补偿算法
//**********************************************************
void Temp_Equalize(void)
{
	uchar Temp;
	
	Temp = Temp_Read();
	
	if(Temp&0x80) 							  	//温度零下
	{
		 Temp = ~Temp+1+70;
		 if(Temp>90 ) 	Temp = 90;				//低于负20度
	}
    else
	{
		if(Temp>70 ) 	Temp  = 70;				//高于70度
		if(Temp>=50)
		{  
			MSSum += Temp;						//高温>=50度偏置补偿
			if(Temp>=60)MSSum += 100;		 
		}
	}
	
	MSSum += Equalize_Table[Temp];				//误差累加
	
	if(MSSum>=1000)								//时间补偿1秒
	{
		SECINC();
		RTC_Set(0x00,RTC,0x07);
		MSSum -= 1000;	
	}
}



//**********************************************************
//刷新显示数据
//**********************************************************
void Display(uchar idata *ptr)
{	
	uchar Temp[2];

	Addr[0] = PCF8576;         					//从器件地址    	  	
	Len[0]  = 0x01;								//无子地址
  	Len[1]  = 0x02;   	
  	Temp[0] = PWR_MODE|0x80;   					//模式选择指令
  	Temp[1] = OFF_GLITTER;     					//闪烁选择指令 
	if(Prog_Flag==1)  Temp[1] = ON_GLITTER;	 

  	ISendStr(Addr,Temp,Len);

	//Addr[0] = PCF8576; 
	Addr[1] = 0x00; 
    Len[0]  = 0x02; 
  	Len[1]  = 0x08;
  	ISendStr(Addr,ptr,Len); 

	if(CommFlag==0)  COMMSEL = 0;

/*   
	if(CommFlag==0)									//显示RAM初始化清零
	{
		ArrayInit(ComBuf,RS_MaxSize);
		Addr[1] = 16;
		Len[1]  = 11;	
		ISendStr(Addr,ComBuf,Len);  			
	}
*/
} 


//**********************************************************
//历史月份计算
//**********************************************************
uchar LastMonthSN(uchar sn)
{
	uchar Temp1;
	uchar Temp2;
	
	Temp1 = 0x00;
	Temp2 = sn;
	Temp1 = BCD2HEX(Month)+10-Temp2;
	if(Temp1>=12)Temp1 -= 12;
	return Temp1;
}





//**********************************************************
//时间检查
//**********************************************************
bit TimeCHK(uchar idata *ptr)
{ 	
	uchar Temp[3];	
	  	
	Temp[0] = *ptr;//秒    	
	ptr++;
	Temp[1] = *ptr;//分
	ptr++;   	
	Temp[2] = *ptr;//时    	  	

	if( (BCDCHK(Temp,0x03)==0)||(Temp[0]>0x59)||(Temp[1]>0x59)||(Temp[2]>0x23))	return(0);

/*
	if(BCDCHK(Temp,0x03)==0)	return(0);	

	//秒、分、时检查	
	if((Temp[0]>0x59)||(Temp[1]>0x59)||(Temp[2]>0x23))return(0);	
*/
	
	return(1);
}



//**********************************************************
//日期检查
//**********************************************************
bit DateCHK(uchar idata *ptr)
{ 	
	uchar Temp[3];	
	  	
	Temp[0] = *ptr;    	
	ptr++;
	Temp[1] = *ptr;
	ptr++;   	
	Temp[2] = *ptr;    	  	

   	if( (BCDCHK(Temp,0x03)==0)||(Temp[0]==0x00)||(Temp[1]==0x00)||(Temp[1]>0x12) )return(0);
/*
	if(BCDCHK(Temp,0x03)==0)return(0);

	//日、月、年检查	
	if((Temp[0]==0x00)||(Temp[1]==0x00)||(Temp[1]>0x12))return(0);
*/
	
	if(Temp[1]==0x02)
	{
		if(Temp[0]>0x28)
		{
			if((BCD2HEX(Temp[2])&0x03)==0x00)//闰年
			{
				if(Temp[0]>0x29) return(0);
			}
			else return(0); 			
		}
	}
	
	else if((Temp[1]==0x04)||(Temp[1]==0x06)||(Temp[1]==0x09)||(Temp[1]==0x11))
	{
		if(Temp[0]>0x30) return(0);
	}
	
	else
	{
		if(Temp[0]>0x31) return(0);
	}
	
	return(1);
}

⌨️ 快捷键说明

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