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

这篇具有很好参考价值的文章主要介绍了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++;
				}				
				else
					osDelay(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,
FreeRTOS通过消息队列实现串口命令解析(串口中断),单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-634723.html

到了这里,关于FreeRTOS通过消息队列实现串口命令解析(串口中断)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • FreeRTOS 消息队列 详解

    目录 什么是队列? 消息队列特点 1. 数据入队出队方式 2. 数据传递方式 3. 多任务访问 4. 出队、入队阻塞 消息队列相关 API 函数 1. 创建队列 2. 写队列 3. 读队列 消息队列实操 队列又称 消息队列 ,是一种常用于任务间通信的数据结构,队列可以在任务与任务间、中断和任 务

    2024年02月08日
    浏览(41)
  • FreeRTOS(3)----消息队列

    一.消息队列的基本概念 队列成为消息队列,可以进行任务与任务间,中断和任务间传递信息,实现任务接收来自其他任务或中断的不固定长度的消息,任务可以从队列中读取消息,当队列消息为空的时候,读取消息的任务将会被阻塞,但是可以设定等待阻塞任务的时候xTic

    2024年03月18日
    浏览(70)
  • FreeRTOS-消息队列详解

    ✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页: @rivencode的个人主页 🔥系列专栏: 玩转FreeRTOS 💬保持学习、保持热爱、认真分享、一起进步!!! 本文将详细全方位的讲解FreeRTOS的队列消息,其实在FreeRTOS中队列的重要性也不言

    2024年02月05日
    浏览(43)
  • FreeRTOS - 消息队列

    消息队列(queue):可以在任务与任务间、中断和任务间传递消息,实现任务接收来自其他任务或中断的不固定的消息 1、使用消息队列检测串口输入 2、通过串口发送字符串openled1,openled2,openled3,分别打开板载led1,led2,led3 3、通过串口发送字符串closeled1,closeled2,closele

    2023年04月08日
    浏览(42)
  • FreeRTOS教程4 消息队列

    正点原子stm32f407探索者开发板V2.4 STM32CubeMX软件(Version 6.10.0) Keil µVision5 IDE(MDK-Arm) 野火DAP仿真器 XCOM V2.6串口助手 本文主要学习 FreeRTOS 消息队列的相关知识, 包括消息队列概述、创建删除复位队列、写入/读取数据到队列等关于队列的基础知识 在一个实时操作系统构成的

    2024年03月14日
    浏览(39)
  • FreeRTOS源码分析-7 消息队列

    目录 1 消息队列的概念和作用 2 应用 2.1功能需求 2.2接口函数API 2.3 功能实现 3 消息队列源码分析 3.1消息队列控制块 3.2消息队列创建 3.3消息队列删除 3.4消息队列在任务中发送 3.5消息队列在中断中发送 3.6消息队列在任务中接收 3.7消息队列在中断中接收  消息队列(queue),可

    2024年02月14日
    浏览(36)
  • 【FreeRTOS】【应用篇】消息队列【下篇】

    本篇文章主要对 FreeRTOS 中消息队列的概念和相关函数进行了详解 消息队列【下篇】详细剖析了消息队列中发送、接收时队列消息控制块中各种指针的行为,以及几个发送消息和接收消息的函数的运作流程 笔者有关于 【FreeRTOS】【应用篇】消息队列【上篇】——队列基本概念

    2024年02月10日
    浏览(37)
  • 【FreeRTOS】详细讲解FreeRTOS里中断管理并通过示例讲述其用法

       大家看到中断后,有没有想到一个名词——异常呢?若大家想到了,但是记不起相关概念;或者是,大家没想到这个名词,没关系, 下面小编就给大家伙讲讲 中断 、 异常 相关知识。 异常   异常,是指任何使CPU执行程序时脱离正常运行状态转而跑飞的任何事件,若

    2024年02月11日
    浏览(42)
  • 【STM32】FreeRTOS消息队列和信号量学习

    一、消息队列(queue) 队列是一种用于实现任务与任务之间,任务与中断之间消息交流的机制。 注意:1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验:创建一个消息队列,两个发送任务,一个接收任务。 其中任务一任务三

    2024年02月13日
    浏览(39)
  • 环形队列+DMA空闲中断+接收串口数据

    本次实验利用环形队列+DMA空闲中断+串口。。通过这个实验可以非常深入的理解队列,DMA,串口的知识。如果你能自己实现掌握这个实验,那么你应该基本掌握了队列,DMA,串口的知识。 本次使用的是用环形队列当缓冲器区接收串口数据。我们可以先区了解DMA的空闲中断。本次

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包