蓝桥杯-STM32G431RBT6(UART解析字符串sscanf和解决串口BUG)

一、C语言常识

printfsprintf的主要区别在于它们的功能和用途:

  1. printf:主要用于将格式化的数据输出到标准输出(如屏幕)。

  2. sprintf:则是将格式化的数据存储到一个指定的字符串缓冲区中,而不是直接输出。
    printf 函数

  3. 输出调试信息:在程序开发过程中,将关键数据、状态等信息输出到控制台,便于调试。

  4. 生成格式化的输出:如输出格式化的文本、数值等。

sprintf 函数

  1. 构建字符串:将数据按照特定格式转换为字符串,用于后续处理或存储。
  2. 在不直接输出的情况下生成格式化的文本,例如在需要将格式化后的内容传递给其他函数或存储在变量中时使用。
    %4ssscanf中的含义是:读取最多 4 个字符并将其存储为字符串。

它确保读取的字符串长度不超过 4 个字符。

  • char tx_buf[30]:这是一个可以存储 30 个字符的发送缓冲区。
  • uint8_t rx_data:这是一个 8 位的接收数据变量。
  • char rx_buf[30]:这是一个可以存储 30 个字符的接收缓冲区。
  • uint8_t rx_count:这是接收数据的计数。
  • char car_type[5]:用于存储车型的 5 个字符的数组。
  • char car_num[5]:用于存储车牌号的 5 个字符的数组。
  • char car_time[15]:用于存储时间的 15 个字符的数组。

二、代码

复制代码
 char tx_buf[30];
 uint8_t rx_data;
 char rx_buf[30];
 uint8_t rx_count;
 char car_type[5];
 char car_num[5];
 char car_time[15];

void uart_proc(void)
{
if(rx_count==22)
{
	sscanf(rx_buf,"%4s:%4s:%12s",car_type,car_num,car_time);
	sprintf(tx_buf,"car_type:%4s\r\n",car_type);
     HAL_UART_Transmit(&huart1,(uint8_t*)tx_buf,strlen(tx_buf),50);	
	sprintf(tx_buf,"car_num:%4s\r\n",car_num);
     HAL_UART_Transmit(&huart1,(uint8_t*)tx_buf,strlen(tx_buf),50);	
	sprintf(tx_buf,"car_time:%12s\r\n",car_time);
     HAL_UART_Transmit(&huart1,(uint8_t*)tx_buf,strlen(tx_buf),50);	
	rx_count=0;
	memset(rx_buf,0,20);
}
}

三.BUG

1.解决接受不完整问题

假如没接受完成,执行函数,就可能会把count直接清零,就会重新接受

复制代码
 while (1)
{
   Key_Proc();
   Lcd_proc();
   if(rx_count!=0)
   {
   uint8_t ttemp=rx_count;
	   HAL_Delay(1);
	   if(ttemp==rx_count) 
	uart_proc();
   }
   
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

2.解决接受错误下一次不能执行的问题

以下是对这段代码的详细解释:

void rxclear_proc(void):这是一个定义的函数,名为 rxclear_proc,它没有返回值(void)。

在函数内部:

  • if(usrxclear<50) return;:如果变量 usrxclear 的值小于 50,则直接返回,不执行后续代码。
  • usrxclear=0;:将 usrxclear 变量的值重置为 0。
  • rx_count=0;:将接收数据的计数变量 rx_count 重置为 0。
  • memset(rx_buf,0,20);:使用 memset 函数将 rx_buf 数组的前 20 个元素全部设置为 0,以清空该缓冲区。
复制代码
void rxclear_proc(void)
{   if(usrxclear<50) return;
	usrxclear=0;
    rx_count=0;
	memset(rx_buf,0,20);
}

uint32_t usrxclear;//main中定义

void SysTick_Handler(void)//滴答定时器里面定义
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
usrxclear++;
  /* USER CODE END SysTick_IRQn 1 */
}

 extern uint32_t usrxclear;//"stm32g4xx_it.C"中定义

四.代码开源

通过网盘分享的文件:串口.zip

链接: https://pan.baidu.com/s/1s-FNqcBW1CerVNHGyEfvuQ?pwd=0820 提取码: 0820

相关推荐
renhongxia12 分钟前
如何基于知识图谱进行故障原因、事故原因推理,需要用到哪些算法
人工智能·深度学习·算法·机器学习·自然语言处理·transformer·知识图谱
坚持就完事了3 分钟前
数据结构之树(Java实现)
java·算法
星马梦缘4 分钟前
EDA彩灯电路绘制
单片机·嵌入式硬件·物联网·pcb·eda·嘉立创
算法备案代理5 分钟前
大模型备案与算法备案,企业该如何选择?
人工智能·算法·大模型·算法备案
赛姐在努力.29 分钟前
【拓扑排序】-- 算法原理讲解,及实现拓扑排序,附赠热门例题
java·算法·图论
野犬寒鸦2 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总2 小时前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法
rainbow68892 小时前
深入解析C++STL:map与set底层奥秘
java·数据结构·算法
Forsete2 小时前
LINUX驱动开发#9——定时器
linux·驱动开发·单片机
wangjialelele2 小时前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先