📄 ircomm.c
字号:
{ //写数据,RAM
RMtCt_Dtr[i] = Temp_WrtDt_Comm[4+i];
}
if(F_BlckWrt_Eeprm(EMtCt_Dtr,&Temp_WrtDt_Comm[4],3))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
Nor_Write_Answer(); //正常应答处理子程序
break;
case 0xC113: //循显时间
if(Temp_WrtDt_Comm[4] == 0)
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
Abn_Answer(); //异常应答处理子程序
return;
}
RShftDspTm_Dtr[0] = Temp_WrtDt_Comm[4];
if(F_BlckWrt_Eeprm(EShftDspTm_Dtr,&Temp_WrtDt_Comm[4],1))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
Nor_Write_Answer();
break;
case 0xC114: //停显时间
RStpDspTm_Dtr[0] = Temp_WrtDt_Comm[4];
if(F_BlckWrt_Eeprm(EStpDspTm_Dtr,&Temp_WrtDt_Comm[4],1))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
Nor_Write_Answer();
break;
case 0xC117: //4、自动抄表日时;
if((Temp_WrtDt_Comm[4]>0x23)||(Temp_WrtDt_Comm[5]>0x28))//dd>31,hh>23
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
Abn_Answer(); //异常应答处理子程序
return;
}
for (i=0;i<2;i++) //写数据,RAM
{
RAUtRdTm_Dtr[i] = Temp_WrtDt_Comm[4+i];
}
if(F_BlckWrt_Eeprm(EAUtRdTm_Dtr,&Temp_WrtDt_Comm[4],2))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
Nor_Write_Answer(); //正常应答处理子程序
break;
case 0xC119: //有功电能起始读数
ClrPw_Accdnt[0] = 0xe8; //清零标志置位
Databuf[0] = 0x00; //非编程状态清零次数重新初始为零
F_BlckWrt_Eeprm(ClrPw_Cnt,Databuf,0x01); //读取清零允许次数
Nor_Write_Answer(); //正常应答处理子程序
break;
case 0xCD01: //16个正常显示序号
for (i=0;i<16;i++) //写数据,RAM
{
if( (Temp_WrtDt_Comm[4+i] > 0x17)
&& (Temp_WrtDt_Comm[4+i] != 0xff)
)
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
Abn_Answer(); //异常应答处理子程序
return;
}
}
for (i=0;i<16;i++) //写数据,RAM
{
RRttDspNo_Dtr[i] = Temp_WrtDt_Comm[4+i];
}
if(F_BlckWrt_Eeprm(ERttDspNo_Dtr,&Temp_WrtDt_Comm[4],16))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
DispTbl_Disp = 1; //显示表有改变信号
Nor_Write_Answer();
break;
case 0xCD03: //16个按键显示序号
for (i=0;i<16;i++) //写数据,RAM
{
if( (Temp_WrtDt_Comm[4+i] > 0x17)
&& (Temp_WrtDt_Comm[4+i] != 0xff)
)
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
Abn_Answer(); //异常应答处理子程序
return;
}
}
for (i=0;i<16;i++) //写数据,RAM
{
RKeyDspNo_Dtr[i] = Temp_WrtDt_Comm[4+i];
}
if(F_BlckWrt_Eeprm(EKeyDspNo_Dtr,&Temp_WrtDt_Comm[4],16))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
DispTbl_Disp = 1; //显示表有改变信号
Nor_Write_Answer();
break;
default: //标识错,异常应答
ErrByte_Comm.BYTE |= 0x02; //标识错,置错误信息字
Abn_Answer(); //异常应答处理子程序
break;
}//switch end
}
//待写入数据BCD码判断
unsigned char Judge_BCD(void)
{
unsigned char i,temp_num;
if (CommandByte_Comm == 0x04) //为了广播校时等其它命令通用
{
temp_num = CommandDataLength_Comm-6;
for(i=0;i<temp_num;i++)
{
if(!((Temp_WrtDt_Comm[i+4]&0x0f)<=0x09) && ((Temp_WrtDt_Comm[i+4]&0xf0)<=0x90))
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
return 1;
}
}
}
else
{
temp_num = CommandDataLength_Comm;
for(i=0;i<temp_num;i++)
{
if(!((Temp_WrtDt_Comm[i]&0x0f)<=0x09) && ((Temp_WrtDt_Comm[i]&0xf0)<=0x90))
{
ErrByte_Comm.BYTE |= 0x01; //非法数据,置错误信息字
return 1;
}
}
}
return 0;
}
//编程密码比较
unsigned char Compare_sub_code(void)
{
unsigned char i;
for(i=0;i<4;i++)
{
if(RPassWd_Dtr[i] != Temp_WrtDt_Comm[i])
{
return 1;
}
}
return 0;
}
//写命令正常应答
void Nor_Write_Answer(void)
{
SignPrgrm = DI1DI0_Comm;
Prgrm_Accdnt = 1;
RxTxState_Comm = AtTxState_Comm; //置待发送状态
Txd_Fe_Cnt = 1;
TempCs_Comm = SioHead_Sub_Comm(); //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
Put_To_SIOBuffer(0x84); //写入从站正常应答控制码
TempCs_Comm+=(0x84);
Put_To_SIOBuffer(0x00); //写入数据域长度
Put_To_SIOBuffer(TempCs_Comm); //写入校验和CS
Put_To_SIOBuffer(0x16); //写入结束符0x16
End_Flg = 0x38; //发送完 触发end 显示
}
//计算周次
unsigned char GetDayofWeek(unsigned char *CurrentYear,unsigned char *Month,
unsigned char *Day)
{
unsigned char Table[13] = {0,0,3,3,6,1,4,6,2,5,0,3,5};
unsigned char AccValue;
unsigned int TempYear;
unsigned int Year;
Year = 2000 + Bcd_hex(*CurrentYear);
AccValue = 5; //2000.1.1是周6,这里的基准为了和日期对应取周5。
TempYear = 2000;
while(TempYear != Year)
{
if (((TempYear%4)==0) && ((TempYear%100)!=0) || ((TempYear%400)==0))
{
AccValue += 2;
}
else
{
AccValue += 1;
}
TempYear += 1;
}
if (Bcd_hex(*Month) > 2)
{
if (((TempYear%4)==0) && ((TempYear%100)!=0) || ((TempYear%400)==0))
{
AccValue += 1;
}
}
AccValue = AccValue + Table[Bcd_hex(*Month)];
AccValue = AccValue + Bcd_hex(*Day);
AccValue = AccValue % 7;
return AccValue;
}
/**********************************************************
广播冻结电量
***********************************************************/
void BroChkEng_frost(void)
{
F_BlckWrt_Eeprm(ELBrock_PPwrTtl_Dtr,RPPwrTtl_Dtr,0x04); //广播冻结电量
F_BlckWrt_Eeprm(ELBrock_Tm,&RTm_Dtr[1],0x02);
F_BlckWrt_Eeprm(ELBrock_Tm+2,&RDtWk_Dtr[1],0x03);
}
/**********************************************************
三、强制从站与主站时间同步,即广播校时处理
***********************************************************/
void CheckTime_Set(void)
{
unsigned char i;
for(i=0;i<3;i++) //为周次腾地方
{
Temp_WrtDt_Comm[6-i] = Temp_WrtDt_Comm[5-i];
}
Temp_WrtDt_Comm[3] = GetDayofWeek(&Temp_WrtDt_Comm[6],&Temp_WrtDt_Comm[5],
&Temp_WrtDt_Comm[4]); //计算周次
for(i=0;i<7;i++)
{
E2Buffer[i] = Temp_WrtDt_Comm[i];
}
ClbrtTm_Trig = 1; //显示时间
SetTm_Accdnt = 1;
SetDate_Accdnt = 1;
}
void CheckTime_Comm(void)
{
unsigned char i;
for(i=0;i<CommandDataLength_Comm;i++) //取出数据域数据
{
Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33;
CommandDataPointer_Comm++;
CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);
}
if(Judge_BCD() == 1) //非法数据
{
return;
}
if((Temp_WrtDt_Comm[0]>0x60) || (Temp_WrtDt_Comm[1]>0x60)||(Temp_WrtDt_Comm[2]>0x23))
{
return;
}
if((Temp_WrtDt_Comm[3]>0x31) || (Temp_WrtDt_Comm[4]>0x12))
{
return;
}
if(Progrm_Disp) //**编程开关打在编程禁止
{
CheckTime_Set(); //广播校时条件成立
}
else //编程开关未闭合
{
if(BrochkSec_Cnt < 0x13c680) //广播校时后秒计数器值大于60天
{
return;
}
if((Temp_WrtDt_Comm[5] != RDtWk_Dtr[3]) || (Temp_WrtDt_Comm[4] != RDtWk_Dtr[2])) //主站校时年、月与电表年、月不等
{
return;
}
if((RDtWk_Dtr[1] > Temp_WrtDt_Comm[3]) || ((RDtWk_Dtr[1] == Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] > Temp_WrtDt_Comm[2]))
||((RDtWk_Dtr[1] == Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] == Temp_WrtDt_Comm[2]) && (RTm_Dtr[1] > Temp_WrtDt_Comm[1]))
||((RDtWk_Dtr[1] == Temp_WrtDt_Comm[3]) && (RTm_Dtr[2] == Temp_WrtDt_Comm[2]) && (RTm_Dtr[1] == Temp_WrtDt_Comm[1]) &&(RTm_Dtr[0] > Temp_WrtDt_Comm[0])))
{
if((RDtWk_Dtr[1] * 86400 + RTm_Dtr[2] * 3600 + RTm_Dtr[1] * 60 + RTm_Dtr[0])
- (Temp_WrtDt_Comm[3] * 86400 + Temp_WrtDt_Comm[2] * 3600 + Temp_WrtDt_Comm[1] * 60 + Temp_WrtDt_Comm[0]) < 1500)
{
CheckTime_Set(); //广播校时条件成立
}
else
{
return;
}
}
else
{
if((Temp_WrtDt_Comm[3] * 86400 + Temp_WrtDt_Comm[2] * 3600 + Temp_WrtDt_Comm[1] * 60 + Temp_WrtDt_Comm[0])
-(RDtWk_Dtr[1] * 86400 + RTm_Dtr[2] * 3600 + RTm_Dtr[1] * 60 + RTm_Dtr[0]) < 1500)
{
CheckTime_Set(); //广播校时条件成立
}
else
{
return;
}
}
}
}
/**********************************************************
四、写设备地址,即设置某从站的地址码处理
***********************************************************/
void WirteDevcNo_Comm(void)
{
unsigned char i;
Hello_Flg = 0x38; //通信协议解析成功;触发 Hello 显示
if ( ! Progrm_Disp) //**编程开关打在编程禁止
{
return;
}
for(i=0;i<CommandDataLength_Comm;i++) //取出数据域数据
{
Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33;
CommandDataPointer_Comm++;
CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);
}
if(Judge_BCD() == 1) //非法数据
{
return;
}
for (i=0;i<6;i++)
{
RMtNo_Dtr[i] = Temp_WrtDt_Comm[i];
}
if(F_BlckWrt_Eeprm(EMtNo_Dtr,&Temp_WrtDt_Comm[0],6))
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
Prgrm_Accdnt = 1; //记录编程事件
SignPrgrm = 0xc033;
RxTxState_Comm = AtTxState_Comm; //置待发送状态
Txd_Fe_Cnt =1;
TempCs_Comm = SioHead_Sub_Comm(); //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
Put_To_SIOBuffer(0x8A); //写入从站正常应答控制码
TempCs_Comm += (0x8A);
Put_To_SIOBuffer(0x00); //写入数据域长度
Put_To_SIOBuffer(TempCs_Comm); //写入校验和CS
Put_To_SIOBuffer(0x16); //写入结束符0x16
End_Flg = 0x38; //发送完 触发end 显示
}
/**********************************************************
五、写密码处理
***********************************************************/
void AmendCode_Comm(void)
{
unsigned char i;
Hello_Flg = 0x38; //通信协议解析成功;触发 Hello 显示
for(i=0;i<CommandDataLength_Comm;i++) //取出数据域数据
{
Temp_WrtDt_Comm[i] = *CommandDataPointer_Comm-0x33;
CommandDataPointer_Comm++;
CommandDataPointer_Comm = Bufferl_Tail_OP(CommandDataPointer_Comm);
}
if(Judge_BCD() == 1) //非法数据
{
return;
}
for(i=0;i<4;i++) //与原密码比较
{
if(Temp_WrtDt_Comm[i] != RPassWd_Dtr[i])
{
return;
}
}
if(Temp_WrtDt_Comm[4] != 0) //新密码权限必须为0
{
return;
}
for (i=0;i<4;i++) //写数据,RAM
{
RPassWd_Dtr[i] = Temp_WrtDt_Comm[4+i];
}
if(F_BlckWrt_Eeprm(EPassWd_Dtr,RPassWd_Dtr,4))//写数据,E2
{
RMtWd_Dtr[0] &= 0xfd; //存储芯片无错
}
else
{
RMtWd_Dtr[0] |= 0x02; //存储芯片出错
}
RxTxState_Comm = AtTxState_Comm; //置待发送状态
Txd_Fe_Cnt = 1;
TempCs_Comm = SioHead_Sub_Comm(); //向通讯缓冲区内写入DLT/645 协议头,返回协议头的校验和
Put_To_SIOBuffer(0x8F); //写入从站正常应答控制码
TempCs_Comm += 0x8F;
Put_To_SIOBuffer(0x04); //写入数据域长度
TempCs_Comm += 0x04;
for(i=0;i<4;i++) //写入数据
{
Put_To_SIOBuffer(Temp_WrtDt_Comm[4+i]+0x33);
TempCs_Comm += (Temp_WrtDt_Comm[4+i]+0x33);
}
Put_To_SIOBuffer(TempCs_Comm); //写入校验和CS
Put_To_SIOBuffer(0x16); //写入结束符0x16
End_Flg = 0x38; //写正确,显示end
Prgrm_Accdnt = 1; //记录编程事件
SignPrgrm = 0xcd12;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -