2025年第16届蓝桥杯嵌入式竞赛学习笔记(十二):不定长数据接收

1.任务分析

查看第十二届的真题,有一个串口接收的任务

最后有一个任务要求为

这就需要我们考虑错误的情况,串口接收的特点为每次进入中断只能接收一个字节的数据,如果考虑错误的情况,那么有两种方法。

1.每次接收到一个字节时,就去判断这个字节是否符合要求

2.接受完全部字节,判断字符串是否符合要求

第一种方法,我们要进行很多次判断,所以不能采用

第二种方法,存在一个问题,怎么去判断接收完了所有字符

解决方法:利用定时器,处理串口接收

                串口波特率 = 9600bit/s 就是1s可以传输9600bit

                串口传输一次数据 包含起始位(1bit),数据位(8bit),结束位(1bit),一共10bit

                10 * 1/9600 = 0.00104s = 1.04ms

串口接收两个数据的间隔为1.04ms,在接收一个数据时让定时器的计数器清零,第二个也是如此,在后面接收每个数据的时候都让计数器清零。

当接收最后一个数据的时候,进行一次判断,如果时间大于1.04ms,那就说明它不会再有下一个数据发来了,也就意味着数据接收完成。

比方说我们设置定时器的PSC + 1 =  8000。那么cnt计数器每次加一,它所需要的时间就是8000/80MHz = 1/10000 。cnt = 15 时对应的时间 t = 15 * 1/10000 = 0.0015s = 1.5ms。

这样在最后我们就可以判断cnt是否大于15。大于15说明接收完成。cnt大于15也就是说t大于1.5ms

2.CubeMX配置

USART1设置为异步通信,波特率为9600

打开TIM4的配置界面,时钟源为内部时钟,PSC设置为8000-1

配置完成点击右上角生成代码

3.代码部分

首先进行定时器的使能

HAL_TIM_Base_Start(&htim4);

编写串口接收的回调函数与接收判断函数

uint8_t rec_data, count;
uint8_t rec_flag;
char rec_buff[20];
char send_buff[20];

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart -> Instance == USART1)
	{
		TIM4 -> CNT = 0;
		rec_flag = 1;
		rec_buff[count] = rec_data;
		count++;
		HAL_UART_Receive_IT(huart, &rec_data, 1);
	}
}

void uart_data_rec(void)
{
	if(rec_flag)
	{
		if(TIM4 -> CNT > 15)
		{
			if(rec_buff[0] == 'l' && rec_buff[1] == 'a' && rec_buff[2] == 'n')
			{
				sprintf(send_buff,"lan\r\n");
				HAL_UART_Transmit(&huart1,(uint8_t *)send_buff,sizeof(send_buff),50);
			}
			else if(rec_buff[0] == 'q' && rec_buff[1] == 'i' && rec_buff[2] == 'a' && rec_buff[3] == 'o')
			{
				sprintf(send_buff,"qiao\r\n");
				HAL_UART_Transmit(&huart1,(uint8_t *)send_buff,sizeof(send_buff),50);
			}
			else if(rec_buff[0] == 'b' && rec_buff[1] == 'e' && rec_buff[2] == 'i')
			{
				sprintf(send_buff,"bei\r\n");
				HAL_UART_Transmit(&huart1,(uint8_t *)send_buff,sizeof(send_buff),50);
			}
			else
			{
				sprintf(send_buff,"error!\r\n");
				HAL_UART_Transmit(&huart1,(uint8_t *)send_buff,sizeof(send_buff),50);
			}
			rec_flag = 0;
			for(uint8_t i=0; i<count; i++)
				rec_buff[i] = 0;
			count = 0;
		}
	}
}

将uart_data_rec函数放在主程序的while(1)中

烧录完成开打串口助手进行试验,将波特率设为9600

实验发现,当发送lan、qiao、bei时,分别显示在了接收区,当发送haha时,显示error!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值