📄 rtc_dsp.c
字号:
if(i<3)
{
DspBuf[6] = 0x10; //LED2
DspBuf[7] = 0x10; //LED1(最高位)
if(i==1)
{
DspBuf[4] = 0x10; //LED4
DspBuf[5] = 0x10; //LED3
}
}
}
//电量相关显示屏
else if(DspPtr<22) //显示指针10~21
{
if(DspPtr<14) //当前总有功(总、峰、平、谷)电量
{
CreateRealTimeEry();
i = (DspPtr-10)*4;
for(j=0;j<4;j++) DspExch[j] = CommVariant[i+j];
}
else //14~21
{
addr1 = 0x01; //上月总有功(总、峰、平、谷)电量
j = DspPtr-14;
if(DspPtr>17)
{
addr1 = 0x02; //上月正向有功(总、峰、平、谷)电量
j = DspPtr-18;
}
i = LastMonthSN(0); //如果上1月为2月,则i=1
////////////////////////////////////////////////////////////////////////////
if(isLastMonthEry==0x01) i = LastMonthSN(1); //用上上月电量代替上月电量
////////////////////////////////////////////////////////////////////////////
i <<= 4; //上1月总有功总电量地址
i += (j<<2);
//addr2 = i;
Read24C64(CommVariant,addr1,i,4); //读取历史电量数据
for(j=0;j<4;j++) DspExch[j] = CommVariant[j];
}
//十万位不处理
DspBuf[7] = DspExch[3]&0x0F; //万位 :LED1(最高位)
DspBuf[6] = DspExch[2]>>4; //千位 :LED2
DspBuf[5] = DspExch[2]&0x0F; //百位 :LED3
DspBuf[4] = DspExch[1]>>4; //十位 :LED4
DspBuf[3] = DspExch[1]&0x0F; //个位 :LED5
DspBuf[2] = DspExch[0]>>4; //小数位:LED6(最低位)
}
//系统自检结果显示
else if(DspPtr==22) //显示指针22
{
DspBuf[7] = 0x0E; //"E" :LED1(最高位)
DspBuf[6] = 0x10; //"" :LED2
DspBuf[5] = 0x10; //"" :LED3
DspBuf[4] = SystemCheckFlag&0x04; //EEPROM :LED4
DspBuf[3] = SystemCheckFlag&0x02; //RTC :LED5
DspBuf[2] = SystemCheckFlag&0x01; //BAT :LED6(最低位)
}
//else if(DspPtr==23) //显示指针23,系统备用
//{
//}
//扩展查询显示屏
else if((DspPtr>25)&&(DspPtr<47)) //显示指针26~46
{
i = 0xC0; //预置为6个“8”字LED显示: 1100 0000
if(DspPtr==26) //时钟偏置
{
Read24C64(CommVariant,0x08,0xFE,1);
DspExch[0] = CommVariant[0];
DspExch[2] = DspExch[0];
i = 0xCC; //1100 1100
}
else if(DspPtr==27) //全显界面
{
DspExch[2] = 0x88;
DspExch[1] = 0x88;
DspExch[0] = 0x88;
//i = 0xC0;
}
else if((DspPtr==28)||(DspPtr==29)) //时段表切换及标志
{
Read24C64(CommVariant,0x09,0x40+(DspPtr-28)*3,3);
for(j=0;j<3;j++) DspExch[j] = CommVariant[j];
//i = 0xC0;
}
else if(DspPtr==30) //电量清零次数
{
Read24C64(CommVariant,0x05,0xE9,1);
DspExch[0] = CommVariant[0];
i = 0xFC; //1111 1100;
}
else //时段表1、2时段1~8(30<DspPtr<47)
{
i = DspPtr-30-1; //获取时段N的地址
j = 0x60+i*3;
if(DspPtr>38)
{
i = DspPtr-38-1; //获取时段N的地址
j = 0x80+i*3;
}
Read24C64(CommVariant,0x00,j,3);
for(j=0;j<3;j++) DspExch[j] = CommVariant[j];
nFee = DspExch[0]; //暂存时段N费率号
DspExch[0] = DspExch[1]; //分
DspExch[1] = DspExch[2]; //时
DspExch[2] = (i+1)<<4;
i = 0xD0; //1101 0000;
}
//显示数据拆分
DspBuf[2] = DspExch[0]&0x0F; //LED6(最低位)
DspBuf[3] = DspExch[0]>>4; //LED5
DspBuf[4] = DspExch[1]&0x0F; //LED4
DspBuf[5] = DspExch[1]>>4; //LED3
DspBuf[6] = DspExch[2]&0x0F; //LED2
DspBuf[7] = DspExch[2]>>4; //LED1(最高位)
///////////////////////////////////////////////////////////////////////////////
//隐显处理
for(j=0;j<6;++j)
{
if((i>>j)&0x01) DspBuf[j+2]=0x10;
}
///////////////////////////////////////////////////////////////////////////////
}
//错误或未用的轮显项处理
else
{
DspPtr = 0x00;
LCDShowMode = 0; //切换为正常轮显模式
DspSec = 0; //显示计数清零
}
DspBuf[0] = 0;
DspBuf[1] = 0;
for(i=2;i<8;i++) DspBuf[i] = LcdCoding[DspBuf[i]]; //显示编码转换(LED1~LED6)
if(EryRev==1) DspBuf[1] |= 0x02; //反向状态显示
if(CommLCDSec>0) DspBuf[1] |= 0x04; //通讯状态显示
//各页固定显示字符形成
switch(DspPtr)
{
case 0x00://当前日期
DspBuf[0] |= 0x80; //"日期"
DspBuf[4] |= 0x10; //P4
DspBuf[6] |= 0x10; //P2
break;
case 0x01://当前时间+":"
DspBuf[0] |= 0x28;//"时间"+P7
DspBuf[1] |= 0x80;//P8
DspBuf[4] |= 0x10;//P4
DspBuf[6] |= 0x10;//P2
break;
case 0x02://自动抄表日期
DspBuf[4] |= 0x10; //P4
break;
case 0x03://资产条形码号(显示前六位)
DspBuf[0] |= 0x40; //显示“上”
DspBuf[1] |= 0x20; //显示“局号”
break;
case 0x04://资产条形码号(显示后六位)
DspBuf[1] |= 0x20; //显示“局号”
break;
case 0x05://屏幕循显时间
//break;
case 0x06://输出脉冲宽度
//break;
case 0x07://电表有功常数
break;
case 0x08://有功反向累计总时间
DspBuf[0] |= 0x20; //显示“时间”
DspBuf[1] |= 0x02; //显示“反向”
break;
case 0x09://现在执行时段表编号
break;
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x0E:
case 0x0F:
case 0x10:
case 0x11:
case 0x12:
case 0x13:
case 0x14:
case 0x15://电量数据显示
DspBuf[1] |= 0x09; //"电量"+"kW/h"
DspBuf[3] |= 0x10; //小数点--->5P
if(DspPtr>13) DspBuf[0] |= 0x02; //显示“上月”
if(DspPtr==10||DspPtr==14||DspPtr==18) DspBuf[0] |= 0x01; //显示“总”
else if(DspPtr==11||DspPtr==15||DspPtr==19) DspBuf[1] |= 0x10; //显示“峰”
else if(DspPtr==12||DspPtr==16||DspPtr==20) DspBuf[0] |= 0x04; //显示“平”
else DspBuf[1] |= 0x40; //显示“谷”
break;
case 0x16://系统自检
case 0x1A://时钟偏置
break;
case 0x1B://全显界面
DspBuf[0] = 0xFF;
DspBuf[1] = 0xFF;
break;
case 0x1C://时段切换标志、时、分
//时段切换日、月、年
DspBuf[6] |= 0x10; //小数点--->2P
DspBuf[0] |= 0x68; //时间、上、P7
DspBuf[4] |= 0x10; //小数点--->4P
break;
case 0x1D://时段切换日、月、年
DspBuf[6] |= 0x10; //小数点--->2P
DspBuf[0] |= 0xC0; //日期、上
DspBuf[4] |= 0x10; //小数点--->4P
break;
case 0x1E://电量清零次数
break;
default://时段表1、2时段1~8
if(DspPtr>38) DspBuf[0] |= 0x40; //时段表2显示“上”
if(nFee==2) DspBuf[1] |= 0x10; //显示“峰”
if(nFee==3) DspBuf[0] |= 0x04; //显示“平”
if(nFee==4) DspBuf[1] |= 0x40; //显示“谷”
DspBuf[4] |= 0x10; //小数点--->4P
DspBuf[1] |= 0x80; //P8
break;
}
Display(DspBuf); //输送显示数据
/////////////////////////////////////////////////////////////////////////
/***********************************************************************/
//刷新I/O口工作模式
P0M1=0xCF; //11001111
P0M2=0xB0; //10110000
P1M1=0x3F; //00111111
P1M2=0xCD; //11001101
P2M1=0xFC; //11111100
P2M2=0xFF; //11111111
P3M1=0x03; //00000011
P3M2=0x00; //00000000
/***********************************************************************/
if( ((Prog_Flag)&&(Last_Prog_Flag==0x01)) || (ProgActiveFlag==0xFF) ) //LED编程提示
{
ProgLEDShow = ~ProgLEDShow;
if(ProgLEDShow==0xFF)
{
LED_F = 0; //峰
LED_P = 0; //平
LED_G = 0; //谷
}
else
{
LED_F = 1; //峰
LED_P = 1; //平
LED_G = 1; //谷
}
}
else
{
LED_F = 1; //峰指示灯灭
LED_P = 1; //平指示灯灭
LED_G = 1; //谷指示灯灭
if((Fee1==0)&&(Fee0==1)) LED_F = 0; //峰时段指示亮
else if((Fee1==1)&&(Fee0==1)) LED_G = 0; //谷时段指示亮
else LED_P = 0; //平时段指示亮
}
////////////////////////////////////////////////////////////////////////////
}
//**********************************************************
//读取显示控制数据
//**********************************************************
void DspPara_Read(void)
{
uchar Temp,CorrectFlag;
CorrectFlag = 0xAA;
Read24C64(CommVariant,0x00,0x50,6);
for(Temp=0;Temp<6;Temp++) DspPara[Temp] = CommVariant[Temp];
Temp = DspPara[0]+DspPara[1]+DspPara[2];
//显示数据默认值,必要时可以更改
if( (DspPara[3]!=~Temp) || ((DspCtrl1==0x00)&&(DspCtrl2==0x00)&&((DspCtrl3&0x3F)==0x00)) )
{
DspCtrl1 = 0x03; //当前日期、时间
DspCtrl2 = 0x34; //当前总有功(总、平、谷)指数
DspCtrl3 = 0x00; //
DspParaCHK = 0xC8; //校验和反码
CorrectFlag = 0x55; //重新写入EEPROM
}
//轮显时间默认值,必要时可以更改
if((DspTime!=~DspTimeCHK)||(DspTime==0))
{
DspTime = 0x10; //10秒,BCD码
DspTimeCHK = 0xEF; //反码校验
CorrectFlag = 0x55; //重新写入EEPROM
}
//纠正循显参数
if(CorrectFlag==0x55)
{
for(Temp=0;Temp<6;Temp++) CommVariant[Temp] = DspPara[Temp];
Write24C64(CommVariant,0x00,0x50,6);
}
}
//***********************************************************
// 名称: bit DateTerm(void)
// 功能: 校时期判断(30天判断)
// 说明: 编程禁止时,同一块电表的两次对时操作必须相隔30天以上.
//***********************************************************
bit DateTerm(void)
{
uchar Temp;
uchar DataTime[5];
//if(Prog_Flag==1) return(1); //编程允许时,则校时期允许
//else
//{
Read24C64(DataTime,0x08,0x7A,5); //读取上次校时时间
Temp = SumCHK(DataTime,4);
if(Temp!=~DataTime[4]) //读取最近校时时间发生错误
{
return(1); //预置一次广播校时机会
}
//==================================================
//月判断
//==================================================
Temp = BCD2HEX(Month); //当前月份
DataTime[3] = BCD2HEX(DataTime[3]); //上次校时月份
if(Temp<DataTime[3]) Temp += 12; //跨年
DataTime[4] = Temp-DataTime[3]; //计算月差
Temp = 0; //预置不进行30日、小时、分比较
if(DataTime[4]>2) return(1); //相隔至少3个月,满足校表日期条件
else if(DataTime[4]==2) //相隔2个月
{
if(DataTime[3]==1) //上次校时月份为1月
{
Temp = BCD2HEX(Day); //当前日期
DataTime[2] = BCD2HEX(DataTime[2]);//上次校时日期
if((BCD2HEX(Year)%0x04)==0x00) Temp += 29; //闰月判断,百年问题不考虑
else Temp += 28;
Temp += 31;
}
else return(1); //上次校时月份不为1月,满足校表日期条件
}
else //相隔0、1个月
{
Temp = BCD2HEX(Day); //当前日期
DataTime[2] = BCD2HEX(DataTime[2]);//上次校时日期
if(DataTime[4]==1) //相隔1个月
{
//上次校时月份为2月
if( DataTime[3]==2 )
{
if((BCD2HEX(Year)%0x04)==0x00) Temp += 29; //闰月判断,百年问题不考虑
else Temp += 28;
}
//上次校时月份为4、6、9、11月
else if(DataTime[3]==4||DataTime[3]==6||DataTime[3]==9||DataTime[3]==11) Temp += 30;
//上次校时月份为1、3、5、7、8、10、12月
else Temp += 31;
}
//else Temp = BCD2HEX(Day); //Temp即为当前日期
}
if(Temp>DataTime[2])
{
Temp -= DataTime[2];
//校时限制天数(30天)判断
if(Temp>DateErrorTerm) return(1);
else if(Temp==DateErrorTerm)//天数相等
{
//小时、分比较
if((Hour>DataTime[1])||((Hour==DataTime[1])&&(Min>=DataTime[0]))) return(1);//5分钟有效
else return(0);
}
else return(0);
}
else
{
return(0);
}
//}
}
//**********************************************************
// 名称: Ery_Balance()
// 功能: 电量结算处理,电表管理状态切换处理
// 说明:
//**********************************************************
void Ery_Balance(void)
{
uchar j,Temp,vTemp;
uchar TMonth[2];
uchar TBalance;
//读取上次结算月份
CurrentMonthNoBlnFlag = 0x00;
isLastMonthEry = 0x00;
TBalance = BlnDateCheck(0x8B); //电能结算日期判断
////////////////////////////////////
if(TBalance>12) TBalance = 0x00;
////////////////////////////////////
if(TBalance>0x00)
{ //////////////////////////////////////////////////////////////////////
ePowerDownCheckFlag = DISABLE; //关闭掉电检测
//////////////////////////////////////////////////////////////////////
//判断当前月是否进行电能结算
vTemp = 0x00;
TMonth[0] = BCD2HEX(Month); //当前月份HEX数据
if(CurrentMonthNoBlnFlag==0x01)
{
vTemp = 0x01; //本月结算日未到,不结算
if(TMonth[0]==1) TMonth[0] = 12;
else TMonth[0]--;
CurrentMonthNoBlnFlag = 0x00;
}
//形成(总/正/反)(总、峰、平、谷)电量
CreateRealTimeEry();
//保存历史电量,反向历史事件
for(j=0;j<3;j++)
{
for(Temp=vTemp;Temp<TBalance;Temp++)
{
Write24C64(&CommVariant[j*16],j+1,LastMonthSN(Temp)<<4,16);
}
}
//读取当前月反向累计时间、最后一次反向起、止时间
Read24C64(CommVariant,0x04,0xC0,16);
//写本次结算形成的上几个月的反向历史电量事件
for(Temp=vTemp;Temp<TBalance;Temp++)
{
Write24C64(CommVariant,0x04,LastMonthSN(Temp)<<4,16);
}
//清除当前月反向累计时间、最后一次反向起、止时间
if(vTemp==0)
{
ArrayInit(CommVariant,16);
EryRev = 0;
Write24C64(CommVariant,0x04,0xC0,16);
}
//写本次结算月份,为下次结算作参考
TMonth[1] = ~TMonth[0];
Write24C64(TMonth,0x08,0x8B,2);
//////////////////////////////////////////////////////////////////////
ePowerDownCheckFlag = ENABLE; //打开掉电检测
//////////////////////////////////////////////////////////////////////
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -