FreeRTOS通过消息队列实现串口命令解析(串口中断)

作者:Jack_G
时间:2023.08.08
版本:V1.0
上次修改时间:
环境:
\quad \quad \quad \quad STM32Cube MX V6.8.1
\quad \quad \quad \quad STM32CubeH7 Firmware Package V1.11.0 / 04-Nov-2022
\quad \quad \quad \quad Keil: V5.29

一、串口配置:

正常配置,不过需要勾选全局中断,后续在接收中断中将接收到的数据送入消息队列。
在usart.c文件中添加以下代码以重定义fputc以支持printf

//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)  
//解决HAL库使用时,某些情况可能报错的bug
int _ttywrch(int ch)    
{ch=ch;return ch;
}
//标准库需要的支持函数                 
struct __FILE 
{ int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ 
}; 
/* FILE is typedef’ d in stdio.h. */ 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      while((USART1->ISR&0X40)==0);//循环发送,直到发送完毕   USART1->TDR = (unsigned char) ch;      return ch;//	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&ch, 1); 
//  return (ch);}
#endif 

记得添加头文件

#include "stdio.h"	
#include "stdlib.h"
#include "string.h"

二、代码部分

创建指令解析的任务和消息队列和信号量:

其中信号量是用于串口接收完一次完整消息后通知任务开始获取消息队列的消息。
这部分代码主要:
创建命令解析任务、创建命令解析所用的消息队列、创建命令解析所用的信号量

void StartCMDAnalysisTask(void const * argument);//声明命令解析函数osThreadId cmdAnalysisTaskHandle;//定义命令解析任务的句柄
SemaphoreHandle_t  uartSemaphore;//定义串口接收一次完成的信号量
QueueHandle_t  uartQueue;//定义串口消息队列的句柄/* 创建指令解析任务 */
osThreadDef(cmdAnalysisTask, StartCMDAnalysisTask, osPriorityBelowNormal, 0, 512);
cmdAnalysisTaskHandle = osThreadCreate(osThread(cmdAnalysisTask), NULL);/* 创建串口的消息队列 */
uartQueue = xQueueCreate((UBaseType_t ) 128,/* 消息队列的长度 */(UBaseType_t ) sizeof( char));/* 消息的大小 */
if(NULL == uartQueue)printf("uartQueue created failed\r\n");/* 创建串口接收完成的信号量 */
uartSemaphore = xSemaphoreCreateBinary();
if(NULL == uartSemaphore)printf("uartSemaphore created failed\r\n");

具体实现:

实现逻辑:
①开启串口的接收中断(UART_IT_RXNE)和空闲中断(UART_IT_IDLE)
\quad \quad 接收中断是每接收一个字符时 产生一次中断
\quad \quad 空闲中断是每完成一次接收后产生的中断

②每当接收中断时(即接收一个字符),将获取的字符送入消息队列
③当完成一个串口传输时(即本次传输完成),释放信号(通知任务传输完成)
④任务获取到信号量后,将消息队列中的数据尽数取出,直到’\r’,(这个\r是我自己定义的)
⑤将取出的消息放提前准备好的缓冲区中,使用strcmp函数进行对比
⑥清空缓冲区,等待下一次的’\r’

开启串口中断

笔者实测STM32H7将开启串口中断代码放于串口初始化后,会莫名奇妙直接进入空闲中断,查阅资料发现有些F1不会出现这种情况,因此笔者建议这部分放于创建完任务后,实测可行。

__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);//开启接收中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);//开启空闲中断
__HAL_UART_CLEAR_IDLEFLAG(&huart1);	

串口中断函数

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 1 */uint8_t res = 0;
if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) != RESET){HAL_UART_Receive(&huart1,&res,1,1000);//将数据放入消息队列xQueueSendFromISR(uartQueue,&res,NULL);__HAL_UART_CLEAR_FLAG(&huart1,UART_FLAG_RXNE);}//空闲中断if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE) != RESET){//一帧数据接收完成		//释放信号量xSemaphoreGiveFromISR(uartSemaphore,NULL);__HAL_UART_CLEAR_IDLEFLAG(&huart1);}/* USER CODE END USART1_IRQn 1 */
}

解析任务

void StartCMDAnalysisTask(void const * argument)
{char Rx_Buffer[128];int index=0;memset(Rx_Buffer,'\0',128);for(;;){if(uxSemaphoreGetCount(uartSemaphore) == 1) //串口完成了一次接收{xSemaphoreTake(uartSemaphore, ( TickType_t ) 10);//获取信号量/* 获取消息队列中的数据到Buffer中直至获取到\r */		do{if(xQueueReceive(uartQueue,&Rx_Buffer[index],( TickType_t ) 10) == pdTRUE){index++;}				elseosDelay(10);}while(Rx_Buffer[index-1] != '\r');Rx_Buffer[index-1] = '\0';index = 0;	
/* 命令解析 命令 存于Rx_Buffer中,解析完一次则清空一次*/if(strcmp(Rx_Buffer,"AT") == 0){printf("ok\r\n");}/* 放置你需要解析的命令if(strcmp(Rx_Buffer,"your CMd") == 0){//定义处理的方式}*/memset(Rx_Buffer,'\0',128);			}osDelay(2);}
}

这里只写了AT,返回OK,
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/28492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抖音的竞争对手?Meta计划人工智能聊天机器人增加社交媒体数量

在来自抖音的竞争中,Meta着眼于用户参与的下一个前沿。 报道,Meta正在开发一系列具有不同个性的人工智能聊天机器人,此举旨在增加用户在脸书和Instagram等社交平台上的参与度金融时报和边缘。这些聊天机器人被Meta staff称为“personas ”,将…

LabVIEW开发高压配电设备振动信号特征提取与模式识别

LabVIEW开发高压配电设备振动信号特征提取与模式识别 矿用高压配电设备是井下供电系统中的关键设备之一,肩负着井下供配电和供电安全的双重任务,其工作状态直接影响着井下供电系统的安全性和可靠性。机械故障占配电总故障的70%。因此,机械故…

代理模式及常见的3种代理类型对比

代理模式及常见的3种代理类型对比 代理模式代理模式分类静态代理JDK动态代理CGLIBFastclass机制 三种代理方式之间对比常见问题 代理模式 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修…

嵌入式开发实用工具——QFSViewer

嵌入式开发实用工具——QFSViewer 介绍 今天给大家推荐个我个人业余时间开发的一个嵌入式开发实用工具——QFSViewer,这个工具主要是用来加载查看各种嵌入式常用的文件系统映像,目前支持JFSS2、Fat32、Fat16、Fat12、exFat、Ext2、Ext3、Ext4等文件系统…

用栈判断是否匹配

1 问题 写代码的时候用到的括号都是成双成对的出现,并且大小也相同。在集成编辑环境中,IDE就会为我们自己动检查括号是否匹配。那么为了避免在报错,如何判断是否有无括号不匹配? 2 方法 利用栈来实现这种功能。当遇见一个左括号&a…

【Linux命令行与Shell脚本编程】 第十七章 图形化桌面环境脚本编程

Linux命令行与Shell脚本编程 第十七章 图形化桌面环境脚本编程 文章目录 Linux命令行与Shell脚本编程七.图形化桌面环境脚本编程7.1.创建文本菜单7.1.1.创建菜单布局7.1.2.创建菜单逻辑7.1.3.整合脚本菜单7.1.4.使用select命令 7.2.创建文本窗口部件7.2.1.dialog软件包部件msg…

wpf 项目中使用 Prism + MaterialDesign

1.通过nuget安装MaterialDesign 2.通过nuget安装Prism 3.修改App.xmal <prism:PrismApplication x:Class"VisionMeasureGlue.App"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/…

66 # form 数据格式化

实现一个 http 服务器 客户端会发送请求 GET POST 要处理不同的请求体的类型 表单格式&#xff08;formData a1&b2&#xff09;&#xff0c;可以直接通信不会出现跨域问题JSON &#xff08;"{"kaimo":"313"}"&#xff09;文件格式 &#x…

Android 项目导入高德SDK初次上手

文章目录 一、前置知识&#xff1a;二、学习目标三、学习资料四、操作过程1、创建空项目2、高德 SDK 环境接入2.1 获取高德 key2.2下载 SDK 并导入2.2.1、下载SDK 文件2.2.2、SDK 导入项目2.2.3、清单文件配置2.2.4、隐私权限 3、显示地图 一、前置知识&#xff1a; 1、Java 基…

移动端自动化测试实战

UI自动化测试的价值 1、提升回归测试的效率 2、可以进行兼容性测试 UI 自动化测试应用场景 • 冒烟测试自动化&#xff1a;提测之前自动断言提测质量&#xff0c;提供准入参考。 • 功能测试自动化&#xff1a;辅助 QA 与测试工程师的快速验证。 • 验收测试自动化&#xf…

stable-diffusion-webui 界面汉化

本教程通过安装 sd-webui-bilingual-localization 插件来达到汉化目的, 项目地址为:https://github.com/journey-ad/sd-webui-bilingual-localization 一、安装插件 先进入插件安装界面 在搜索栏搜索 zh_CN Localization 中文语言包, 项目地址: https://github.com/dtlnor/st…

CrossOver是什么软件 CrossOver软件好用吗

CrossOver是一款由CodeWeavers公司开发的软件&#xff0c;它可以在Mac和Linux等操作系统上运行Windows软件&#xff0c;而无需在计算机上安装Windows操作系统。这款软件的核心技术是Wine&#xff0c;它是一种在Linux和macOS等操作系统上运行Windows应用程序的开源软件。本文将会…

使用docker 搭建nginx + tomcat 集群

创建3个Tomcat容器&#xff0c;端口分别映射到 8080,8081,8082&#xff0c;使用数据卷挂载&#xff0c;分别将宿主机目录下的 /opt/module/docker/tomcat3/ROOT1/&#xff0c;/opt/module/docker/tomcat3/ROOT2/&#xff0c;/opt/module/docker/tomcat3/ROOT2/ 挂载到 容器内部…

CAD练习——绘制冲压件三视图

首先还是先设置咱们的绘图模板&#xff1a; 这是图层划分&#xff1a; 文字样式设置&#xff1a; 标注样式&#xff1a; 从主视图开始&#xff0c;首先绘制如下图形 用到的快捷指令&#xff1a; L&#xff1a;直线 O&#xff1a;偏移 TR&#xff1a;修剪 效果&#xff1a;…

搭建日志服务器Rsyslog

Rsyslog介绍 Rsyslog的全称是 rocket-fast system for log&#xff0c;它提供了高性能&#xff0c;高安全功能和模块化设计。rsyslog能够接受从各种各样的来源&#xff0c;将其输入&#xff0c;输出的结果到不同的目的地。rsyslog可以提供超过每秒一百万条消息给目标文件。 特…

SQL Server数据库如何添加Oracle链接服务器(Windows系统)

SQL Server数据库如何添加Oracle链接服务器 一、在添加访问Oracle的组件1.1 下载Oracle的组件 Oracle Provider for OLE DB1.2 注册该组件1.2.1 下载的压缩包解压位置1.2.2 接着用管理员运行Cmd 此处一定要用管理员运行&#xff0c;否则会报错 二、配置环境变量三、 重启SQL Se…

使用Spring五大注解来更加简单的存储Bean对象

在使用Spring框架的时候我们如果使用这种方式来存储bean对象的话未免有点太麻烦了 <bean id"xxx" class"xxx"> </bean> 为了简化存储Bean对象的操作&#xff0c;我们可以使用五大类注解来进行存储Bean对象 我们首先要在配置文件配置扫描路径…

【快应用】list组件属性的运用指导

【关键词】 list、瀑布流、刷新、页面布局 【问题背景】 1、 页面部分内容需要瀑布流格式展示&#xff0c;在使用lsit列表组件设置columns进行多列渲染时&#xff0c;此时在里面加入刷新动画时&#xff0c;动画只占了list组件的一列&#xff0c;并没有完全占据一行宽度&…

把大模型装进手机,分几步?

点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机&#xff0c;AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代&#xff0c;华为盘古大模型将会来助力鸿蒙生态。”8月4日&#xff0c;华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍&#xff0c…

Gson 添加数据默认值问题记录

问题&#xff1a;在用Gson add(key&#xff08;string类型&#xff09;&#xff0c;value&#xff08;必须是JsonElement子类&#xff09;&#xff09;时发现&#xff0c;value 传了 "" 空字符串&#xff08;非null&#xff09;&#xff0c;默认解析后返回null&#…