📄 rscomm.c
字号:
Write24C64(&ComBuf[RS_CmdPtr+6],0x08,0x88,3);
EryBln_Flag = 1; //电能结算
break;
}
case 0xC1BB://时钟偏置
{
if(RX8025_CC==0x01) Temp[0] = 0x7F;
else if(RX8025_CC==0x02) Temp[0] = 0x7E;
else if(RX8025_CC==0x03) Temp[0] = 0x7D;
else Temp[0] = 0x00;
RTC_Set(0x70,Temp,1);
Temp[1] = ~Temp[0];
Write24C64(Temp,0x08,0xFE,2);
break;
}
case 0xC32F://时区起始日期及日时段表号数据块
{
ComBuf[RS_CmdPtr+6+6] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],3);
ComBuf[RS_CmdPtr+6+7] = ~SumCHK(&ComBuf[RS_CmdPtr+6+3],3);
Write24C64(&ComBuf[RS_CmdPtr+6],0x09,0x47,8);
Fee_Flag = 1; //置位费率检查标志
EryBln_Flag = 1; //电能结算
break;
}
case 0xC33F:
case 0xC34F://时段表1、2时段起始日期及费率号数据块
{
addr1 = 0x00;
if(RS_CmdL==0x3F) addr2 = 0x60;
else if(RS_CmdL==0x4F) addr2 = 0x80;
else break;
ComBuf[RS_CmdPtr+6+24] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],24);
Write24C64(&ComBuf[RS_CmdPtr+6],addr1,addr2,25);
Fee_Flag = 1; //置位费率检查标志
EryBln_Flag = 1; //电能结算
break;
}
/////////////////////////////////////////////////////////////////////////
case 0xC212://修改密码
{
if(ComBuf[12]<=ComBuf[16]) //密级判断,高级可修改低级
{
ComBuf[20] = ~SumCHK(&ComBuf[17],3); //新密码的校验和
//addr0 = 0xA0;
addr1 = 0x08;
addr2 = 0x58; //编程密码
if(ComBuf[16]==0x00) addr2 = 0x54; //清零密码
Write24C64(&ComBuf[17],addr1,addr2,4);
}
else //密级不对,非法数据
{
ErrInfFlag = 0xAA; //通讯错误信息标志
ErrInfStat = 0x01;
RS_Len =0x01;
TimeProg= 0; //无编程事件
}
break;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
case 0xC818://清过程(清事件)
{
ClearEvenFlag = 1;
break;
}
/////////////////////////////////////////////////////////////////////////
case 0xD400://自动显示数据域
{
ComBuf[RS_CmdPtr+6+3] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],3);
Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0x50,4);
DspDataReadFlag = 1; //读显示控制参数标志置位
break;
}
case 0xD403://电表管理状态
{
Temp[0] = ComBuf[RS_CmdPtr+6+0]&0x03;
if(Temp[0]==0x00) isNewState = 0x80; //新进,启动36小时计时
else isNewState = 0x00;
ComBuf[RS_CmdPtr+6+1]=~ComBuf[RS_CmdPtr+6+0];
Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0xEE,2);
break;
}
case 0xD404://检定人代码和检定时间
{
Write24C64(&ComBuf[RS_CmdPtr+6],0x00,0xF0,6);
break;
}
case 0xD415://时段表切换及标志
{
//读取上次切换方式标志字节
Read24C64(&Temp[2],0x09,0x40,1);
Temp[3] = ~Temp[2];
//写本次时段表切换及标志
ComBuf[RS_CmdPtr+6+6] = ~SumCHK(&ComBuf[RS_CmdPtr+6+0],6);
Write24C64(&ComBuf[RS_CmdPtr+6],0x09,0x40,7);
//********************************************************
Temp[0] = 0x00; //清按编号切换完成标志
Temp[1] = 0xFF;
Write24C64(Temp,0x09,0x53,4);
//********************************************************
Fee_Flag = 1; //置位费率检查标志
EryBln_Flag = 1; //电能结算
break;
}
//自定义命令
case 0x230A://产品条形码1(低30字节)
{
Write24C64(&ComBuf[16],0x09,0xC0,30);
break;
}
case 0x230B://产品条形码2(高30字节)
{
Write24C64(&ComBuf[16],0x09,0xE0,30);
break;
}
case 0x230C://电表表号
{
ComBuf[22] = ~SumCHK(&ComBuf[16],6); //表号检验和
//用户号、局编号地址(资产条形码后8位)
Write24C64(&ComBuf[16],0x00,0xF7,7);
break;
}
default://数据项标识错
{
ErrInfFlag = 0xAA; //通讯错误信息标志
ErrInfStat = 0x02;
RS_Len =1;
TimeProg= 0; //无编程事件
}
}
}
else //编程开关无效
{
Flag &= ~0x0A;
//TxdFlag = 0; //不回应
//TimeProg = 0; //无编程事件
}
}
}
//**********************************************************
//名称: void LCDView(void)
//功能: LCD显示屏查看
//说明:
//**********************************************************
void LCDView(void)
{
Flag &= 0xE0;
DspPtr = RS_CmdF; //查询页指针
if( (DspPtr>21)&&(DspPtr<26) || (DspPtr>46) )
{
DspPtr = 0x00; //查询页指针出错处理
LCDShowMode = 0;//正常轮显模式
}
else
{
LCDShowMode = 1; //查询模式
LCDViewSec = LCDViewTime; //液晶显示屏查看时间
CommLCDSec = 1; //查询时液晶不闪
}
}
//**********************************************************
//名称: uchar RxdCheck(void)
//功能: 通讯帧格式及通讯地址检查
//说明:
//**********************************************************
uchar RxdCheck(void)
{
uchar i,CodeN,ErrorMeterAddrFlag=0;
uchar Address[7];
//帧长度、帧结构检查
if(ComPtr<RS_MinSize || RS_Head!=0x68 || RS_Head0!=0x68 || RS_End!=0x16) return(0x00);
//校验错误
if( RS_CRC!=SumCHK(ComBuf,RS_CmdPtr+RS_Len)) return(0x00);
Read24C64(Address,0x00,0xF7,7); //用户号、局编号地址(资产条形码后8位)
i = SumCHK(Address,6); //表号检验和
if(Address[6]!=~i) ErrorMeterAddrFlag = 0xFF; //读表号出错
CodeN = 0x00;
if( RS_Addr0==0x99 && RS_Addr1==0x99 && RS_Addr2==0x99 &&
RS_Addr3==0x99 && RS_Addr4==0x99 && RS_Addr5==0x99 )
{
if(RS_Ctrl==RS_CTRL_Time) CodeN=0x10; //广播校时
//else if( RS_Ctrl==RS_CTRL_MetID && Prog_Flag==1 ) return(0x11); //广播设置电表号
else CodeN=0x00; //广播命令码错误
}
//局号符合(包含缩位寻址)
else if( (RS_Addr0==Address[0]||RS_Addr0==0xAA) && (RS_Addr1==Address[1]||RS_Addr1==0xAA) &&
(RS_Addr2==Address[2]||RS_Addr2==0xAA) && (RS_Addr3==Address[3]||RS_Addr3==0xAA) &&
(RS_Addr4==Address[4]||RS_Addr4==0xAA) && (RS_Addr5==Address[5]||RS_Addr5==0xAA) )
{
if(RS_Ctrl==RS_CTRL_Read) CodeN=0x21; //读数据
else
{
if((RS_Addr0==0xAA) && (RS_Addr1==0xAA) && (RS_Addr2==0xAA)
&&(RS_Addr3==0xAA) && (RS_Addr4==0xAA) && (RS_Addr5==0xAA))
{
if(RS_Ctrl==RS_CTRL_Write)
{
//表号初始化,通过万能表号进行写操作
if( (RS_CmdL==0x3F) && (RS_CmdH==0x56) && (ComBuf[12]==0x33) && (ComBuf[13]==0x56)
&&(ComBuf[14]==0x3C) && (ComBuf[15]==0xC7) )
{
CodeN=0x22; //写数据
ErrorMeterAddrFlag = 0x00; //
//表号数据去0x33处理
i = 0;
do
{
Address[i] = ComBuf[16+i]+0xCD;
i++;
}while(i<6);
}
//群清
if( (RS_CmdH==0x07) && (RS_CmdL==0x43) && (ComBuf[12]==0x33) && (ComBuf[13]==0x56)
&&(ComBuf[14]==0x3C) && (ComBuf[15]==0xC7) )
{
CodeN=0x22; //写数据
ErrorMeterAddrFlag = 0x00; //
}
}
else CodeN=0x00; //万能表号不允许写操作
}
else if(RS_Ctrl==RS_CTRL_Write) CodeN=0x22; //写数据
else if(RS_Ctrl==RS_CTRL_Pswd) CodeN=0x20; //修改密码(高级可修改低级)
else CodeN=0x00;
}
}
else CodeN=0x00; //地址身份不符合,错误不响应
for(i=6;i>0;--i) //构建返回表号
{
ComBuf[i] = Address[i-1];
}
if(ErrorMeterAddrFlag!=0) CodeN = 0x00; //
return(CodeN);
}
//**********************************************************
//名称:uchar PsWdCHK(uchar PsWdPtr)
//功能:
//说明:
//**********************************************************
uchar PsWdCHK(uchar PsWdPtr)
{
uchar PassWord[4];
if(ComBuf[PsWdPtr]>0x01) return 0x00; //权限错误
//为扩展的自定义命令(设置表号,产品条形码)提供操作权限
//(RS_CmdL==0x0C)||(RS_CmdL==0x0B)||(RS_CmdL==0x0A)
else if( (RS_CmdH==0x23)&&(ComBuf[PsWdPtr+0]==0x00)&&(ComBuf[PsWdPtr+1]==0x23)
&&(ComBuf[PsWdPtr+2]==0x09)&&(ComBuf[PsWdPtr+3]==0x94) )
{
return 0x10; //清零密码
}
else if( (RS_CmdH==0xD4)&&(ComBuf[PsWdPtr+0]==0x00)&&(ComBuf[PsWdPtr+1]==0x23)
&&(ComBuf[PsWdPtr+2]==0x09)&&(ComBuf[PsWdPtr+3]==0x94) )
{
return 0x10; //清零密码
}
else
{
//0x58--->编程密码地址 / 0x54--->清零密码地
Read24C64(PassWord,0x08,0x54+ComBuf[PsWdPtr]*4,3);
//密码比较
if( ComBuf[PsWdPtr+1]==PassWord[0] && ComBuf[PsWdPtr+2]==PassWord[1] && ComBuf[PsWdPtr+3]==PassWord[2] )
{
if(ComBuf[PsWdPtr]==0x00) return 0x10; //清零密码
else return 0x11; //编程密码
}
else return 0x00; //密码错误
}
}
//**********************************************************
//名称: TimeTerm()
//功能: 时间条件检查
//说明: 当编程开关打在"编程允许时",可用掌上机向时钟写入任意
// 时间。当编程开关打在"编程禁止时",只能对于误差在5分钟
// 之内的电表,进行对时。
//**********************************************************
bit TimeTerm(void)
{
uchar MinSum1;
uchar MinSum2;
//时间数据正确性检查
if(TimeCHK(&ComBuf[RS_CmdPtr+6])==0) return(0);
//30天判断
AdjDate = DateTerm();
//编程条件检查
//if(Prog_Flag==1) return(1); //编程允许
//else
//{
if(AdjDate==1) //30天判断
{
//不允许跨日校时
if((Hour==0x00 && ComBuf[RS_CmdPtr+6+2]==0x23)||
(Hour==0x23 && ComBuf[RS_CmdPtr+6+2]==0x00)) return(0);
//时间误差计算
if(abs(BCD2HEX(Hour)-BCD2HEX(ComBuf[RS_CmdPtr+6+2]))>1) //小时条件检查
{
//AdjTime = 1; //时钟异常
return(0);
}
else
{
//相差1小时之内
MinSum1 = BCD2HEX(Min); //分
MinSum2 = BCD2HEX(ComBuf[RS_CmdPtr+6+1]);
if(Hour>ComBuf[RS_CmdPtr+6+2]) MinSum1 += 60;
if(Hour<ComBuf[RS_CmdPtr+6+2]) MinSum2 += 60;
if(abs(MinSum1-MinSum2)>=TimeErrorTerm) //大于时间条件,5分钟
{
return(0);
}
else
{
return(1); //满足校时误差条件
}
}
}
else return(0); //不满足30天条件
//}
}
//**********************************************************
//名称: Proc33()
//功能: 加减0x33H处理
//说明: 数据去0x33处理----0xCD ; 数据加0x33处理----0x33
//**********************************************************
void Proc33(uchar procdata)
{
uchar i;
i=0x00;
do
{
ComBuf[RS_CmdPtr+i] += procdata;
i++;
}while(i<RS_Len);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -