STM32的串口通讯协议

简单理解一下正点原子的串口通讯的协议代码,代码如下

void USART1_IRQHandler(void)
{
	u8 res;
	u16 USART_RX_STA=0;       //接收状态标记	
	u8 USART_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节
	
	if(USART1->SR&(1<<5))	//接收到数据
	{	 
		res=USART1->DR; //接受到的数据给临时变量
		if((USART_RX_STA&0x8000)==0)//接收未完成
		{
			if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
			}else //还没收到0X0D
			{	
				if(res==0x0d)USART_RX_STA|=0x4000;
				else
				{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
				}		 
			}
		}  		 									     
	}

首先声明两个全局变量,1、extern u8 USART_RX_BUF[USART_REC_LEN],其中USART_REC_LEN为宏定义的最大字节数,USART_RX_BUF数组为数据接受缓冲器,将一次协议过程接受到的数据放入此数组,可用于主函数调用分析。2、extern u16 USART_RX_STA为接受状态标记,此变量为16位。当接受到的一个数据0x0d时bit14置1。当bit14为1且接受到的下一个数据为0x0a时,bit15置1,此时即可认为完成了一次通讯协议。

bit15bit14bit13~0
接受完成标志接受预完成标志接受有效数据个数
0x0a(ASCII码中的换行符)0x0d(ASCII码中回车符)最多16382个字节

临时变量u8 res用于存放接受到的每个数据。
if(USART1->SR&(1<<5))即每接收到一个字节就产生中断,把每个字节进入协议分析。
if((USART_RX_STA&0x8000)==0)“接受完成标志位“”为0也即未完成数据接收,那么进入协议,若此位为1则表面已经完成一次协议跳过之后分析,当主函数完成相应功能后,需要再次接收数据时置0。

if(USART_RX_STA&0x4000)//接收到了0x0d
			{
				if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了
			}

“接受预完成标志“为0则是还在正常接收数据中,即继续进行协议。若“接受预完成标志“为1,则是已经接收了0x0d,那么判断这次接收到的数据是否为0x0a,若不是那么说明数据接收发生错误,至此重新接收,将数据重头放入缓冲数据接收器覆盖之前的数据。若这次接收的数据是0x0a,那么接收完成标志置1,代表此次协议完成。

	
	if(res==0x0d)USART_RX_STA|=0x4000;
		else
		{
			USART_RX_BUF[USART_RX_STA&0X3FFF]=res;
			USART_RX_STA++;
			if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
		}		 
			

若接收到的数据为0x0d则将“接受预完成标志“置1之后等待接收下一个字节。若接收到的数据不是0x0d则此数据为有效数据,将它放入“数据缓冲器“,[USART_RX_STA&0X3FFF]代表这是接收的第n个数据。if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;当接收到超过设置的最大字节数,代表接收错误则重新开始接收。

最后简单总结一下:每接收到一个字节便产生中断,将此接收到的数据进行协议分析,接收到的有效数据放入接收缓冲器(这是声明的外部数组),并且给USART_RX_STA即接受状态标志位加1,USART_RX_STA的0~13位代表这是接受到的第几个数据,若接收到的数据是0x0d则将bit14置1,此数据不是有效数据,有效数据位不会增加。之后的情况1、若下一个接收的数据是0x0a,则将bit15置1且代表此协议完成,在bit15未置0之前不再接收数据2、若下一个接收的数据是不是0x0a,则代表此次数据传输错误,则将USART_RX_STA清0,再次重新接收数据。
注意:
1、每次正常传输的数据必须以0x0d,0x0a为结尾
2、接收完成标志位也即USART_RX_STA第15位必须由主函数置0,在置0前不会再接收到数据
3、传输了0x0d未传输0x0a和传输的字节数超过设定数目都会发生传输错误,这会导致重新接收数据且重新的数据又从0开始覆盖接收缓冲器数组里(即之前的数据会被覆盖)
4、USART_RX_STAUSART_RX_BUF[USART_REC_LEN]必须声明外部变量才能在主函数使用

此协议可获得:
1、接收到了多少个字节的数据(也即USART_RX_STA里0~13bit的数量,在主函数可通过USART_RX_STA&0x3FFF表示)
2、接收到的数据(存放在接收缓冲器数组里,在此代码里为USART_RX_BUF[USART_REC_LEN] ,可在主函数里通过此数组进行处理)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32串口通讯协议的改进方面,可以考虑以下几个方向: 1. 提高传输速率:可以通过优化串口通讯协议的数据包格式,减少校验位或停止位的数量,从而提高传输速率。另外,也可以考虑使用更高速的串口通讯协议,如USB协议,来替代传统的RS-232、RS-485协议。 2. 增加数据安全性:可以引入更强大的数据校验机制,如CRC校验,来确保数据的完整性和准确性。此外,还可以考虑使用加密算法对数据进行加密,以提高数据的安全性。 3. 支持多种通讯方式:可以在STM32上实现多种串口通讯协议的支持,如UART、USART、I2C、SPI等,以满足不同应用场景的需求。 4. 降低功耗和成本:可以通过优化串口通讯协议的实现方式,减少功耗和成本。例如,可以采用低功耗的通讯模式,或者使用更简化的硬件电路设计。 需要注意的是,具体的改进方案需要根据实际应用需求和硬件平台的特性来确定。以上只是一些常见的改进方向,具体的实施需要根据具体情况进行评估和选择。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [STM32串口通信编程](https://blog.csdn.net/qq_53352654/article/details/127305609)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值