📄 rxd.c
字号:
接收文件rxd.c
#include "ModBus.h"
/******************************************************************/
StrRxd xdata sys_rxd; //定义接收处理结构体
/******************************************************************/
/*******公有函数***************************************************/
void init_proc_rxd(void); //初始化串口通信变量
void process_rxd(void); //通信处理函数
void init_serial(void); //初始化串口
/*******私有函数***************************************************/
uint8 read_sys_rxd(void); //读接收缓冲区
uint8 data_check(void); //校验和检验
uint8 lenghchk(void); //数据长度检验
void data_change(void); //数据ASCII转换成HEX
/******************************************************************/
void init_proc_rxd(void)
{
uint8 idata i;
for( i = 0;i < POOLLEN;i++ )
{
sys_rxd.pool[i] = 0;
sys_rxd.rec_buf[i] = 0;
sys_txd.pool[i] = 0;
sys_txd.combuf[i] = 0;
}
for( i = 0;i < 16;i++ )
{
sys_rxd.add_buf[i] = 0;
}
sys_rxd.front = 0;
sys_rxd.rear = 0;
sys_rxd.frm_num = 0;
sys_rxd.rd_byte = 0;
sys_rxd.start_0x7e = 0;
sys_rxd.end_0x0d = 0;
sys_txd.txd_len = 0;
}
/*****************************************************************/
uint8 read_sys_rxd(void)
{
if( sys_rxd.rear == sys_rxd.front )
{
return WRONG;
}
else
{
sys_rxd.rd_byte = sys_rxd.pool[sys_rxd.front];
sys_rxd.front = (sys_rxd.front+1) % POOLLEN;
return RIGHT;
}
}
/*****************************************************************/
uint8 data_check(void)
{
uint8 add_len,temp;
uint8 i,j,k,fram_temp;
uint16 chk_sum,chk_sum_temp;
fram_temp = sys_rxd.frm_num;//如何防止在处理数据的同时新的中断使该值变化
add_len = 0;
if( fram_temp )//接收的一帧完整数据
{
fram_temp -= 1;
j = sys_rxd.add_buf[fram_temp * 2];
k = sys_rxd.add_buf[fram_temp * 2 + 1];
if(k > j)
{
add_len = k-j;
}
else
{
add_len = (POOLLEN - j ) + k;//地址确认
}
sys_rxd.front = j;
chk_sum = 0;
for( i = 0;i < add_len - 4;i++ ) //4 byte is chuck sum
{
read_sys_rxd(); //the poionter is add1
if( sys_rxd.rd_byte == FRAME_START )
{
sys_rxd.rd_byte = 0;
}
chk_sum += sys_rxd.rd_byte;
}
chk_sum = (~chk_sum) + 1;
chk_sum_temp = 0;
for(i=0;i<4;i++)
{
read_sys_rxd();
temp = sys_rxd.rd_byte;
if(temp > 0x40)
{
temp -= 0x37; // get the hex valume
}
else
{
temp -= 0x30;
}
chk_sum_temp += temp;
if( i < 3 )
{
chk_sum_temp = chk_sum_temp << 4;
}
}
if( chk_sum_temp == chk_sum )
{
return RIGHT;
}
else
{
return WRONG;
}
}
else
{
return WRONG;
}
}
/*****************************************************************/
uint8 lenghchk(void) //数据长度检验
{
uint8 link_sum,link_sum_temp;
uint8 add_len;
uint8 j,k,fram_temp;
if( sys_rxd.rec_buf[4] != lchksum(sys_rxd.rec_buf[5]) )
{
return WRONG;
}
fram_temp = sys_rxd.frm_num; //如何防止在处理数据的同时新的中断使该值变化
if ( fram_temp == 0 )
{
return WRONG;
}
fram_temp--;
j = sys_rxd.add_buf[fram_temp*2];
k = sys_rxd.add_buf[fram_temp*2+1];
if(k>j)
{
add_len = k-j;
}
else
{
add_len = ( POOLLEN - j ) + k;
}
link_sum_temp = (add_len - 17);
link_sum = sys_rxd.rec_buf[5];
if(link_sum != link_sum_temp)
{
return WRONG;
}
else
{
return RIGHT;
}
}
/*****************************************************************/
void data_change(void)
{
uint8 add_len;
uint8 i,j,k,temp1,fram_temp;
uint8 temp;
fram_temp = sys_rxd.frm_num; //如何防止在处理数据的同时新的中断使该值变化
if ( fram_temp == 0 )
{
return;
}
fram_temp--;
j = sys_rxd.add_buf[fram_temp*2];
k = sys_rxd.add_buf[fram_temp*2+1];
if(k>j)
{
add_len = k-j;
}
else
{
add_len = ( POOLLEN - j ) + k;
}
add_len = add_len / 2 + 1; //cup down 2 byte chksum
sys_rxd.front = j;
for(i = 0;i < add_len;i++ )
{
read_sys_rxd(); //the poionter is add1
if (sys_rxd.rd_byte == 0x0d)
{
sys_rxd.rec_buf[i] = 0xaa;
sys_rxd.rec_buf[i+1]=0x55;
return;
}
if (sys_rxd.rd_byte == 0x7e)
{
read_sys_rxd();
}
temp = sys_rxd.rd_byte;
if(temp>0x40)
{
temp-=0x37;
}
else
{
temp -=0x30;
}
temp = temp<<4;//高4位
read_sys_rxd();//the poionter is add1
temp1 = sys_rxd.rd_byte;
if(temp1>0x40)
{
temp1-=0x37;
}
else
{
temp1-=0x30;
}
sys_rxd.rec_buf[i] = temp+temp1; // include ver/adr/cid1/cid2/length/info
}
}
/*****************************************************************/
void process_rxd(void) //接收缓冲区中的数据 入处理缓冲区
{
while(sys_rxd.frm_num)
{
if(data_check() == WRONG)
{
sys_rxd.add_buf[sys_rxd.frm_num*2] = 0;
sys_rxd.add_buf[sys_rxd.frm_num*2+1] =0;
sys_rxd.frm_num --;
txd_uni(0x02); //校验和错误
return;
}
data_change();
if( (sys_rxd.rec_buf[1] == ADDR ) ) //地址正确
{
if( lenghchk() ==WRONG ) //长度校验
{
sys_rxd.add_buf[sys_rxd.frm_num*2] = 0;
sys_rxd.add_buf[sys_rxd.frm_num*2+1] =0;
sys_rxd.frm_num --;
txd_uni(0x03); //长度校验错误
return;
}
if(sys_rxd.rec_buf[0] != VER)
{
sys_rxd.add_buf[sys_rxd.frm_num*2] = 0;
sys_rxd.add_buf[sys_rxd.frm_num*2+1] =0;
sys_rxd.frm_num --;
txd_uni(0x01); //版本错
return;
}
if( (sys_rxd.rec_buf[2] != M_CID)) //设备ID错
{
sys_rxd.add_buf[sys_rxd.frm_num*2] = 0;
sys_rxd.add_buf[sys_rxd.frm_num*2+1] =0;
sys_rxd.frm_num--;
txd_uni(0xe1); //设备ID错
return;
}
switch(sys_rxd.rec_buf[3])
{
case 0x44:
txd_sta();
break;
case 0x4f:
txd_uni(0x4f); //发送通讯协议版本号
break;
case 0x50:
txd_uni(0x50); //发送设备地址
break;
case 0x51:
txd_man(); //发送设备厂家信息
break;
case 0x60:
txd_uni(0x60); //系统初始化
break;
default:
txd_uni(0x04); //无效命令
break;
}
}
sys_rxd.frm_num--;
}
}
/*****************************************************************/
void init_serial(void)
{
//串行口波特率等设置
TMOD=0x21; // T1 mode 2 T0,mode 1 //GATE C/T M1 M0 GATE C/T M1 M0
TL1=0xfa; // 0xfa=4800 bps 0xfd=9600 bps 0xe8 = 1200 0xf4 = 2400
TH1=0xfa;
TH0=-(10000/256);
TL0=-(10000%256);
PCON=0; //波特率不变等设置
SCON=0x50; //串口1方式1,允许接收
IT0=1; //外部中断0下降沿有效
IT1=1; //外部中断1下降沿有效
TR0=1; //启动定时器0
TR1=1; //启动定时器1
ET0=1; //开放定时器0中断
ES=1; //串行中断
EX0=0; //外部中断0
EX1=1; //外部中断1
EA=1; //开总中断
// RS485EN = 0;
}
/*****************************************************************/
void serial_uart(void) interrupt 4
{
uchar idata temp;
uchar idata num;
if(RI)
{
RI = 0;
temp = SBUF;
if( sys_rxd.start_0x7e && (temp != FRAME_END) )
{
sys_rxd.pool[sys_rxd.rear] = temp;
sys_rxd.rear = (sys_rxd.rear + 1) % POOLLEN;
return;
}
else
{
if( (temp ^ FRAME_START)==0 ) //如果接收到包起始位
{
if( (sys_rxd.start_0x7e) && (sys_rxd.end_0x0d) )
{
sys_rxd.rear = sys_rxd.add_buf[num];
}
else
{ //第一次接收到起始位
sys_rxd.start_0x7e = 1;
sys_rxd.end_0x0d = 1;
num = sys_rxd.frm_num * 2; //新的一帧的起始地址下标
sys_rxd.add_buf[num] = sys_rxd.rear; //起始地址保存
}
sys_rxd.pool[sys_rxd.rear] = temp;
sys_rxd.rear=(sys_rxd.rear+1) % POOLLEN;
return;
}
else
{
if( sys_rxd.start_0x7e && ( temp == FRAME_END ) )
{
sys_rxd.end_0x0d = 0;
sys_rxd.start_0x7e = 0;
sys_rxd.pool[sys_rxd.rear] = temp;
sys_rxd.rear = (sys_rxd.rear+1) % POOLLEN;
num = sys_rxd.frm_num*2+1;//结束地址位
if(sys_rxd.rear==0) //对于POOLLEN不是255的时候,如果直接-1做尾地址。肯定造成尾地址错误。因为 0-1=255
{
sys_rxd.add_buf[num] = POOLLEN - 1;//在写进后的地址已加上1
}
else
{
sys_rxd.add_buf[num] = sys_rxd.rear-1;//在写进后的地址已加上1
}
sys_rxd.frm_num++;//增加一帧//成功才加一位
sys_rxd.frm_num = sys_rxd.frm_num % 16;
return;
}
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -