单片机串口接收通信协议的编写

        通信协议

        通信协议在很多单片机的使用中都是挺重要的内容,我自己学的时候看到很多配置挺头晕的,本文将不从配置的角度谈通信协议的编写,本文将从整体的角度编写通信协议。

我以stm32c8t6为例子编写下面的代码

举例

首先对于通信协议我们直接理解为接收和发送数据的格式就行了。对于接收来说,像这种

数据格式

5A 0A为帧头,ff ff ff为帧尾,第3、4位数字为数据位,如5A 0A 01 00 ff ff ff,这其实就是一串高低电平用十六进制表示而已,用电脑发给单片机的时候用相关串口软件就行了,至于接收就是下面的内容了

首先呢单片机的接收大部分都是使用中断函数,就是配置好相关参数后,接收到信息后就会跳转到中断的函数,然后在中断函数中调用读取串口传来的信息,一般单片机的库函数都是读取一个字节即8位,如0x5A就是0101 1010

过程

中断接收完一个字节后,清空标志位就能接收下一位,即重新进入中断函数,有几位中断就能会进几次。这是整个代码接收的过程。

我写了一个实现的代码

void USART1_IRQHandler(void)  //串口中断
{
	static uint8_t Rx_State=0;
	static uint8_t Rx_Pstart=0;
	static uint8_t Rx_PMessage=0;
	static uint8_t Rx_PEnd=0;
	static uint8_t RX_Cnt=0;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET){//接收中断非空标志位			
		Recive_Data=USART_ReceiveData(USART1);
		RX_Cnt++;
		//搜索帧头
		if(Rx_State==0){
			if(Recive_Data==0x5A){
			//RX_Cnt=0;	
			Rx_Pstart=1;
			}			
			if(Recive_Data==0x0A&&Rx_Pstart==1){				
				Rx_PMessage=0;//准备接收数据
				Rx_Pstart=0;//准备重新搜索帧头
				Rx_State=1;				
			}
		}		
		if(Rx_State==1 ){//这样可以使第二位也能是0x0A,直接不等于就行
			if(Recive_Data!=0x0A && Rx_PMessage==0){
				Serial_RecievePacket[Rx_PMessage]=Recive_Data;//问题所在
				Rx_PMessage=1;				
			}						
			if( Rx_PMessage==1 && RX_Cnt==4){//第4位			
					Serial_RecievePacket[Rx_PMessage]=Recive_Data;
					Rx_PEnd=0;//准备判断帧尾
					Rx_State=2;
								
			}
			
		}
		if(Rx_State==2){
		
			if(Recive_Data==0xFF)Rx_PEnd++;
			if(Rx_PEnd>=3){
			Recive_Flag=1;
			RX_Cnt=0;
			Frame_times_Cut++;//Frame_times_Cut 的值为有效帧的帧数
			Rx_State=0;
			}			
		}			
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);
	}		
}

我用了一个RX_Cnt来表示代码进入的次数,方便整个代码思路的研究,实际上直接else if   else if就可以了不用使用这样来判断到了第几位,因为中断会重复进入7次,因为上面我用7位字节当作一次完整的数据接收。

实际上大部分通信接收的过程都是这样,在配置好串口或者其他代码的时候,中断重复进入,清楚中断标志位后接收下一位数据。我上面的代码在最后还分辨了帧数的个数,你发两帧我还可以接收第二帧。

直接用if else其实代码可以非常简短,我为了表明中断会多次进入使用以上的编写方式

调用接收的数据

那么调用要的数据其实也简单,在代码后面我让一个Recive_Flag=1,在主循环中if之后清楚,中间就可以调用。

while(1){
		
			if(Recive_Flag==1 &&Frame_times_Cut==1){//截取第一帧
				USART_SendPackets(Serial_RecievePacket);//Receive;
				Recive_Flag=0;
				
			}
				
				
		              										
	}

了解整体的过程后其实其他很多配置网上都能找到,甚至模块化的库都有,对于一些单片机比如stc32逐飞的库配置就非常方便,我们只需要在意通信代码的编写就行。

总结

        接收的过程其实就是接收到一个字节,然后进入中断函数,清楚中断标志位后再次进入中断,直到把数据全部读完。以次为基础寻找配置的代码,其实就中间那段代码判断帧头帧尾的要自己写,串口接收的效果实现其实是非常简单的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值