1107.c
来自「电能表源码」· C语言 代码 · 共 1,319 行 · 第 1/3 页
C
1,319 行
#define _PRO1107_C_
//#include "var.h"
//#include "reg52.h"
#include "1107.h"
//uint8 ASC2HEX(uint8 vdin1,uint8 vdin2)
//{
// uint8 temp1,temp2;
//
// temp1 = vdin1 - 0x30;
// temp1 *= 10;
// temp2 = vdin2 - 0x30;
// temp1 += temp2;
// return temp1;
//}
uint8 ASC2BCD(uint8 vdin1,uint8 vdin2)
{
uint8 temp1,temp2;
temp1 = vdin1 - 0x30;
temp1 <<= 4;
temp2 = vdin2 - 0x30;
temp1 += temp2;
return temp1;
}
uint16 BCD2ASC(uint8 vdin)
{
uint16 temp16;
uint8 temp8;
temp8 = vdin & 0x0f;
temp8 += 0x30;
temp16 = temp8;
temp8 = vdin & 0xf0;
temp8 >>= 4;
temp8 += 0x30;
temp16 += (((uint16)temp8) << 8);
return temp16;
}
//#define DEBUG
/*
函数功能:波特率切换
入口: val_numb---串口号-----------2/3/4/5
val_bps----目标波特率-------1200bps/2400bps/4800bps/9600bps
出口: 1----设置成功
0----串口号出错
-2---波特率出错
注:目前支持串口方式为10位/11位;波特率支持1200bps,2400bps,4800bps,9600bps
*/
//char SwitchBPS(unsigned char val_numb,unsigned char val_bps)
//{
// unsigned char temp1,temp2;
// unsigned char xdata *point;//
// temp2 = 0;
////==================串口号定位================================
// if(val_numb > 5 || val_numb <2)
// {
// return 0; // 串口号找不到
// }
// point = 0x2820 + (8*(val_numb-2)); // TCONx
// *point &= ~0xa2; // clear T1M & SMOD & TR1
////==================波特率发生器模式设定======================
// point++; // TMODx
////==================串口波特率设定============================
// switch(val_bps)
// {
// case 0: temp1 = 0xc7;temp2 = 2;break; // T1M = 0,SMOD = 1;
// case 1: temp1 = 0xf2;temp2 = 3;break; // T1M = 0,SMOD = 0;
// case 2: temp1 = 0xab;break; // T1M = 1,SMOD = 0;
// case 3: temp1 = 0xab;temp2 = 1;break; // T1M = 1,SMOD = 1;
// case 4: temp1 = 0xeb;break; // T1M = 1,SMOD = 0;
// case 5: temp1 = 0xeb;temp2 = 1;break; // T1M = 1,SMOD = 1;
// default:return -2;break; // 波特率不支持
// }
// point += 2; // TH1
// *point = temp1;
// point += 2; // TL1
// *point = temp1;
////===================波特率加倍设定============================
// point -= 5; // TCONx
// if(temp2 == 0)
// {
// *point |= 0x20; // T1M = 1 波特率不加倍
// }
// else if(temp2 == 1)
// {
// *point |= 0x20 | 0x80; // T1M = 1 波特率加倍
// }
// else if(temp2 == 2)
// {
// *point |= 0x80; // T1M = 0 波特率加倍
// }
////===================开启波特率发生器==========================
// *point |= 0x02; // TR1 = 1;
// return 1;
//}
void Init_P1107(void)
{ // 接受缓存1初始化
Ubuff[DEFRBUFF].buffadd = RecvBuffA;
Ubuff[DEFRBUFF].bufflen = UBUFFLEN;
Ubuff[DEFRBUFF].buffplen = 0;
Ubuff[DEFRBUFF].pbuff = Ubuff[0].buffadd;
// Ubuff[DEFRBUFF].rpbuff = Ubuff[0].buffadd;
// 发送缓存初始化
Ubuff[DEFTBUFF].buffadd = RecvBuffA;
Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
Ubuff[DEFTBUFF].buffplen = 0;
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
// TransBuff[0] = 0x11;
// TransBuff[1] = 0x13;
// 底层规约状态初始化
UMS.bits.PS = 0;
UMS.bits.FRBS = 0;
UDS.bits.UMOD = 0;
UDS.bits.RBPS = 4; // 修改推荐使用的波特率
FHead[0] = '/';
FHead[1] = SOH;
// FEnd[0] = CR;
// FEnd[1] = ETX;
// UniC = 0;
}
/*
数据接受--当前默认uart3
*/
char RecvUpData(void)
{
uint8 xdata *point;
uint8 xdata *p;
#ifdef DEBUG
#else
if(UDS.bits.UMOD == 4 || UDS.bits.UMOD == 2)
return 1;
#endif
point = UARTADDR; // SBUF3
ACC = *point;
if(P)
{
UDS.bits.FByte = 1; // 字节校验错
return -1;
}
p = Ubuff[DEFRBUFF].pbuff;
*p = *point & 0x7f;
#ifdef DEBUG
Ubuff[DEFRBUFF].pbuff++;
Ubuff[DEFRBUFF].buffplen++;
#else
Ubuff[DEFRBUFF].pbuff++;
Ubuff[DEFRBUFF].buffplen++;
if(UDS.bits.UMOD == 3)
{
UDS.bits.UMOD = 4;
return 0;
}
if(*p == FHead[0] || *p == FHead[1])
{ // 接受到起始符
Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
*Ubuff[DEFRBUFF].pbuff = *p;
Ubuff[DEFRBUFF].pbuff++;
Ubuff[DEFRBUFF].buffplen = 1;
UDS.bits.UMOD = 1;
}
else if(*p == ETX || *p == CR)
{ // 接受到结束符
if(UDS.bits.UMOD == 1) // 并且已经启动了接受
{
UDS.bits.UMOD = 3; // 切换准备
}
else // 否则归零,视为无效数据
{
Ubuff[DEFRBUFF].pbuff = Ubuff[DEFRBUFF].buffadd;
Ubuff[DEFRBUFF].buffplen = 0;
}
}
#endif
return 0;
}
/*
数据发送--当前默认uart3
*/
char TranUpData(void)
{
uint8 xdata *point;
uint8 xdata *p;
if(Ubuff[DEFTBUFF].buffplen == 0)
{
UMS.bits.FRBA = 0; // 发送处理完毕,再次开放缓存用于接受
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
Ubuff[DEFTBUFF].buffplen = 0;
UDS.bits.UMOD = 0;
return 0; // 发送完毕
}
point = UARTADDR;
p = Ubuff[DEFTBUFF].pbuff;
ACC = *p;
*point = *p | ((uint8)P)<<7;
Ubuff[DEFTBUFF].pbuff++;
Ubuff[DEFTBUFF].buffplen--;
UDS.bits.UMOD = 2;
return 1; //还有数据发送
}
/*
启动数据发送--当前默认uart3
*/
void StartTranUData(uint8 vlen)
{
uint8 xdata *point;
uint8 xdata *p;
// Ubuff[DEFTBUFF].buffadd = TransBuff;
Ubuff[DEFTBUFF].bufflen = UBUFFLEN;
Ubuff[DEFTBUFF].buffplen = vlen;
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
UDS.bits.UMOD = 2; // 切换成发送模式
point = UARTADDR;
p = Ubuff[DEFTBUFF].pbuff;
ACC = *p;
*point = *p | ((uint8)P)<<7;
Ubuff[DEFTBUFF].pbuff++;
Ubuff[DEFTBUFF].buffplen--;
}
/*
出错返回复位指令
*/
void NAK_NERR(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = SOH;
*(Ubuff[DEFTBUFF].pbuff++) = 'B';
*(Ubuff[DEFTBUFF].pbuff++) = '0';
*(Ubuff[DEFTBUFF].pbuff++) = ETX;
*Ubuff[DEFTBUFF].pbuff = 0x71;
StartTranUData(5);
}
/*
出错返回
*/
void RET_NAK(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = NAK;
StartTranUData(1);
}
/*
正确应答
*/
void RET_ACK(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = ACK;
StartTranUData(1);
}
/*
ERO返回
*/
void ERO_NERR(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = SOH;
*(Ubuff[DEFTBUFF].pbuff++) = 'E';
*(Ubuff[DEFTBUFF].pbuff++) = '0';
*(Ubuff[DEFTBUFF].pbuff++) = ETX;
*Ubuff[DEFTBUFF].pbuff = 0x76;
StartTranUData(5);
}
/*
应用层调用接口,首先完成数据准备,然后启动发送数据
入口参数: value
0----读数据返回
1----写数据成功返回(编程允许)
2----写数据失败返回(编程不允许)
*/
void ReturnUData(uint8 value)
{
uint8 i,bcc;
uint8 rlen,tlen;
uint16 temp16;
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
if(!value) // 读数据返回
{ // 数据格式转换
rlen = InstPro.bufflen; // 转换源长度
tlen = InstList[ListLen].DLen; // 转换目标长度
for(i = 0; i < tlen; i+=2)
{
temp16 = BCD2ASC(*(Ubuff[DEFTBUFF].pbuff+2+rlen-(i/2)));
*(Ubuff[DEFTBUFF].pbuff+2+tlen-i) = (uint8)temp16;
*(Ubuff[DEFTBUFF].pbuff+1+tlen-i) = (uint8)(temp16>>8);
}
*(Ubuff[DEFTBUFF].pbuff++) = STX;
*(Ubuff[DEFTBUFF].pbuff++) = '(';
bcc = STX ^ '(';
for(i = 0; i < tlen; i++)
{
bcc ^= *Ubuff[DEFTBUFF].pbuff;
Ubuff[DEFTBUFF].pbuff++;
}
*(Ubuff[DEFTBUFF].pbuff++) = ')';
bcc ^= ')';
*(Ubuff[DEFTBUFF].pbuff++) = ETX;
bcc ^= ETX;
*Ubuff[DEFTBUFF].pbuff = bcc;
StartTranUData(tlen+5);
}
else if(value == 1) // 写数据成功返回
{
RET_ACK();
}
else if(value == 2) // 写数据失败返回
{
NAK_NERR();
}
}
/*
获取表号
默认表号必须存放在FLASH地址中,并且在指令表(InstList)的第1个位置就要出现
*/
void GetMeterSeri(uint8 xdata *rp)
{
uint8 code *p;
uint8 i;
p = InstList[0].DAddr;
for(i = 0; i < InstList[0].DLen; i++)
{
*rp = *p & 0x7f;
rp++;
p++;
}
}
/*
获取密码,将密码依次存放到rp指针指定的地址中去
默认密码必须存放在FLASH地址中,并且在指令表(InstList)的第2和第3个位置就要出现,分别为读密码和写密码
*/
void GetMeterCode(uint8 xdata *rp,uint8 vno)
{
uint8 code *p;
uint8 i;
p = InstList[vno].DAddr;
for(i = 0; i < InstList[vno].DLen; i++)
{
*rp = *p & 0x7f;
rp++;
p++;
}
}
/*
状态机为0时进行表号比对
入口参数: vp----需要被比对的数据首地址指针
vlen--需要被比对的数据项长度
出口参数: ifok
0-----表号匹配
1-----万能表号
-1----表号不匹配
*/
char Step0Cp1107(uint8 xdata *vp,uint8 vlen)
{
uint8 xdata *p;
uint8 xdata *tp;
uint8 i,ti,ifok;
// uint8 xdata MeterSeri[13] = {'/','?',0,0,0,0,0,0,0,0,'!',CR,LF};
// uint8 xdata AllSeri[5] = {'/','?','!',CR,LF};
ifok = -1; // 开始时默认表号不匹配
p = &MeterSeri[2];
GetMeterSeri(p); // 获取表号
p = vp;
for(i = 0; i < vlen; i++)
{
if(*p == '/' && *(p+1) == '?')
{
ifok = 0; // 找到首地址了,默认表号匹配
tp = p;
ti = i;
break;
}
p++;
}
if(ifok != 0) // 连首地址都无法找到,说明匹配失败
return -1; // 返回表示表号不匹配
for(i = 0; i < vlen-ti; i++)
{
if(*p != MeterSeri[i])
{
ifok = -1; // 匹配表号不成功
break;
}
p++;
}
if(ifok == 0) // 匹配表号成功
return 0; // 成功返回
p = tp;
for(i = 0; i < vlen-ti; i++)
{
if(*p != AllSeri[i])
{
return -1; // 返回匹配失败
}
p++;
}
return 1; // 如果没有返回匹配失败,则返回匹配成功,为万能表号
}
/*
*/
void Step0ACK1107(void)
{
Ubuff[DEFTBUFF].pbuff = Ubuff[DEFTBUFF].buffadd;
*(Ubuff[DEFTBUFF].pbuff++) = '/';
*(Ubuff[DEFTBUFF].pbuff++) = 'H';
*(Ubuff[DEFTBUFF].pbuff++) = 'L';
*(Ubuff[DEFTBUFF].pbuff++) = 'Y';
*(Ubuff[DEFTBUFF].pbuff++) = ' ';
*(Ubuff[DEFTBUFF].pbuff++) = UDS.bits.RBPS + 0x30; // 发送推荐使用的波特率
*(Ubuff[DEFTBUFF].pbuff++) = ' ';
*(Ubuff[DEFTBUFF].pbuff++) = 'L';
*(Ubuff[DEFTBUFF].pbuff++) = 'I';
*(Ubuff[DEFTBUFF].pbuff++) = 'M';
*(Ubuff[DEFTBUFF].pbuff++) = 'E';
*(Ubuff[DEFTBUFF].pbuff++) = 'S';
*(Ubuff[DEFTBUFF].pbuff++) = ' ';
*(Ubuff[DEFTBUFF].pbuff++) = 'V';
*(Ubuff[DEFTBUFF].pbuff++) = ' ';
*(Ubuff[DEFTBUFF].pbuff++) = '1';
*(Ubuff[DEFTBUFF].pbuff++) = '.';
*(Ubuff[DEFTBUFF].pbuff++) = '0';
*(Ubuff[DEFTBUFF].pbuff++) = CR;
*Ubuff[DEFTBUFF].pbuff = LF;
// UDS.bits.RBPS = 4; // 修改推荐使用的波特率
StartTranUData(20);
UMS.bits.PS = 1; // 转入下一个状态机
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?