📄 zhubo.c
字号:
uchar bufver;//接收到的版本号
if(receive_over == 1)//如果接收完毕(包头,包尾都收到)
{
length = receive_cnt - 2;
//if(Prmter1.TYPE != receive_buf[1]) //判断协议类型
// if(TYPE != receive_buf[1]) //判断协议类型
// {
// send_reply_flag(0x10,0x00);//协议类型错误
// goto go_return;
// }
if((Prmter1.ADDR != receive_buf[4]) && (receive_buf[4] != 0xff))//模块地址错(0xff为广播群发)0X00为没有设置地址
{
goto go_return; //模块地址不符合,没返回
}
dog();
bufver=receive_buf[2] & 0x0f;//取缓冲数组的第二个字节的低4位字节,高4位是信息来源
//if(Prmter1.PROTL_ETN != bufver)//协议版本号判断
if(bufver!= PROTL)//协议版本号判断
{
send_reply_flag(0x02,0x00);//0X02表示版本错误
goto go_return;
}
if(receive_buf[7] > 69) //命令体长度不能大于69
{
send_reply_flag(0x05,0x00);
goto go_return;
}
if(receive_buf[6]!= 0xff) //命令头应答标志错
{
send_reply_flag(0x06,0x00);
goto go_return;
}
length = receive_buf[7] + 7; //长度=命令体长度+……(不包括起始、结束、ASCII校验这4个字节)
start = 1;
CheckCRC(receive_buf,length,start,pChecksum);
buf1 = length + 1;
if((pChecksum[0] != receive_buf[buf1]) || (pChecksum[1] != receive_buf[buf1+1]))//CRC检验判断
{
send_reply_flag(0x03,0x00);
goto go_return;
}
if(receive_buf[5] == 0x40)//查询基本参数
{
buf = Query_Basic_Parameter();//模块基本信息参数查询
send_reply_flag(0x00,buf);//发送成功标志
goto go_return;
}
if(receive_buf[5] == 0x60)//设置基本信息项
{
buf = Set_Basic_Parameter();//模块基本信息参数设置
if(erro&0x02)//设置出错
{
receive_buf[6] = 0x07;
erro = erro & 0xfd;
}
else
{
receive_buf[6] = 0x00;
}
send_reply_flag(receive_buf[6],buf);
goto go_return;
}
if(receive_buf[5] == 0xc1)//设置参数
{
buf = Set_Parameter();//设置参数
if(erro&0x02)//设置出错
{
receive_buf[6] = 0x07;
erro = erro & 0xfd;
}
else
{
receive_buf[6] = 0x00;
}
send_reply_flag(receive_buf[6],buf);
goto go_return;
}
else if(receive_buf[5] == 0xc2)//查询参数
{
buf = Query_Parameter();
if(erro&0x01)//查询出错
{
receive_buf[6] = 0x08;
erro = erro & 0xfe;
}
else
{
receive_buf[6] = 0x00;
}
send_reply_flag(receive_buf[6],buf);
goto go_return;
}
else if(receive_buf[5] == 0x50)//查询模块参数地址
{
buf = Query_Address();
send_reply_flag(0x00,buf);
goto go_return;
}
else
{
send_reply_flag(0x09,0x00); //命令编号错
goto go_return;
}
}
else if(receive_over == 0 && receive_time_on == 1)
{
if(receive_time_count >= 200)
{
headend_flag=0x00;
tran_flag=0x00;
receive_time_on = 0;
receive_time_count = 0;
receive_free();
receive_cnt = 0x00;
CREN = 1;
RCIE = 1;
return;
}
else
{
receive_time_count++;
return;
}
}
// T1CON=0x31;
return;
go_return:
headend_flag=0x00;
tran_flag=0x00;
receive_free();
receive_over = 0;
receive_cnt = 0;
CREN = 1;
RCIE = 1;
// T1CON=0x31;
return;
}
/**********************************************************
** 功能说明: 基本数据查询函数
** 输入参数: 无
** 输出参数:
** 返 回 值: 参数个数
** 引用函数:
*********************************************************/
uchar Query_Basic_Parameter()
{
uchar buf;
uchar i ;
uint j ;
j = 0x0700;
buf=receive_buf[8];//BUF为上位机下传的第几包数据;命令体的第1个字节为我应传给上位机第几包数据
receive_buf[8]=2;//PIC需上传总包数为2包;所以命令体的第1个字节变成了总包数.
if(buf==1)
{
receive_buf[9]=1;//表示PIC发送第1包数据
for(i=0; i<32; i++)
{
receive_buf[i+10] = basic_table[i];
}
return 34;
}
else if(buf==2)//
{
receive_buf[9]=2;//表示PIC发送第2包数据
for(i=0; i<37; i++)
{
receive_buf[i+10] = rrom(j + i);
}
return 39;
}
else
{
return 0;
}
}
/**********************************************************
** 功能说明: 基本信息参数设置函数
** 输入参数: 无
** 输出参数:
** 返 回 值: 参数个数
** 引用函数:
*********************************************************/
uchar Set_Basic_Parameter()
{
auto union buf_union comm;
uint i;
uchar length;
uchar buf;
uchar *P = 0;
length = receive_buf[7];
P = receive_buf+8;
erro = 0;
while(length)
{
comm.buf2[0] = *P++;
comm.buf2[1] = *P++;
length = length - 2 ;
switch(comm.buf1)
{
case 0xf000: //模块ID号
for(i=0;i<10;i++)
{
buf=*P++;
// dog();
wrom(mod_idadd+2+i,buf);
}
length=length-10;
break;
case 0xf002: Prmter1.ADDR=*P++ ;//模块地址
wrom(mod_add_add+2,Prmter1.ADDR);
length--;
break;
case 0xf019: //生产序列号
for(i=0;i<20;i++)
{
buf=*P++;
// dog();
wrom(product_add+2+i,buf);
}
length=length-20;
break;
default: receive_buf[9] = *--P;
receive_buf[8] = *--P;
erro = erro | 0x02;
length = 0;
break;//特殊处理
}
}
if(erro & 0x02)
{
length = 2;//设置参数失败
}
else
{
length = receive_buf[7];
}
return length;
}
/**********************************************************
** 功能说明: 参数地址查询函数
** 输入参数: 无
** 输出参数:
** 返 回 值: 参数个数
** 引用函数:
*********************************************************/
uchar Query_Address()
{
uchar i,buf;
uchar length;
buf = receive_buf[8];
switch(buf)
{
case 1: for(i=0; i<Para_Num; i++)
{
receive_buf[i+8]= Para_Num_Conf[i];
}
length = Para_Num;
break;
default: receive_buf[8] = buf;
length = 1;
break;
}
return length;
}
/**********************************************************
** 功能说明: 参数设置函数
** 输入参数: 无
** 输出参数:
** 返 回 值: 参数个数
** 引用函数:
*********************************************************/
uchar Set_Parameter()
{
auto union buf_union comm;
uchar length;
// char buf;
// uchar buff1;
// uchar buff2;
// uchar buf1,buf2;
uchar*P = 0;
erro=0x00;
length = receive_buf[7];
P = receive_buf+8;
while(length)
{
comm.buf2[0] = *P++;
comm.buf2[1] = *P++;
length = length - 2 ;
// buff1=comm.buf2[0];
// buff2=comm.buf2[1];
switch(comm.buf1)
{
case poffset1: Prmter1.POFFSET1=*P++ ;
wrom(poff1add,Prmter1.POFFSET1);
length--;
break;
case poffset2: Prmter1.POFFSET2=*P++ ;
wrom(poff2add,Prmter1.POFFSET2);
length--;
break;
default: receive_buf[9] = *--P;
receive_buf[8] = *--P;
erro = erro | 0x02;
length = 0;
break;//特殊处理
}
}
if(erro & 0x02)
{
length = 2;//设置参数失败
}
else
{
length = receive_buf[7];
}
return length;
}
/**********************************************************
** 功能说明: 参数查询函数
** 输入参数: 无
** 输出参数:
** 返 回 值: 参数个数
** 引用函数:
*********************************************************/
uchar Query_Parameter()
{
auto union buf_union comm;
//uchar length,erro;
uchar length;
uchar * P1 = 0;
erro = 0;
P1 = receive_buf+8;
length = receive_buf[7];
//receive_buf[4] = 0x00;
while(length)
{
comm.buf2[0] = *P1++;
comm.buf2[1] = *P1++;
length = length - 2;
switch(comm.buf1)
{
case pofu: *P1++ = Prmter1.POFU ;
*P1++ = 0 ;
length=length-2;
break;
case poru : *P1++ = Prmter1.PORU ;
*P1++ = 0 ;
length=length-2;
break;
case pof: *P1++ = Prmter1.POF ;
length--;
break;
case por : *P1++ = Prmter1.POR ;
length--;
break;
case poffset1: *P1++=Prmter1.POFFSET1 ;
length--;
break;
case poffset2: *P1++=Prmter1.POFFSET2;
length--;
break;
//case SWR_dn : *P1++ = Prmter1.SWR ;
// length--;
// break;
//case temp: *P1++ = Prmter1.TEMPL;
// length--;
// *P1++ = Prmter1.TEMPH;
// length--;
// break;
default: receive_buf[9] = *--P1;
receive_buf[8] = *--P1;
erro = erro | 0x01;
length = 0;
break;//特殊处理
}
}
if(erro & 0x01)
{
length = 2;//设置参数失败
//receive_buf[4] = 0x05;
}
else
{
length = receive_buf[7];
}
return length;
}
/**********************************************************
** 功能说明: 发送参数函数
** 输入参数: 类型: uchar 应答标志位
类型: uchar 命令体的长度
** 输出参数:
** 返 回 值: 无
** 引用函数:
*********************************************************/
void send_reply_flag(uchar reply_flag,uchar length)
{
auto uchar start,i;
receive_buf[7] = length;
receive_buf[6] = reply_flag;
start = 1; //CRC校验
length = length + 7;
CheckCRC(receive_buf,length,start,pChecksum);
receive_buf[length + 1] = pChecksum[0];
receive_buf[length + 2] = pChecksum[1];
length = length + 3;//加上校验字节(2BYTE),再加一个字节,就为包的总长度-1
receive_buf[length] = 0x4e;//最后一个字节是包尾
portd_wbuf = portd_wbuf | 0x80; //485发送使能
PORTD = portd_wbuf;
TXEN = 1; //USART 使能
delay_unit(2000);
length = length + 1;
for(i = 0;i < length;i ++)
{
if((i==0)||(i==(length-1)))
{
TXREG = receive_buf[i];
}
else if(receive_buf[i]==0x5e)
{
TXREG = 0x5e;
receive_buf[i]=0x5d;
i--;
}
else if(receive_buf[i]==0x4e)
{
TXREG = 0x5e;
receive_buf[i]=0x4d;
i--;
}
else
{
TXREG = receive_buf[i];
}
while(TRMT == 0)
{
;
}
}
delay_unit(1000);
TXEN = 0;
portd_wbuf = portd_wbuf & 0x7f;
PORTD = portd_wbuf;
headend_flag=0x00;
tran_flag=0x00;
return;
}
/**********************************************************
** 功能说明: CRC校验函数
** 输入参数: 类型: uchar* 须校验的数组
类型: uchar 命令体的长度
类型: uchar 开始位置
类型: uchar* 校验配置表
** 输出参数:
** 返 回 值: 无
** 引用函数:
*********************************************************/
void CheckCRC(uchar *pData, uchar length,uchar start, uchar *pChecksum)
{
auto uchar i = 0;
auto uint checksum = 0;
for(i = 0;i < length;i ++)
{
checksum = ( checksum << 8) ^ CRCTable[( checksum >> 8 ) ^ pData[i + start]];
}
pChecksum[0] = checksum % 256;
pChecksum[1] = checksum / 256;
return;
}
/**********************************************************
** 功能说明: 接受数据数组的初始化
** 输入参数:
** 输出参数:
** 返 回 值: 无
** 引用函数:
***********************************************************/
void receive_free()
{
auto uchar i;
for(i = 0; i < BUF_LENGTH; i ++)
{
receive_buf[i] = 0;
}
}
/**********************************************************
** 功能说明: 中断处理子程序(包括接收中断、定时器中断)
** 输入参数:
** 输出参数:
** 返 回 值: 无
** 引用函数:
*********************************************************/
void interrupt int_process(void)
{
auto uchar i;
// uchar buf;
if(RCIF == 1) //USART接收中断标志位为1
{
if(portd_wbuf&0x80)//如果处于发送状态,返回主程序,不处理缓冲区中的数据
{
return;
}
if(receive_over == 1 )//如果接收完成标志为1,则接收完成,不再接收数据.
{
return;
}
if(receive_cnt > 79)//接收缓冲超过80个字节时,就为溢出,将接收缓冲重新计数
{
receive_time_on = 0;//接收超时定时器开关关闭
receive_time_count = 0;//接收超时定时计数器清零
receive_cnt = 0;//发送或接收的字节数清零.
for(i = 0; i < BUF_LENGTH; i++) //将接收缓冲清零
{
receive_buf[i] = 0;
}
return;
}
receive_buf[receive_cnt] = RCREG;
// if (receive_cnt==1)
// {
// buf=receive_buf[receive_cnt];
// }
if(receive_buf[receive_cnt] == 0x4E)//接收到的字节是包头或包尾
{
if(headend_flag==0x01)//判断接收到的是包头还是包尾,如果标志=1,则接收到过包头,现在接收到的是包尾;
{
headend_flag=0x02;//接收到的是包尾
}
if(headend_flag==0x00)//判断接收到的是包头还是包尾,如果标志=0,则接收到的是包头,之前没接收到包尾和包头;
{
receive_buf[0]=0x4E;
headend_flag=0x01;//接收到的是包头
receive_cnt = 0x01;//接收的字节数为1个.
receive_time_on = 0x01;//接收超时定时器开关打开
receive_time_count = 0x00;//接收超时定时计数器清零
// for(i = 0; i < BUF_LENGTH;i++)//将接收缓冲清零
// {
// receive_buf[i] = 0;
// }
return;
}
}
else if(receive_buf[0] != 0x4E)//如果缓冲区接收到的第一个字节不是包头
{
receive_cnt = 0x00;//发送或接收的字节数清零.
receive_time_on = 0x00;//接收超时定时器开关关闭
receive_time_count = 0x00;//接收超时定时计数器清零
return;
}
if((receive_buf[receive_cnt-1] == 0x5E)&&(tran_flag==0x00))//接收到转义字节0x5E
{
// tran_flag=0x01;
if (receive_buf[receive_cnt] == 0x4D)//0X5E的转义处理
{
receive_buf[receive_cnt-1] =0X4E;
tran_flag=0x01;//完成转义处理
//receive_cnt--;
return;
}
else if(receive_buf[receive_cnt]==0x5D)//0X5E的转义处理
{
tran_flag=0x01;//完成转义处理
receive_buf[receive_cnt-1]=0x5E;
//receive_cnt--;
return;
}
else //说明接收错误,返回
{
tran_flag=0x00;
headend_flag=0x00;
receive_time_on = 0;//接收超时定时器开关关闭
receive_time_count = 0;//接收超时定时计数器清零
receive_cnt = 0;//发送或接收的字节数清零.
return;
}
}
receive_cnt++;
if(headend_flag==0x02)//接收到了包头和包尾,并且没有接收到转义字节0X5E或转义处理已完成
{
tran_flag=0x00;
headend_flag==0x00;//包头包尾标志清零
receive_time_on = 0;//接收超时定时器开关关闭
receive_time_count = 0;//接收超时定时计数器清零
receive_over = 1;//接收完成标志置1
RCIE = 0;//接收允许标志位清零,不允许接收
CREN = 0;
return;
}
}
else if(TMR1IF == 1)
{
chushi++;
// if (chushi<=0x0d6b)
// {
TMR1IF=0;
// }
return;
}
else if(TMR2IF == 1)
{
// i= 100;
TMR2IF =0;
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -