📄 pcm-rtx51.c
字号:
{
NODE = Ascii2Hex(&BuffCOM1[13]); //取命令节点号
switch(NODE) //按节点处相应处理
{
case 2: //节点2, 均浮充转换
{
*PtrD++ = Ascii2Hex(&BuffCOM1[15]); //存命令字
for(i = 1; i < 17; i++)
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 56: //模块开关机
case 60:
case 64:
case 78:
case 72:
case 76:
case 80:
case 84:
case 88:
case 92:
case 96:
case 100:
case 104:
case 108:
case 112:
{
*PtrD++ = Ascii2Hex(&BuffCOM1[15]); //存命令字
*PtrD++ = (NODE-52)/4; //存模块号
for(i = 1; i < 18; i++)
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 114: //交流高压阀值
case 115: //交流低压阀值
{
a_float.c[3] = Ascii2Hex(&BuffCOM1[15]);//转换成浮点数
a_float.c[2] = Ascii2Hex(&BuffCOM1[17]);
a_float.c[1] = Ascii2Hex(&BuffCOM1[19]);
a_float.c[0] = Ascii2Hex(&BuffCOM1[21]);
a_int.i = (uint)(a_float.f); //转换成int
AlarmParaChar[(NODE-114)*2] = a_int.c[1];
AlarmParaChar[(NODE-114)*2+1] = a_int.c[0];
*PtrD++ = 0x01;
BuffCmdSet[7] = 0x53;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 116: //直流输出高压告警阀值
case 117: //直流输出低压告警阀值
{
for(i = 0; i < 4; i++)
{
AlarmParaChar[(NODE-116)*4+4+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
}
*PtrD++ = 0x01;
BuffCmdSet[7] = 0x53;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 118: //环境温度过高阀值
{
AlarmParaChar[12] = Ascii2Hex(&BuffCOM1[15]);
*PtrD++ = 0x01;
BuffCmdSet[7] = 0x53;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 119:
case 120:
case 121:
{
for(i = 0; i < 4; i++)
{
AlarmParaChar[(NODE-135)*4+13+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
}
*PtrD++ = 0x01;
BuffCmdSet[7] = 0x53;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 122:
{
AlarmParaChar[25] = Ascii2Hex(&BuffCOM1[15]);
*PtrD++ = 0x01;
BuffCmdSet[7] = 0x53;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 123:
{
for(i = 0; i < 4; i++)
{
AlarmParaChar[26+i] = Ascii2Hex(&BuffCOM1[15+i*2]);
}
BuffCmdSet[7] = 0x53;
*PtrD++ = 0x01;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
case 124:
case 125:
case 126:
case 127:
case 128:
{
AlarmParaChar[NODE-124 + 30] = Ascii2Hex(&BuffCOM1[15]);
BuffCmdSet[7] = 0x53;
*PtrD++ = 0x01;
for(i = 0; i < 35; i++)
{
*PtrD++ = AlarmParaChar[i]; //存入命令串中
}
for(i = 1; i < 52; i++) //生成校验
{
p ^= BuffCmdSet[i];
sum += BuffCmdSet[i];
}
*PtrD++ = p;
*PtrD++ = (uchar)(sum&0xFF);
*PtrD++ = (uchar)((sum>>8)&0xFF);
*PtrD = 0x12;
break;
}
}
}
FlagCmdSet = 1;
os_switch_task();
}
}
/********************************************/
/** 运行状态显示及喂狗 **/
/********************************************/
void Task_LEDWDT(void) _task_ TASK_LEDWDT
{
while(1)
{
os_wait(K_TMO,50,0);
P3_5 = !P3_5;
P1_3 = !P1_3;
RXDTimeOut++;
if(RXDTimeOut > 50) //从设备接收数据超时
{
TR0 = 0; //禁止任务调度,等待复位
ET0 = 0;
EA = 0;
while(1);
}
TXDTimeOut++;
if(TXDTimeOut > 100) //上传数据超时
{
TR0 = 0; //禁止任务调度,等待复位
ET0 = 0;
EA = 0;
while(1);
}
os_switch_task();
}
}
/********************************************/
/** 串口1收发中断 **/
/********************************************/
void ISR_COM1(void) interrupt 2
{
uchar i;
static data uchar ch0,ch1,ch2,ch3,ch4;
i = IIR; //识别中断源
i = i & 0x0f;
switch (i)
{
case 2:
{
if(FlagCOM1AllOut)
{
for(i = 0; i < 100; i++); //有必要延时之后再启动接收
COM1_RXD_En();
return;
}
while((*PtrCOM1TXD != '\0') && (i < 16))
{
THR = *PtrCOM1TXD;
PtrCOM1TXD++;
i++;
}
if(*PtrCOM1TXD == '\0')
{
FlagCOM1AllOut = 1;
TXDTimeOut = 0; //清超时计时
}
break;
}
case 4: //接收区满
case 12: //超时
{
for(i = 0; i < 14; i++)
{
ch4 = ch3;
ch3 = ch2;
ch2 = ch1;
ch1 = ch0;
ch0 = RBR;
if((ch4 == 0x7E) && (ch3 == '2') && (ch2 == '0') && (ch1 == 'F') && (ch0 == PcmAddr[1])) //有效命令头
{
FlagCmdStart = 1; //命令开始标志
PtrCOM1RXD = BuffCOM1;
*PtrCOM1RXD++ = 0x7E;
*PtrCOM1RXD++ = '2';
*PtrCOM1RXD++ = '0';
*PtrCOM1RXD++ = 'F';
}
if(ch0 == 0x0D)
{
if(FlagCmdStart)
{
FlagCmdStart = 0; //清命令开始标志
isr_send_signal(TASK_COM1); //发送收到命令信号
}
}
*PtrCOM1RXD++ = ch0;
if(PtrCOM1RXD == (BuffCOM1 + MAX_NUM_COM1))
{
PtrCOM1RXD = BuffCOM1;
}
}
break;
}
}
}
/********************************************/
/** 串口2收发中断 **/
/********************************************/
void ISR_COM2(void) interrupt 4
{
uchar data c;
static FlagShift = 0; //换码标志
if(RI)
{
RI = 0;
c = SBUF;
if((c == 0x14) && (!FlagShift)) //收到换码标志
{
FlagShift = 1;
return;
}
if(FlagShift) //需要换码
{
FlagShift = 0;
*PtrCOM2RXD++ = ~c;
}
else
{
if(c == 0x10)
{
PtrCOM2RXD = BuffCOM2;
}
*PtrCOM2RXD++ = c;
if(c == 0x12)
{
isr_send_signal(TASK_DATA);
RXDTimeOut = 0; //清超时计时
}
}
}
else
{
TI = 0;
if(FlagCOM2AllOut) return; //发送完成
if(*PtrCOM2TXD != 0x12) //连续发送直至结束符
{
SBUF = *PtrCOM2TXD;
PtrCOM2TXD++;
}
else
{
FlagCOM2AllOut = 1; //置发送完成标志
SBUF = 0x12; //发送结束符
}
}
}
/********************************************/
/** COM1初始化 **/
/** 1.8432MHZ 19200BPS **/
/********************************************/
void COM1_Init()
{
P1_2 = 0; //16C550完成复位
LCR = 0x80; //DLAB
DLL = 0x06; //Divisor
DLM = 0x00;
LCR = 0x03; //字符长度为八位
IER = 0x03; //允许接收及发送中断
FCR = 0xC7; //每收到14字节产生接收中断
COM1_RXD_En(); //充许接收
}
/********************************************/
/** COM2初始化 **/
/** 定时器2作波特率发生器 **/
/** TH2,TL2初值如下: **/
/** 19200bps 0xFFEE, 9600bps 0xFFDC, **/
/** 4800bps 0xFFB8, 2400bps 0xFF70, **/
/** 1200bps 0xFEE0, **/
/********************************************/
void COM2_Init()
{
P1_2 = 1; //此处开始复位16C550,节约时间
SCON = 0x58;
RCAP2L = 0xE0;
RCAP2H = 0xFE;
TL2 = 0xE0;
TH2 = 0xFE;
T2CON = 0x34;
RCLK = 1;
TCLK = 1;
TR2 = 1;
RI = 0;
TI = 0;
ES = 1;
}
/********************************************/
/** CPU 初始化 **/
/********************************************/
void CPU_Init()
{
TMOD = 0x11;
TH0 = 0xEE;
TL0 = 0x00;
IP = 0x00;
ET0 = 1;
IE1 = 0;
EX1 = 1;
IT1 = 1;
EA = 1;
}
/********************************************/
/** 读取PCM地址 **/
/** 低位PCM设备号,由拨码开关设置 **/
/********************************************/
void Get_PcmAddr()
{
uchar t;
t = (P1 >> 4) & 0x0F;
PcmAddr[0] = 'F';
if(t < 10)
PcmAddr[1] = 0x30 + t;
else
PcmAddr[1] = 0x37 + t;
}
uchar code HEX_[]={"0123456789ABCDEF"};
/*********************************/
/* 转换一字节为连续的两Ascii码 */
/* 高位在前,低位在后 */
/*********************************/
void Hex2Ascii(uchar s, uchar *d)
{
*d++ = HEX_[(s >> 4) & 0x0F];
*d++ = HEX_[s & 0x0F];
}
void Int2Ascii(uint s, uchar *d)
{
*d++ = HEX_[(s >> 12) & 0x0F];
*d++ = HEX_[(s >> 8) & 0x0F];
*d++ = HEX_[(s >> 4) & 0x0F];
*d++ = HEX_[s & 0x0F];
}
/*********************************/
/* 连续的两Ascii码转换为一字节 */
/* 高位在前,低位在后 */
/*********************************/
uchar Ascii2Hex(uchar *pt)
{
uchar hex;
/********先处理高位*********/
if(*pt < 0x3A) //0~9
hex = *pt++ - 0x30;
else //A~F
hex = *pt++ - 0x37;
hex = hex << 4;
/********再处理高位*********/
if(*pt < 0x3A)
hex |= *pt - 0x30;
else
hex |= *pt - 0x37;
return hex;
}
bit Chk_Sum(uchar *s)
{
uint sum=0;
s++; //跳过SOI
while(*(s+4) != 0x0D) //除去chksum和EOI,其余相加
{
sum += *s++;
}
sum = sum % 0xFFFF; //生成校验码
sum = ~sum + 1;
/*****校验码存放顺序为先高字节,后低字节;先高位,后低位*****/
/***** 对比校验码 *****/
if(*s++ != HEX_[(sum >> 12) & 0x000F]) return 0;
if(*s++ != HEX_[(sum >> 8) & 0x000F]) return 0;
if(*s++ != HEX_[(sum >> 4) & 0x000F]) return 0;
if(*s++ != HEX_[sum & 0x000F]) return 0;
return 1; //正确
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -