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

📄 rtc_dsp.c

📁 江苏单相复费率电能表方案
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <Reg931.h>
#include <Meter_def.h>
#include <General.h>

#ifdef    uchar 
  #define READYDEF 1     //宏uchar已定义
#else  
  #define uchar unsigned char 
#endif



//**********************************************************
//变量申明
//**********************************************************
extern uchar bdata MeterFlag;
extern bit   Battery;
extern bit   Hardware;
extern bit   RsComm; 
extern bit   AdjTime;
extern bit   EryRev;
extern bit   AdjDate;
extern bit   Fee0;
extern bit   Fee1;

extern uchar bdata Flag;
extern bit   TimeAdj;
extern bit   TimeProg;
extern bit   RxdFlag;
extern bit   TxdFlag;
extern bit   TxdWork;
extern bit   DspType;
extern bit   DspPage;
extern bit   DspFlag;

extern uchar bdata SystemStates; 
extern bit   Comm_RTC_Err;
extern bit   Comm_EPM_Err;
extern bit   Data_RTC_Err;
extern bit   Data_EPM_Err;
extern bit   EryBln_Flag;
extern bit   Prog_Flag;
extern bit   Fee_Flag;
extern bit   CommFlag;

extern uchar ComPtr;
extern uchar DspPtr;
extern uchar DspSec;
extern uchar RevSec;
extern uchar CommSec;
extern uchar CommTimer;

extern uchar Len[2];
extern uchar Addr[2];
extern uchar DspPara[4];
extern uchar DspExch[6];
extern uchar PulseTmp[6];
extern uchar EryTmp[6];
extern uchar RTC[8];
extern uchar Ptr[8];
extern uchar idata ComBuf[RS_MaxSize];

extern unsigned int MSSum;
extern unsigned int ProgTimer; 


//===============================================
//LCD_TABLE
//===============================================
uchar code LcdCoding[17]=
{
	0xED,	//"0"  a+b+c+d+e+f
	0x60,	//"1"  b+c 
	0xA7,   //"2"  a+b+d+e+g
	0xE3,   //"3"  a+b+c+d+g
	0x6A,   //"4"  b+c+f+g
	0xCB,   //"5"  a+c+d+f+g 
	0xCF,   //"6"  a+c+d+e+f+g
	0xE0,   //"7"  a+b+c   
	0xEF,   //"8"  a+b+c+d+e+f+g
	0xEB,   //"9"  a+b+c+d+f+g    
	0xEE,   //"A"  a+b+c+e+f+g
    0x4F,   //"b"  c+d+e+f+g
    0x8D,   //"C"  a+d+e+f
    0x67,   //"d"  b+c+d+e+g
    0x8F,   //"E"  a+d+e+f+g
    0x8E,   //"F"  a+e+f+g
    0x00	//" "  
};




//===============================================
//时钟温度补偿表
//===============================================
uchar code Equalize_Table[91]=
{
	0x63,0x5F,0x5B,0x57,0x53,	//  0~4
	0x4F,0x4B,0x47,0x43,0x3F,	//  5~9
	0x3B,0x37,0x33,0x2F,0x2B,	// 10~14
	0x28,0x25,0x22,0x1F,0x1C,	// 15~19
	0x09,0x06,0x04,0x02,0x01,	// 20~24
			  0x00,				// 25
	0x00,0x01,0x01,0x02,0x03,	// 26~30
	0x05,0x06,0x08,0x0A,0x0D,	// 31~35
	0x0F,0x12,0x15,0x19,0x1C,	// 36~40
	0x20,0x24,0x29,0x2E,0x32,	// 41~45
	0x38,0x3D,0x43,0x49,0x4F,	// 46~50

	0x55,0x5C,0x63,0x6A,0x71,	// 51~55
	0x79,0x81,0x89,0x92,0x9A,	// 56~60
	0xA3,0xAD,0xB6,0xC0,0xCA,	// 61~65
	0xD4,0xDE,0xE9,0xF4,0xFF, 	// 66~70

	0x67,0x6B,0x6F,0x73,0x77,	// -1  ~ -5
	0x7C,0x81,0x86,0x8B,0x90,	// -6  ~ -10
	0x95,0x9A,0x9F,0xA5,0xAB,	// -11 ~ -15
	0xB2,0xB8,0xBE,0xC4,0xCA	// -16 ~ -20 
};


           
//**********************************************************
//函数申明
//**********************************************************
void  RTC_Dsp_Proc(void);								//时间、显示事件处理 
void  Dsp_Proc(void);									//显示处理
void  Rev_Proc(void);									//电能反向处理
void  DspPara_Read(void);								//读显示控制参数
void  Ery_Balance(void);								//电量冻结
void  Temp_Equalize(void);								//时钟温度补偿
void  Fee_CHK(void);									//费率检查和切换

void  RTC_Init(void);									//RTC初始化设置
void  RTC_Read(void);									//时间读取
void  RTC_BAK(void);									//时间备份
void  SECINC(void);                                     //秒加1

void  Display(uchar idata *ptr);						//LCD数据刷新
void  RTC_Set(uchar staddr,uchar idata *ptr,uchar len);	//RTC设置

 bit  DateTerm(void);									//日期条件判断
 bit  DateCHK(uchar idata *ptr);						//日期正确性判断
 bit  TimeCHK(uchar idata *ptr);						//时间正确性判断
 
uchar Temp_Read(void);									//温度测量
uchar LastMonthSN(uchar sn);							//历史月份计算

extern bit  ReadData(uchar idata *ptr); 

extern void WriteEPMData(uchar idata *ptr);
extern void ErrorModify(uchar addr,uchar idata *ptr);




//**********************************************************
// 名称:RTC_Dsp_Proc()
// 功能:
// 说明:
//**********************************************************
void RTC_Dsp_Proc(void)									
{	  	
  	Watchdog_feed();									//喂狗
    
    //电池情况
	Battery  = 1;   									//电池电压偏低
  	if(CMP2&0x02) 			Battery  = 0;				//电池电压正常
	
	//********  	
    //硬件情况	
  	Hardware = 0; 										//电表硬件正确
  	if(SystemStates&0x0F)	Hardware = 1;				//电表硬件出错 
  	//********

  	//编程开关处理
  	if(PROG==0)
    {
		DelayNms(100);									//按键延时100ms

		if( PROG==0 )
		{	    
			Prog_Flag = 1;  							//确认编程按键操作有效		
			ProgTimer = 0x0000;							//编程有效计时器清零
			AdjDate   = 1;	 							//校时期有效

			//通讯指示灯闪烁一下
			LED_COMM  = !LED_COMM;
			DelayNms(100);								//闪烁100ms
			LED_COMM  = !LED_COMM;
		}
    }
    else
    {      	
		if(ProgTimer>=1800)								//编程开关有效时间:30分钟
		{
			Prog_Flag = 0;
			ProgTimer = 0x0000;
			AdjDate   = DateTerm();						//日期条件处理
		} 
    }

    //费率检查	
  	if(Fee0==0&&Fee1==0)	Fee_CHK();					//费率检查和恢复(出错处理)
  	  	
    //显示方式检查	
  	if(DspParaCHK!=SumCHK(DspPara,3))DspPara_Read();	//显示控制参数校对处理
 
    //显示刷新
	if(DspFlag==1)										//显示刷新标志位(1秒刷新一次)
  	{	
        DspFlag = 0;									//清除显示刷新标志位        
        
        //※※※※※※※※※※※※※※※※※※※※※※※※※※※※※  	  	             
        if(CommSec==0x00)	              		    	//通讯指示灯灭,指示时间超出或没有通讯产生
        {
        	LED_COMM = 1;            
        }
        else
        {
         	LED_COMM = 0;								//通讯指示灯亮
        	CommSec--;									//维持时间减一        	
        }	
		//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※		
  	
  		
  		//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※  	  	  		
    	if(Sec==0x59)
    	{
    		//整分时刻任务事件处理

	 		RTC_Read(); 								//1分钟间隔校时
    		
			if(Sec<=0x02)								//3秒时间窗口
			{
    			if(Min&0x01)	RTC_BAK();				//逢单时间备份(2分钟备份一次)

				AdjDate = DateTerm();					//日期条件检查

				if(((Min==0x00)||(Min==0x30)))			//半小时间隔判断检查
				{	
					Fee_Flag = 1;						//时段费率检查标志位

					RTC_Init();							//时钟配置初始化(刷新)
			
					if(Min==0x00)						//整点时刻任务处理
					{
						EryBln_Flag = 1;				//电量冻结计算标志
						Temp_Equalize(); 				//1小时时钟温度补偿					
					}
				}
			}
    	}
    	else  	SECINC();								//秒加1

	
    	//※※※※※※※※※※※※※※※※※※※※※※※※※※※※※    	

	  	Rev_Proc(); 									//电能反向事件处理  
    	
    	Dsp_Proc();										//显示处理
  	}

   	if(CommFlag==0)                                     //不在通讯状态
    {
		HW38K   = 1;

		if(COMMSEL==0)	    KBMASK  = 0x40;				//默认红外通讯

    	if(Fee_Flag==1)	    Fee_CHK();				    //时段费率处理
	
    	if(EryBln_Flag==1)	Ery_Balance();			    //结算日处理(日、时)
    }
}




//**********************************************************
// 名称:Rev_Proc()
// 功能:
// 说明:电能反向时间处理
//**********************************************************
void Rev_Proc(void)
{
	uchar DataTime[8];

	//电能反向起始时间判断
	if( REVP==0 )
  	{   
		DelayNms(10);

		if( REVP==0 )
		{	 	
    		if(EryRev==0)								//电能反向起始条件及时间
    		{    									
    			//反向事件发生时实时时间
    			DataTime[0] = Min;						//分
    			DataTime[1] = Hour;						//时
	    		DataTime[2] = Day; 						//日   	
	    		DataTime[3] = Month;					//月     	
      			DataTime[4] = SumCHK(DataTime,4); 	   
        	
        		Addr[0] = 0xA0; 
        		Addr[1] = 0xAA;    
        		Len[1]  = 0x05;
				WriteEPMData(DataTime);
       		}		                  	
      		EryRev = 1;									//电能反向标志置位 
		}
  	}
	else	EryRev = 0;									//电能正常	
  	
  	
  	//电能反向累计总时间计算
  	if( RevSec>59 )										//反向时间累计满1分钟处理
  	{
  		RevSec  = 0x00;
		  		
  		Addr[0] = 0xA0;
        Addr[1] = Ptr[6];
        Len[1]  = 0x04;
      	do
      	{
       		ReadData(DataTime);
  			DataTime[4]= DataTime[0]+DataTime[1]+DataTime[2];		//SumCHK(DataTime,3);
      	} while((DataTime[4]!=DataTime[3])&&(Addr[0]<=0xA4));
		
		if(DataTime[4]!=DataTime[3])	ArrayInit(DataTime,4);	   //数据错误,清零
						
  		BCDINC(DataTime,3,1);                                       //+1
  		DataTime[3] = DataTime[0]+DataTime[1]+DataTime[2];			//SumCHK(DataTime,3);
  		
  		Addr[0] = 0xA0;
		WriteEPMData(DataTime);										//写数据

  		Addr[0] = 0xA0;												//读取存储区数据
		ReadData(&DataTime[4]);

  		if((DataTime[7]!=SumCHK(&DataTime[4],3))||(DataTime[3]!=DataTime[7]))//比较数据的正确性
  		{	
  			EC = 0;													//关闭掉电检测
			
			Addr[0] = 0xA0;
			WriteEPMData(DataTime);									//再次写入数据

			Addr[0] = 0xA0;
			ReadData(&DataTime[4]);									//再次读取数据  			

  			if((DataTime[7]!=SumCHK(&DataTime[4],3))||(DataTime[3]!=DataTime[7]))//再次数据比较判断
  			{
  				Ptr[6] += 0x04;				
				if(Ptr[6]>=0x40)Ptr[6] = 0x30;  					//指针边界处理
							
				DataTime[4] = Ptr[6];
				DataTime[5] =~Ptr[6];
			
				Addr[0] = 0xA0;
				Addr[1] = 0xBC;
       			Len[1]  = 0x02;
				WriteEPMData(&DataTime[4]);							//指针值
			
				Addr[0] = 0xA0;
				Addr[1] = Ptr[6];
        		Len[1]  = 0x04;
				WriteEPMData(DataTime);								//反向累计时间值				
			
				Ptr[7]  = SumCHK(Ptr,7);
			}			
			EC = 1;													//开启掉电检测
  		}
  	}
}






//**********************************************************
// 名称:Dsp_Proc()
// 功能:
// 说明:
//**********************************************************
void Dsp_Proc(void)
{ 	
  	uchar i;  	 	
 	uchar DspBuf[8];									//显示缓冲区
  	
  	ArrayInit(DspBuf,8);								//显示缓冲区清零    	

	//显示方式												
  	DspType = 0;										//5+1显示
  	if(DspCtrl1&0x80)DspType = 1;				        //小数分开显示

  	DspSec++;											//轮显时间+1
  	
    //显示项目切换
    if(DspSec>=BCD2HEX(DspTime))						//轮显时间满,更新显示指针
    { 
    	DspSec  = 0;									//显示计数清零		
		DspPage = 0; 									//显示首页  			
		   	
      	i = 0x00;										//轮显指针处理
      	do
      	{       			
      		DspPtr++; 
      		if( DspPtr<7 )	  i = (DspCtrl1>>DspPtr)&0x01;     //      		
			if( DspPtr>7 )
			{
				/*
				if(DspPtr<16) i = (DspCtrl2>>(DspPtr-8))&0x01; // 			
				
				else if(DspPtr==16)  
				{
					if(DspCtrl1&0x40)	i	   = 0x01; 	//电表自检有效
					else		  		DspPtr = 0xFF;
				} 			
				else 			   		DspPtr = 0xFF;  			
				*/

				if(DspPtr<16)
				{ 
					i = (DspCtrl2>>(DspPtr-8))&0x01; 
				}
				else if(DspPtr==16) 	//电表自检有效 
				{
					if(DspCtrl1&0x40) i = 0x01; 					
				} 
				else if(DspPtr==17)		//电池偏低报警
				{
				    if(Battery==1)    i = 0x01;
				}			
				else 		     DspPtr = 0xFF;  
			}

      	} while(i==0x00);
     
     	if(DspPtr<8)
     	{ 		
			if((DspPtr>0x01)&&(DspPtr<0x05))			//当前总、峰、谷电量
			{	
     			Addr[0] = 0xA0;
     			
     			if(DspPtr==0x02)						//当前总电量     			
     			{
     				Addr[1]    = 0xC1;
     				DspExch[0] = EryTmp[0];
     			}
     			else if(DspPtr==0x03)					//当前峰电量     			   				
     			{
     				Addr[1]    = 0xC5;
     				DspExch[0] = EryTmp[1];
     			}
     			else 									//当前谷电量
     			{
     				Addr[1]    = 0xCD;
     				DspExch[0] = EryTmp[3];
     			} 		

      			Len[1] = 0x03;      			
				ReadData(&DspExch[1]);					//读取电量整数数据				
			}
			
			if(DspPtr==0x05)							//局编号处理
			{
				//ID检查
				Addr[0] = 0xA0;
   				Addr[1] = 0xF0;
   				Len[1]  = 0x07; 
    			do
    			{
    				ReadData(DspBuf);
					i = SumCHK(DspBuf,6);    				
    			}while((i!=DspBuf[6])&&(Addr[0]<=0xA4));
    	
    			if( i!=DspBuf[6] ) ArrayInit(DspBuf,8);	//局号默认为“000000000000”
    			
				ErrorModify(0xA4,DspBuf);				//保存区数据重置
 

⌨️ 快捷键说明

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