📄 com.c
字号:
#define _com_
#include "general.h"
#include "state.h"
#include "protocol.h"
#define INLEN 0x32 //40,固定帧长10 的倍数为宜
uchar idata r_buf[INLEN/*+0x0a*/]; //接收缓冲区
uchar *p_wrecibuf=r_buf; //接收时缓冲区写入指针
uchar *p_rrecibuf=r_buf; //解析时缓冲区读出指针
uchar cnt_reci;
//uchar idata t_buf[32];
uchar *pSTX,*pETX; //定位帧头、帧尾指针
//uchar r_in,r_out,t_in,t_out; //FIFO
bit r_full,r_notempty; //标志:接收缓冲满、缓冲不空
bit f_stx_ok=0; //
bit f_etx_ok=0;
//f_rxbit f_etx=0;
///////////////////初始化///////////////////////////////////////////////////////
void init_com(void)
{
//Timer1
TMOD=0x20; /*定时器1工作方式2*/
TH1=0xfd; /*装253,波特率=9600bit/s*@11.0592MHz*/
TCON=0x40; //启动Timer1
//COM
//EA=0;
//TI=0;
SCON=0x50; //0101,串口工作方式1 SM2=0,REN=1,允许接收
//PCON=0x00;
//PS=1; //串口优先级
//buf
r_notempty=0;
r_full=0;
//r_out=t_in=t_out=0;
//r_in=1;
//IE
//ES=1;//开串口中断
//EA=1;//开中断
IE=0x90;
}
////////////////////////发送部分(非中断)//////////////////////////////////////////
void put_char(uchar ch){//发送一个字符,非中断方式
SBUF=ch;
while(TI==0);
TI=0; //查询硬件置位,发送完毕
}
void put_string(uchar *str,uchar strlen){//发送一个字符串,非中断方式,strlen长度,注意本案中是从数组 高位 开始送
uchar k=strlen;
do {
if(*(str+k-1)>=0&&*(str+k-1)<=9) put_char(*(str+k-1)+'0'); //数字码
else put_char(*(str+k-1)); //非数字
k--;
} while(k>0);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
void loadmsg(uchar *msg){ // 将字符串装入缓冲区子程序发
while((*msg!=0)&&((((t_in+1)^t_out)&0x1f)!=0)){ // 检查缓冲区满
t_buf[t_in]=*msg;
msg++;
t_in=++t_in&0x1f; // if t_in+1大于缓冲区0x1f,t_in=0
if (t_done){ // 启动发送
TI=1;
t_empty=0;
t_done=0;
}
}
}
*/
///////////////////////////接收部分(中断)///////////////////////////////////////
void serial_int() interrupt 4 using 1{
if (RI&~r_full){ // 接收并且接收缓冲区未满 ,full就不再收了
//uchar ch;
//ch=SBUF;
RI=0;
//if(SBUF=FR_STX){
*p_wrecibuf=SBUF; // 接收数据写入
r_notempty=1;
if(p_wrecibuf==(r_buf+INLEN-1)) p_wrecibuf=r_buf;//循环
else p_wrecibuf++;
//cnt_reci++;
if (p_wrecibuf==p_rrecibuf) r_full=1; // 置缓冲区满标志
//if(*(p_wrecibuf-1)==FR_ETX) f_etx=1;
//}
}
/*else if (TI&&~t_empty){ // 发送并且发送缓冲区未空
SBUF=t_buf[t_out]; TI=0;
t_out=++t_out&0x1f; // t_out+1大于缓冲区,则t_out=0
if (t_out==t_in) t_empty=1; // 要发送的数据还未送入缓冲区数据,缓冲区空
}
else if (t_empty){ // 等待缓冲区装入数据
TI=0;
t_done=1;
}*/
}
/*
void process(uchar ch)
{
return;
}
*/
/*
void processmsg(void){
/* // 处理接收缓冲区字符子程序
while (((r_out+1)^r_in)!=0){ // 不空即可处理
if(r_buf[r_out+1]=='@'){ //定位帧头
pSTX=&(r_buf[r_out+1]);
f_stx_ok=1; //帧定位开始,可以unwrap
}
if((r_buf[r_out+1]=='\n')&&(f_stx_ok=1)){ //定位帧尾
pETX=&(r_buf[r_out+1]);
f_stx_ok=0;
f_etx_ok=1; //帧定位好,可以应答(同时f_stx=1)
}
r_out=++r_out&0x1f; //取缓冲计数
}
*/
/* uchar i;
i=*p_rrecibuf;
if(i==FR_STX){ //定位帧头
pSTX=p_rrecibuf;
f_stx_ok=1;
}
if((i=FR_ETX)&&(f_stx_ok=1)){ //定位帧尾
pETX=p_rrecibuf;
f_stx_ok=0;
f_etx_ok=1;
}
if(p_rrecibuf==(r_buf+INLEN-1))p_rrecibuf=r_buf;
else p_rrecibuf++;
cnt_reci--;
}
*/
void frame_unpack(uchar pre_cmd){ //通信发起命令字,
//最大重发次数
//==从缓冲读出一帧遍历,FR_ETX结束,期间关中断=================
uchar i;
uchar re_cmd,*re_para/*,re_bcc1,re_bcc2*/;
if(r_notempty/*&&f_etx*/){ //缓冲区不空
//do{
//ES=0;
i=*p_rrecibuf;
r_full=0;//清缓冲满标志
if(i==FR_STX){ //定位帧头
pSTX=p_rrecibuf; //头指针
f_stx_ok=1; //标志:头定位好
}
else if((i==FR_ETX)&&(f_stx_ok==1)){ //定位帧尾(前提:头定位好)
pETX=p_rrecibuf; //尾指针
f_stx_ok=0; //清标志
f_etx_ok=1; //标志:尾定位好,且帧定位好
}
if(p_rrecibuf==(r_buf+INLEN-1)) p_rrecibuf=r_buf; //循环
else p_rrecibuf++;
if(p_rrecibuf==p_wrecibuf) r_notempty=0; //置缓冲区取空标志
//cnt_reci--;
//}while(cnt_reci>0);
//ES=1;
//==应答域======================================
if(f_etx_ok&&(pETX-pSTX==9)){ //如果接收完毕并且 帧长度正确,可以开始读报
f_etx_ok=0; //1.清标志
//re_stx=*pSTX; //帧头
if(pSTX<pETX){ //不跨越缓冲区尾(一般情况)
re_cmd=*(pSTX+1); //命令字位置指针
re_para=pSTX+2; //数据域起始指针
//re_bcc1=*(pETX-2); //校验码1
//re_bcc2=*(pETX-1); //校验码2
}
/*else{ //如果溢出(特殊情况)
uchar *pi;
for(pi=r_buf;pi<=pETX;pi++){
*(pi+INLEN)=*pi;
}
re_cmd=*(pSTX+1);
re_para=pSTX+2;
}*/
//==应答机制====================================
switch(pre_cmd){
//程序分支1: 开始采集--光标数据--正确应答**************************************************
// --重发命令--
case FR_Start://开始采集
switch(re_cmd){
/*1*/ case FR_Cursor://'d'光标数据--[0][1]小数两位[2][3][4][5]整数四位
para_gb[5]=*re_para-'0';
para_gb[4]=*(re_para+1)-'0';
para_gb[3]=*(re_para+2)-'0';
para_gb[2]=*(re_para+3)-'0';
para_gb[1]=*(re_para+4)-'0';
para_gb[0]=*(re_para+5)-'0';
//frame_cmd(FR_Roger);//应答
//f_acq_ok=1;
break;
case FR_Result://计算结果--[6][5][4]度[3][2]分[1][0]秒
//put_char('r');
result[9]=*re_para-'0';
result[8]=*(re_para+1)-'0';
result[7]=*(re_para+2)-'0';
result[6]=DEG;
result[5]=*(re_para+3)-'0';
result[4]=*(re_para+4)-'0';
result[3]=MIN;
result[2]=*(re_para+5)-'0';
result[1]=*(re_para+6)-'0';
result[0]=SEC;
//frame_cmd(FR_Roger); //应答"收到"
Index=30; //转显示结果状态
Index=30; //冗余一次
break;
case FR_Cancel://报错--result[6][5][4][3][2][1][0]此时存放报错信息
//put_char('r');
result[6]=*re_para-'0'; //错位代码
result[5]=*(re_para+1)-'0'; //错误代码
//result[4]=*(re_para+2)-'0';
//result[3]=*(re_para+3)-'0';
//result[2]=*(re_para+4)-'0';
//result[1]=*(re_para+5)-'0';
//result[0]=*(re_para+6)-'0';
//frame_cmd(FR_Roger); //应答"收到"
Index=31; //转显示结果状态
Index=31; //冗余一次
break;
}
break;
//程序分支2: 开始标定--光标数据--正确应答**************************************************
// --重发命令--
case FR_Swing://开始标定
switch(re_cmd){
/*1*/ case FR_Cursor://'d'光标数据--[0][1]小数两位[2][3][4][5]整数四位
para_gb[5]=*re_para-'0';
para_gb[4]=*(re_para+1)-'0';
para_gb[3]=*(re_para+2)-'0';
para_gb[2]=*(re_para+3)-'0';
para_gb[1]=*(re_para+4)-'0';
para_gb[0]=*(re_para+5)-'0';
//frame_cmd(FR_Roger);//应答
//f_acq_ok=1;
break;
/*case FR_Swing://标定结果--[3][2][1][0]坐标
//put_char('r');
result[9]=SPACE;
result[8]=SPACE;
result[7]=SPACE;
result[6]=SPACE;
result[5]=*re_para-'0';
result[4]=*(re_para+1)-'0';
result[3]=*(re_para+2)-'0';
result[2]=*(re_para+3)-'0';
result[1]=*(re_para+4)-'0';
result[0]=*(re_para+5)-'0';
//frame_cmd(FR_Roger); //应答"收到"
Index=30; //转显示结果状态
Index=30; //冗余一次
break;*/
case FR_Cancel://报错--result[6][5][4][3][2][1][0]此时存放报错信息
//put_char('r');
result[6]=*re_para-'0'; //错位代码
result[5]=*(re_para+1)-'0'; //错误代码
//result[4]=*(re_para+2)-'0';
//result[3]=*(re_para+3)-'0';
//result[2]=*(re_para+4)-'0';
//result[1]=*(re_para+5)-'0';
//result[0]=*(re_para+6)-'0';
//frame_cmd(FR_Roger); //应答"收到"
Index=31; //转显示结果状态
Index=31; //冗余一次
break;
}
break;
//程序分支: 结束采集--计算结果--***********************************************************
/*case FR_Cancel:
switch(re_cmd){
case FR_Result://技术结果--[6][5][4]度[3][2]分[1][0]秒
result[6]=*re_para-'0';
result[5]=*(re_para+1)-'0';
result[4]=*(re_para+2)-'0';
result[3]=*(re_para+3)-'0';
result[2]=*(re_para+4)-'0';
result[1]=*(re_para+5)-'0';
result[0]=*(re_para+6)-'0';
Index=14;
//frame_cmd(re_cmd);//应答
break;
}
break;*/
//程序分支: 向DSP查询参数(进入Setup菜单时)--发各个参数帧*********************************************************
case FR_Para:
switch(re_cmd){
case FR_A://仪器常数'a'- [0][1]秒[2][3]分[4][5]度
para_a[6]=*re_para-'0';
para_a[5]=*(re_para+1)-'0';
para_a[4]=*(re_para+2)-'0';
para_a[3]=*(re_para+3)-'0';
para_a[2]=*(re_para+4)-'0';
para_a[1]=*(re_para+5)-'0';
para_a[0]=*(re_para+6)-'0';
frame_cmd(FR_Roger); //应答
f_seta_ok=1;
//frame_data(FR_A,para_a,ALEN);
break;
case FR_L://纬度'l'- [0][1]小数两位[2][3]整数两位
para_wd[2]=*re_para-'0';
para_wd[1]=*(re_para+1)-'0';
para_wd[0]=*(re_para+2)-'0';
//para_wd[0]=*(re_para+3)-'0';
frame_cmd(FR_Roger); //应答
//f_setl_ok=1;
//frame_data(FR_L,para_wd,LLEN);
break;
case FR_C://C值'c'- [0][1][2][3]
para_c[3]=*re_para-'0';
para_c[2]=*(re_para+1)-'0';
para_c[1]=*(re_para+2)-'0';
para_c[0]=*(re_para+3)-'0';
//para_c[1]=*(re_para+4);//符号
//para_c[0]=*(re_para+5)-'0';
frame_cmd(FR_Roger); //应答
f_setc_ok=1;
//frame_data(FR_C,para_c,CLEN);
break;
case FR_P://周期个数'm'- [0]个位[1]十位
para_p[1]=*re_para-'0';
para_p[0]=*(re_para+1)-'0';
frame_cmd(FR_Roger); //应答
//frame_data(FR_P,para_p,PLEN);
break;
case FR_Z://中天位置'z'- [3][2][1][0]
para_z[3]=*re_para-'0';
para_z[2]=*(re_para+1)-'0';
para_z[1]=*(re_para+2)-'0';
para_z[0]=*(re_para+3)-'0';
frame_cmd(FR_Roger); //应答
f_setz_ok=1;
//frame_data(FR_P,para_p,PLEN);
break;
}
break;
//程序分支: 向DSP设置参数(4种)******************************************************************************
case FR_A:
switch(re_cmd){
case FR_Roger:
frame_cmd(FR_Roger);
//f_rx_ok=1;
break;
}
break;
case FR_L:
switch(re_cmd){
case FR_Roger:
frame_cmd(FR_Roger);
//f_rx_ok=1;
break;
}
break;
case FR_C:
switch(re_cmd){
case FR_Roger:
frame_cmd(FR_Roger);
//f_rx_ok=1;
break;
}
break;
case FR_P:
switch(re_cmd){
case FR_Roger:
frame_cmd(FR_Roger);
//f_rx_ok=1;
break;
}
break;
case FR_Z:
switch(re_cmd){
case FR_Roger:
frame_cmd(FR_Roger);
//f_rx_ok=1;
break;
}
break;
}//switch
}//f_etx_ok
//f_etx=0;
}//F_etx
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -