⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 com.c

📁 基于C51的通用人机界面程序
💻 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 + -