1107.c
来自「电能表源码」· C语言 代码 · 共 1,319 行 · 第 1/3 页
C
1,319 行
// StartTranUData(vno+5);
//}
/*
FLASH写操作
入口参数:
von-----操作个数
*tp-----目标地址指针,需要写数据的目标地址
*vp-----写数据时的数据源起始指针
*/
//void WFLASH(uint8 vno,uint8 code *tp,uint8 xdata *vp)
//{
// uint8 code *point;
// uint8 xdata *p;
// uint8 i;
//
// point = tp;
// p = vp;
//#ifdef DEF_TBUFF_STRUCTURE
// for(i = 0; i < vno; i++)
// { // 填写data
// TransBuff[i] = *p;
// p++;
// }
//#else
// Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
// for(i = 0; i < vno; i++)
// { // 填写data
// *(Ubuff[DEFTBUFF].pbuff+i) = *p;
// p++;
// }
//#endif
// if(WState)
// { // 处在编程允许状态
// #ifdef DEF_TBUFF_STRUCTURE
// TransBuff[i] = ACK;
// #else
// *(Ubuff[DEFTBUFF].pbuff+i) = ACK;
// #endif
// p = vp;
// for(i = 0; i < vno; i++)
// {
// IAP_FLASH_ByteWrite((uint16)point,*p);
// point++;
// p++;
// }
// StartTranUData(vno+1);
// }
// else
// { // 处在编程禁止状态
// #ifdef DEF_TBUFF_STRUCTURE
// TransBuff[i+0] = SOH;
// TransBuff[i+1] = 'B';
// TransBuff[i+2] = '0';
// TransBuff[i+3] = ETX;
// TransBuff[i+4] = 0x71; // BCC
// #else
// *(Ubuff[DEFTBUFF].pbuff+i+0) = SOH;
// *(Ubuff[DEFTBUFF].pbuff+i+1) = 'B';
// *(Ubuff[DEFTBUFF].pbuff+i+2) = '0';
// *(Ubuff[DEFTBUFF].pbuff+i+3) = ETX;
// *(Ubuff[DEFTBUFF].pbuff+i+4) = 0x71;
// #endif
// StartTranUData(vno+5);
// }
//}
///*
// 读RAM数据
// 入口参数:
// von-----操作个数
// *tp-----目标地址指针,需要读数据的目标地址
// 出口参数: 直接通过串口发送给外部
//*/
//void RRAM(uint8 vno,uint8 xdata *tp)
//{
// uint8 xdata *point;
// uint8 xdata *p;
// uint8 i,bcc;
//
// point = tp;
// Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
// *Ubuff[DEFTBUFF].pbuff = STX;
// *(Ubuff[DEFTBUFF].pbuff+1) = '(';
// p = Ubuff[DEFTBUFF].pbuff+2;
// bcc = '(';
// for(i = 0; i < vno; i++)
// {
// *p = *point;
// bcc ^= *point;
// p++;
// point++;
// }
// *(Ubuff[DEFTBUFF].pbuff+2+vno) = ')';
// bcc ^= ')';
// *(Ubuff[DEFTBUFF].pbuff+3+vno) = ETX;
// bcc ^= ETX;
// *(Ubuff[DEFTBUFF].pbuff+4+vno) = bcc;
// StartTranUData(vno+5);
//}
///*
// RAM写操作
// 入口参数:
// von-----操作个数
// *tp-----目标地址指针,需要写数据的目标地址
// *vp-----写数据时的数据源起始指针
//*/
//void WRAM(uint8 vi,uint8 xdata *tp,uint8 xdata *vp)
//{
// uint8 xdata *point;
// uint8 xdata *p;
// uint8 i,vno,cs;
// uint16 code *pAddr1;
// uint16 code *pAddr2;
//
// point = tp;
// p = vp;
// vno = InstList[vi].DLen;
//// pAddr1 = InstList[vi].WAddrA;
//// pAddr2 = InstList[vi].WAddrB;
// cs = 0;
// Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
// for(i = 0; i < vno; i++)
// { // 填写data
// *(Ubuff[DEFTBUFF].pbuff+i) = *p;
// p++;
// }
// if(WState)
// { // 处在编程允许状态
// *(Ubuff[DEFTBUFF].pbuff+i) = ACK;
// p = vp;
// for(i = 0; i < vno; i++)
// {
// *point = *p;
// cs += *p;
// point++;
// p++;
// }
// StartTranUData(vno+1);
// }
// else
// { // 处在编程禁止状态
// *(Ubuff[DEFTBUFF].pbuff+i+0) = SOH;
// *(Ubuff[DEFTBUFF].pbuff+i+1) = 'B';
// *(Ubuff[DEFTBUFF].pbuff+i+2) = '0';
// *(Ubuff[DEFTBUFF].pbuff+i+3) = ETX;
// *(Ubuff[DEFTBUFF].pbuff+i+4) = 0x71;
// StartTranUData(vno+5);
// }
//}
/*
数据处理
*//*
void CData1107(uint8 xdata *vp,uint8 vi)
{//
uint8 xdata *tp;
uint8 tlen,ttype,tleg,tadt;
uint16 taddr;
tlen = InstList[vi].DLen; // 数据长度
ttype = InstList[vi].US.bits.DT; // 数据存储格式
tleg = InstList[vi].IegAtr; // 数据合法类型
tadt = InstList[vi].US.bits.DAT; // 数据读地址属性
taddr = InstList[vi].DAddr; // 数据读地址
if(Recvrw == 'R')
{ // 读FLASH操作
RFLASH(InstList[i].DLen,tcp);
}
else if(Recvrw == 'W')
{ // 写FLASH操作
CheckIegInst(p,InstList[i].DLen,InstList[i].IegAtr);
WFLASH(InstList[i].DLen,tcp,p);
}
}*/
/*
指令检测
*/
char CheckInst(uint8 xdata *vp)
{
uint8 xdata *p; // 指向xdata空间的指针
uint8 code *tcp; // 指向code空间的指针
uint8 i,j,ti; // 循环变量
ti = MaxInst;
p = &InstArry[0];
for(i = 0; i < MaxInst; i++)
{
if(*(p+i) == '(')
{ // 记录下'('的位置
if(Recvrw == 'R')
{ // 接受到的读指令的格式为A.A.A*A()
// ti = i;
*(p+i) = '*';
ti = i + 1;
}
else if(Recvrw == 'W')
{ // 接受到的写指令的格式为A.A.A(D...)
*(p+i) = '*';
ti = i + 1;
}
}
}
for(i = ti; i < MaxInst; i++)
{ // 统一成A.A.A*A的标准模式
*(p+i) = 'A';
}
// 指令寻址
for(i = 0; i < TABLENUMBER; i++)
{
for(j = 0; j < MaxInst; j++)
{
tcp = &InstList[i].Inst[j];
p = &InstArry[j];
if(*p != *tcp)
break; // 有一个比对错误则退出当前子循环
}
if(j == MaxInst) // 说明全部比对成功
break; // 比对成功则退出大循环
}
if(i == TABLENUMBER) // 说明没有找到指令码
return -1; // 没有此条指令
else // 反之表示指令码匹配成功
{
InstPro.DF.value = InstList[i].InterInst; // 内部协议id号
InstPro.bufflen = InstList[i].DLen; // 数据长度
ListLen = i; // 记下内部通讯协议表位置
if(Recvrw == 'W')
{ // 数据格式转换
ti = InstPro.bufflen % 2; // 奇数个or偶数个
j = InstPro.bufflen / 2;
p = vp + ti + 4;
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
if(ti)
{ // 奇数个时先做一次变换
*Ubuff[DEFTBUFF].pbuff = ASC2BCD(0,*p);
Ubuff[DEFTBUFF].pbuff++;
p++;
}
for(i = ti; i < InstPro.bufflen; i+=2)
{
*Ubuff[DEFTBUFF].pbuff = ASC2BCD(*(p+i),*(p+1+i));
Ubuff[DEFTBUFF].pbuff++;
}
InstPro.pbuff = Ubuff[DEFTBUFF].buffadd;// 数据指针
InstPro.bufflen = j + ti; // 数据长度
InstPro.CtrlByte = 1+InstList[i].IA; // 写操作
}
else if(Recvrw == 'R')
{ // 数据指针
InstPro.pbuff = Ubuff[DEFTBUFF].buffadd+2;
InstPro.CtrlByte = 0; // 读操作
}
}
return 0;
}
/*
状态机复位指令检测
*/
char CheckReset(uint8 xdata *vp,uint8 vlen)
{
uint8 xdata *p;
// uint8 xdata *pBPS;
uint8 i;
p = vp;
for(i = 0; i < vlen; i++)
{
if(*p == SOH && *(p+1) == 'B' && *(p+2) == '0' && *(p+3) == ETX && *(p+4) == 0x71)
{
UMS.bits.PS = 0; // 状态机复位
FHead[0] = '/';
FHead[1] = SOH; // 第一个有效字符
UMS.bits.FRBA = 0; // 接受处理完毕,再次开放接受缓存
Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
Ubuff[DEFRBUFF].buffplen = 0;
// SwitchBPS(UARTSERI,0);
InstPro.CtrlByte = 0x10;// 波特率归零
CfgEU(UARTSERI,300,10,0);
//*pBPS = 0;
//InstPro.pbuff = pBPS;
//InstPro.bufflen = 1;
UDS.bits.UMOD = 0;
return 0; // 找到匹配项
}
p++;
}
return -1; // 没有找到匹配项
}
/*
帧校验
入口参数 val_buffno----需要校验的缓存号
*/
char CheckFram1107(uint8 val_buffno)
{
uint8 i,j,tlen;
uint8 xdata *p;
// uint8 xdata *pBPS;
// uint8 xdata tempbuff[20];
i = 0;
j = -2; // 初始化
tlen = Ubuff[val_buffno].buffplen;
p = Ubuff[val_buffno].pbuff;
i = CheckReset(p,tlen);
if(i) // 如果不是复位状态机指令
{
switch(UMS.bits.PS)
{
case 0: // 握手状态机
i = Step0Cp1107(p,tlen);
if(i != -1)
{ //
Step0ACK1107(); // 握手成功,发送建议通讯波特率,转入下一个状态机
UTest = 0x01;
}
else
{
UMS.bits.FRBA = 0; // 接受处理完毕,再次开放接受缓存
Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
Ubuff[DEFRBUFF].buffplen = 0;
UTest = 0x11;
UDS.bits.UMOD = 0;
}
break;
case 1: // 波特率确认状态机
i = Step1Cp1107(p,tlen);
if(!i)
{ // 匹配成功处理
UTest = 0x02;
UDS.bits.CBPS = UDS.bits.RBPS; // 将使用波特率修改为推荐波特率
// SwitchBPS(UARTSERI,UDS.bits.CBPS); // 切换波特率
CfgEU(UARTSERI,300*(1+UDS.bits.CBPS),10,0);
//InstPro.CtrlByte = 0x10;
//*pBPS = UDS.bits.CBPS;
//InstPro.pbuff = pBPS;
//InstPro.bufflen = 1;
//j = 0;
Step1ACK1107(); // 请求密码,转入下一个状态机
//RecvBuffA[0] = 0;
}
else if(i == -1)
{ // 波特率不匹配,使用300bps
UTest = 0x12;
UDS.bits.CBPS = 0;
Step1ACK1107(); // 请求密码,转入下一个状态机
//RecvBuffA[0] = 0;
}
else if(i == -2)
{ // 帧解析错误
UTest = 0x22;
NAK_NERR(); // 返回 1,'B','0',3,BCC
}
break;
case 2: // 密码认证状态机
i = Step1Cp1107(p,tlen);
if(!i)
{ // 匹配成功处理
UTest = 0x03;
Step1ACK1107(); // 请求密码,转入下一个状态机
break;
}
i = Step2Cp1107(p,tlen);
if(!i) // 密码匹配成功,转入下一个状态机(数据通讯阶段)
{
UTest = 0x13;
Step2ACK1107(); // 返回 ACK
}
else if(i == -1) // 数据帧错误
{
UTest = 0x23;
NAK_NERR(); // 返回 1,'B','0',3,BCC
}
else if(i == -2) // BCC错误
{
UTest = 0x33;
ERO_NERR(); // 返回ERO标识
}
break;
case 3: // 数据通讯状态机
i = Step3Cp1107(p,tlen);
if(!i) // 匹配成功,进行指令操作
{
i = CheckInst(p); // 指令操作
UTest = 0x04;
if(i == -1) // 无此指令
{
UTest = 0x14;
RET_NAK(); // 回复错误
}
else
{
j = 0; // 数据帧通讯请求
}
}
else if(i == -1) // 数据帧错误
{
UTest = 0x24;
RET_NAK(); // 返回NAK指令
}
else if(i == -2) // BCC错误
{
UTest = 0x34;
ERO_NERR(); // 返回ERO标识
}
break;
default:
UMS.bits.PS = 0; // 如果遇到状态机不在上述范围,则复位状态机
UTest = 0x05;
break;
}
}
// else
// { // 当是复位指令时提起应用层需要波特率切换
// j = 0;
// }
return j;
}
/*
规约解析函数
出口参数: -1---没有接受到数据
0----数据解析完成且正确,用户可通过InstPro结构体获得解析结果
-2---数据解析完成但错误,用户可不需要操作
*/
char G1107Pro(void)
{
if(UDS.bits.UMOD == 4)
{
Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
UMS.bits.FRBA = 1; // 缓存数据准备就绪
return(CheckFram1107(0));
}
else
{
return -1;
}
}
#undef _PRO1107_C_
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?