“健康守护者”——STM32F103使用HAL库串口接收不定长数据轮询、中断方式比较


“健康守护者”

我们做的这个“健康守护者”的产品是用来测试用户的下列身体指标:

用户穿戴上我们设备之后,先测量身高,然后站到我们的体重秤上,此时身高,体重,体温,血氧饱和度这几个数据就会在前端页面上进行显示,然后测量血压,血压测量结束之后,收缩压,舒张压,脉搏的数据就会在前端进行显示,这个就是我们整个产品的使用流程。在接下来的几篇博文中,我会分享一些在做产品时候遇到的问题,希望大家一起进步哦 >_<


零、分享顺序

因为我们这个产片分为3大部分,一部分是戴在手臂上的,测量舒张压,收缩压,脉搏,血氧,心率和体温的,一部分是手持的,用于测量身高,以及发送测试者ID和命令的,一部分是放在地上测试体重的,因此分一个目录来分别进行分享哈。(图片明天补上)

手臂部分

手持部分

体重部分

一、中断

好啦终于进入今天的正题啦!大家应该都有遇到过这样的需求,外设会发一串不定长的数字过来,需要我们用串口接收下来,那么串口有3种工作方式:轮询、中断和DMA,究竟用哪一种好呢?之前的我也是一知半解,这次我尝试了其中2个,轮询和中断,发现了一些个中区别,特此分享。


我用的芯片是STMF103,底层库用的是HAL库,有一说一HAL库用起来比标准库方便很多了呢,真香~~
先贴一段芯片初始化的代码:

int main(){
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USART1_UART_Init();
	MX_USART2_UART_Init();
	MX_USART3_UART_Init();
	while(1){
		......
	}
}

但是呢还是遇到了一个问题,就是外设持续以较低速度(以103的晶振频率一定能接收到的速度,1s10个字节的数据)发送数据给103的时候呢,刚开始103同学还是好好的工作者着,把自己收到的数据都老老实实通过串口传输到了电脑上,但是都是三分钟热度,过一会儿,串口就接收不到数据了,这可把我搞懵了。不知所措,明明有数据过来,103同学为什么接收不到了呢?
刚开始我们以为是数据接收缓存区爆了,所以吭哧吭哧去把代码改了,每次接收到数据之后把数据放到一个数组里,结果还是一样,这个bug就把我们劝退了,改用轮询方式接收数据了。
后来我回过头查资料的时候发现CSDN上早已有大佬遇到过这个问题并且把他完美的解决了,讲的超级详细,在CSDN上搜索:STM32 串口中断卡死,一片片的答案。其实就是在串口接受中断里面的库函数里面一个标志位的问题。
所以呢,这个教训告诉我们调库一时爽,BUG火葬场哦。以后在调库的时候可得要好好看看里面的实现,还有技术手册也得经常看,虽然很大概率是全英文的,但是看多了,专业名词就那么几个,很快就很熟练啦。

二、轮询

串口中断方式把我们劝退了之后我们就选了轮询方案,就是在while(1){}里程序不断的问串口,现在你接到数据了嘛?然后如果串口回答:是!那么就进行相应数据的处理,如果回答:否!那就只能让他哪凉快哪呆着去啦。
贴一些轮询处理的代码(这部分的思路是我和我的队员一起讨论出来的,实现是他实现的,写的还不错)

if(Uart3RXBuffer == 'U'){
	HAL_UART_Receive(&huart3,(uint8_t*)&Uart3RXBuffer,1,0xffff);
	if(Uart3RXBuffer == '1'){
		for(i=0;i<12;i++){
			HAL_UART_Receive(&huart3,(uint8_t*)&Uart3RXBuffer,1,0xffff);
			Uart3RX_Data[cnt++] = Uart3RXBuffer;
		}
}

这个就是在轮询过程中处理不定长数据的核心部分,我们的解决思路是先一个字符一个字符接收到数据,当且仅当接收到数据帧头的时候,我们会将接收到下一个帧头前接收到的数据存储到一个固定长度的数组里面,然后通过HAL_UART_Transmit这个函数将数据一次性发送出去,而对于定长的,而且发送数据较慢的情况来说,直接一次性把固定长度的数据接收下来即可,因为数据发送速度不高,所以很少出现丢包的情况。


总结

今天使用轮询方式解决串口接收不定长数据的方案有些简单,但是对于第一次接触串口的朋友们来说不失为一次深入了解串口的机会哦~钻到库里面看看他是怎么样实现的,再看看技术手册,一定会获益匪浅!

猜你喜欢

转载自blog.csdn.net/weixin_43454320/article/details/108458631