1107.c
来自「电能表源码」· C语言 代码 · 共 1,319 行 · 第 1/3 页
C
1,319 行
FHead[0] = ACK;
// FHead[1] = SOH; // 第一个有效字符
}
/*
状态机为1时接受波特率的确认信息
入口参数: vp----需要被比对的数据首地址指针
vlen--需要被比对的数据项长度
出口参数: 0-----匹配成功
-1----波特率不匹配
-2----数据帧不匹配
*/
char Step1Cp1107(uint8 xdata *vp,uint8 vlen)
{
uint8 xdata *p;
uint8 i,ti,ifok;
ifok = -1; // 开始时默认不匹配
p = &ACKBPS[2];
*p = UDS.bits.RBPS + 0x30; // 填入波特率
p = vp;
for(i = 0; i < vlen; i++)
{
if(*p == ACK && *(p+1) == '0')
{
ifok = 0; // 找到首地址了,默认匹配
ti = i;
break;
}
p++;
}
if(ifok != 0) // 连首地址都无法找到,说明匹配失败
return -1; // 返回匹配失败
for(i = 0; i < vlen-ti; i++)
{
if(*p != ACKBPS[i])
{
ifok = i; // 记录下出错地址(由于寻找首地址时的判断,前2个位置不可能错误)
}
p++;
}
if(ifok == 0) // 匹配成功
return 0; // 返回匹配成功
else if(ifok == 2) // 表示出错的仅是波特率
return -1; // 波特率错误
else
return -2; // 数据帧错误
}
/*
*/
void Step1ACK1107(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = SOH;
*(Ubuff[DEFTBUFF].pbuff++) = 'P';
*(Ubuff[DEFTBUFF].pbuff++) = '0';
*(Ubuff[DEFTBUFF].pbuff++) = STX;
*(Ubuff[DEFTBUFF].pbuff++) = '(';
*(Ubuff[DEFTBUFF].pbuff++) = ')';
*(Ubuff[DEFTBUFF].pbuff++) = ETX;
*Ubuff[DEFTBUFF].pbuff = 0x60;
StartTranUData(8);
UMS.bits.PS = 2; // 转入下一个状态机
// FHead[0] = ACK;
FHead[1] = SOH; // 第一个有效字符
}
/*
状态机为2时接受密码请求
入口参数: vp----需要被比对的数据首地址指针
vlen--需要被比对的数据项长度
出口参数: 0-----匹配成功
-1----数据帧不匹配
-2----BCC不匹配
*/
char Step2Cp1107(uint8 xdata *vp,uint8 vlen)
{
uint8 xdata *p;
uint8 xdata *tp;
uint8 i,ti,ifok;
ifok = -1; // 开始时默认密码不匹配
p = vp;
for(i = 0; i < vlen; i++)
{
if(*p == SOH && *(p+1) == 'P')
{
ifok = 0; // 找到首地址了,默认匹配
ti = i;
break;
}
p++;
}
if(ifok != 0) // 连首地址都无法找到,说明匹配失败
return -1; // 返回匹配失败
// ifok = *(p+2); // 获取Y数值*******打印文档上没有这一项********
tp = &MeterCode[7];
// GetMeterCode(p,ifok); // 获取密码******打印文档上默认只有一个密码*******
GetMeterCode(tp,1); // 获取密码
for(i = 0; i < vlen-ti; i++)
{
if(*p != MeterCode[i])
{
// if(i == 2 || i == 15) // 将第3个和第15个数据填入数组
if(i == 15) // 将第15个数据填入数组
{
MeterCode[i] = *p;
continue;
}
else // 非第3个和15个数据错误视为数据帧错误
{
return -1; // 数据帧匹配不成功
}
}
p++;
}
// 对BCC进行校验
ifok = MeterCode[1];
for(i = 2; i < 15; i++)
{ // 计算BCC
ifok ^= MeterCode[i];
}
if(ifok != MeterCode[15])
return -2; // BCC匹配失败
else
return 0; // BCC匹配成功
}
/*
*/
void Step2ACK1107(void)
{
UMS.bits.PS = 3; // 转入下一个状态机
// FHead[0] = ACK;
FHead[1] = SOH; // 第一个有效字符
RET_ACK();
}
/*
状态机为3时接受通讯信息
入口参数: vp----需要被比对的数据首地址指针
vlen--需要被比对的数据项长度
出口参数: 0-----匹配成功
-1----数据帧不匹配
-2----BCC不匹配
*/
char Step3Cp1107(uint8 xdata *vp,uint8 vlen)
{
uint8 xdata *p;
uint8 i,ti,ifok;
ifok = -1; // 开始时默认不匹配
p = vp;
for(i = 0; i < vlen; i++)
{
if(*p == SOH && *(p+2) == '1' && *(p+3) == STX)
{
ifok = 0; // 找到首地址了,默认匹配
ti = i;
break;
}
p++;
}
if(ifok != 0) // 连首地址都无法找到,说明匹配失败
return -1; // 返回匹配失败
Recvrw = *(p+1); // 读操作 or 写操作
for(i = 0; i < MaxInst; i++)
{ // A.A.A*A信息记录,最大数据量为MaxInst(*.h文件中定义)
InstArry[i] = *(p+4+i);
}
for(i = 0; i < vlen-10; i++)
{ // 全帧检测ETX,当前p指向首地址
if(*(p+10+i) == ETX)
{ // 从第12个开始为数据项
ifok = 1; // 检测到ETX,表示正确
break;
}
}
if(!ifok) // 没有检测到ETX
return -1; // 返回帧错误
// 对BCC进行校验
ifok = *(p+1);
p = p+2;
for(; *p != ETX; p++)
{ // 计算BCC
ifok ^= *p;
}
ifok ^= *p;
if(ifok != *(p+1)) // *p=ETX,*(p+1)=BCC
return -2; // BCC匹配失败
else
return 0; // BCC匹配成功
}
///*
// 大小月,闰月,星期匹配
//*/
//char CheckCalendar(uint8 yy,uint8 mm,uint8 dd,uint8 ww)
//{
// uint8 i,FD;
// uint16 daycc;
//
// FD = 28;
// if(yy%4 == 0) // 表示为闰年
// {
// FD = 29;
// }
// switch(mm)
// { // 大小月及闰月判断
// case 1: // 大月
// case 3:
// case 5:
// case 7:
// case 8:
// case 10:
// case 12:
// if(dd > 31)
// return -1;
// break;
// case 4: // 小月
// case 6:
// case 9:
// case 11:
// if(dd > 30)
// return -1;
// break;
// case 2: // 闰月
// if(dd > FD)
// return -1;
// break;
// default:
// return -2;
// break;
// }
//// 星期判断
// // 输入需要比对时间计算
// daycc = (yy*365) + (yy/4);
// if(yy%4)
// daycc++;
// for(i = 1; i < mm; i++)
// {
// if(i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
// {
// daycc += 31;
// }
// else if(i == 4 || i == 6 || i == 9 || i == 11)
// {
// daycc += 30;
// }
// else if(i == 2)
// {
// daycc += FD;
// }
// }
// daycc += dd;
// daycc = daycc - 2; // 2000.01.02 是星期日
// if(daycc%7 != ww)
// return -1;
// return 0;
//}
///*
// 大小月,闰月匹配判断,不包含星期匹配
//*/
//char CheckCalendarWithoutWeek(uint8 yy,uint8 mm,uint8 dd)
//{
// uint8 FD;
//
// FD = 28;
// if(yy%4 == 0) // 表示为闰年
// {
// FD = 29;
// }
// switch(mm)
// { // 大小月及闰月判断
// case 1: // 大月
// case 3:
// case 5:
// case 7:
// case 8:
// case 10:
// case 12:
// if(dd > 31)
// return -1;
// break;
// case 4: // 小月
// case 6:
// case 9:
// case 11:
// if(dd > 30)
// return -1;
// break;
// case 2: // 闰月
// if(dd > FD)
// return -1;
// break;
// default:
// return -2;
// break;
// }
// return 0;
//}
///*
// 常规判断('0' ~ '9')
//*/
//char CheckNormal(uint8 xdata *vp,uint8 vno)
//{
// uint8 i;
//
// for(i = 0; i < vno; i++)
// {
// if(*(vp+i) <= '0' || *(vp+i) >= '9')
// {
// return -1; // 数据不合法
// }
// }
// return 0;
//}
///*
// 数据合法性检查
// 入口参数: *vp-----被检测的数据首地址
// vno-----被检测的数据长度
// vlgw----数据的检测方法
// 出口参数: 0-------数据合法
// -1------数据不合法
// -2------校验方法出错
//*/
//char CheckIegInst(uint8 xdata *vp,uint8 vno,uint8 vlgw)
//{
// uint8 vyy,vmm,vdd,vww,vhh,vmi;//,vss;
//// uint8 i;
//
// if(CheckNormal(vp,vno) != 0)
// return -1; // 数据不合法
// switch(vlgw)
// {
// case 0: // 普通校验
// break;
// case 1: // 长度6;格式hhmmss
// if(ASC2HEX(*(vp+0),*(vp+1)) >= 24)
// return -1; // 数据不合法
// if(ASC2HEX(*(vp+2),*(vp+3)) >= 60)
// return -1; // 数据不合法
// if(ASC2HEX(*(vp+0),*(vp+1)) >= 60)
// return -1; // 数据不合法
// break;
// case 2: // 长度8;格式YYMMDDWW
// vyy = ASC2HEX(*(vp+0),*(vp+1));
// vmm = ASC2HEX(*(vp+2),*(vp+3));
// vdd = ASC2HEX(*(vp+4),*(vp+5));
// vww = ASC2HEX(*(vp+6),*(vp+7));
// if(vyy >= 99)
// return -1; // 数据不合法
// if(vmm >= 13 || vmm == 0)
// return -1; // 数据不合法
// if(vdd >= 32 || vdd == 0)
// return -1; // 数据不合法
// if(vww >= 7)
// return -1; // 数据不合法
// if(CheckCalendar(vyy,vmm,vdd,vww) != 0)
// return -1; // 数据不合法
// break;
// case 3: // 清零当前需量及时间
// vyy = ASC2HEX(*(vp+6),*(vp+7));
// vmm = ASC2HEX(*(vp+8),*(vp+9));
// vdd = ASC2HEX(*(vp+10),*(vp+11));
// vhh = ASC2HEX(*(vp+12),*(vp+13));
// vmi = ASC2HEX(*(vp+14),*(vp+15));
// if(vyy >= 99)
// return -1; // 数据不合法
// if(vmm >= 13 || vmm == 0)
// return -1; // 数据不合法
// if(vdd >= 32 || vdd == 0)
// return -1; // 数据不合法
// if(vhh >= 24)
// return -1; // 数据不合法
// if(vmi >= 60)
// return -1; // 数据不合法
// break;
// case 4: // 抄表日DD
// vdd = ASC2HEX(*(vp+0),*(vp+1));
// if(vdd >= 32 || vdd == 0)
// return -1; // 数据不合法
// break;
// case 5: // 设置第1~8套
//// for(i = 4; i < vno; i += 6)
//// {
//// vhh
//// }
// break;
// default:
// return -2; // 无此校验方法
// break;
// }
// return 0; // 数据合法
//}
/*
FLASH读操作
入口参数:
von-----操作个数
*tp-----目标地址指针,需要读数据的目标地址
出口参数: 直接通过串口发送给外部
*/
//void RFLASH(uint8 vno,uint8 code *tp)
//{
// uint8 code *point;
// uint8 xdata *p;
// uint8 i,bcc;
//
// point = tp;
//#ifdef DEF_TBUFF_STRUCTURE
// TransBuff[0] = STX;
// TransBuff[1] = '(';
// p = &TransBuff[2];
//#else
// Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
// *Ubuff[DEFTBUFF].pbuff = STX;
// *(Ubuff[DEFTBUFF].pbuff+1) = '(';
// p = Ubuff[DEFTBUFF].pbuff+2;
//#endif
// bcc = '(';
// for(i = 0; i < vno; i++)
// {
// *p = *point;
// bcc ^= *point;
// p++;
// point++;
// }
//#ifdef DEF_TBUFF_STRUCTURE
// TransBuff[2+vno] = ')';
// bcc ^= ')';
// TransBuff[3+vno] = ETX;
// bcc ^= ETX;
// TransBuff[4+vno] = bcc;
//#else
// *(Ubuff[DEFTBUFF].pbuff+2+vno) = ')';
// bcc ^= ')';
// *(Ubuff[DEFTBUFF].pbuff+3+vno) = ETX;
// bcc ^= ETX;
// *(Ubuff[DEFTBUFF].pbuff+4+vno) = bcc;
//#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?