📄 rtc_dsp.c
字号:
#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 + -