【STM32L4】FreeRTOS消息队列三串口接收发送

本文介绍了如何在STM32L476G-DISCO开发板上,利用STM32CubeIDE 1.1.0和STM32CubeMX 5.4.0配置FreeRTOS,实现三个串口的异步接收和发送。通过开启串口的DMA接收和中断,结合FreeRTOS的消息队列,实现了高效的数据处理。关键文件包括FreeRTOSConfigure.h、freertos.c等,代码可在优快云或GitHub找到。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境

  • STM32L476G-DISCO 开发板
  • STM32CubeIDE 1.1.0
  • STM32CubeMX 5.4.0

STM32CubeIDE配置

移植FreeRTOS,选择CMSIS_V2。
FreeRTOSConfigure
FreeRTOS的所有配置的选择默认,后面手动修改FreeRTOSConfig.h文件修改配置。如果想直接在IDE中修改配置也可以直接修改。

开启三个串口,异步模式。
UartConfigure
由于接收采用空闲中断接收,所以要打开DMA接收和串口总中断。

重要文件

  • FreeRTOSConfigure.h FreeRTOS的配置文件。修改一些关于FreeRTOS的配置信息。
  • freertos.c FreeRTOS任务主文件,可以在void MX_FREERTOS_Init(void)函数中定义任务。

默认STM32CubeIDE在生成代码的时候是会在MA_FREERTOS_Init函数创建一个默认任务。该任务的功能仅仅做一个延时。

代码

FreeRTOSConfigure.h

#define configTOTAL_HEAP_SIZE       ((size_t)1024 * 24)
//修改Total Heap Size,该参数决定内存池的总大小,当FreeRTOS任务启动后总是进入HardFault_Handler中断程序时,可以考虑Debug看一下任务句柄地址的分配,很可能是因为内存池资源用完,没有空间分配导致的硬件异常中断。

main.h

/* USER CODE BEGIN Private defines */
#define UARTRXBUFFERSIZE 512     //串口接收的缓存区大小
#define UARTQUEUENUM  3          //消息队列的数量
#define UARTQUEUESIZE (uint32_t)UARTRXBUFFERSIZE * UARTQUEUENUM

typedef struct {
   
	uint8_t uartRxTemp[UARTRXBUFFERSIZE];
	uint8_t uartRxName[7];
} UARTMessageQueue_TypeDef;
/* USER CODE END Private defines */
//自己定义了一些宏和结构体

stm32l4xx_it.c

/* USER CODE BEGIN EV */
//在main.c文件中定义的串口接收缓存区,大小为UARTRXBUFFERSIZE
extern uint8_t uart1RxBuffer[UARTRXBUFFERSIZE];
extern uint8_t uart2RxBuffer[UARTRXBUFFERSIZE];
extern uint8_t uart4RxBuffer[UARTRXBUFFERSIZE];

//在freertos.c文件中定义的消息队列句柄
extern osMessageQueueId_t osQueueUart1;
extern osMessageQueueId_t osQueueUart2;
extern osMessageQueueId_t osQueueUart4;
/* USER CODE END EV */

/**
 * @brief This function handles USART1 global interrupt.
 */
void USART1_IRQHandler(void) {
   
	/* USER CODE BEGIN USART1_IRQn 0 */
	uint8_t temp;
	UARTMessageQueue_TypeDef msg;
	uint8_t str[7] = "USART1";
	if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) {
   
		//空闲中断
		//temp = huart4.Instance->ISR;
		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
		temp = huart1.Instance->RDR;
		temp = temp;
		HAL_UART_DMAStop(&huart1);
        //进入串口空闲中断之后,确定串口数据缓存区有数据,将串口数据存入结构体的数据存储数组,结构体的uartRxName成员存放消息来源的串口名称。
        //osMessageQueuePut将结构体推入osQueueUart1消息队列中。
        //其实可以将三个串口放入一个消息队列,用结构体中uartRxName成员区分来源。这里为了简单明了,没有做更多的优化。有兴趣可以自行修改。
		if (strlen(uart1RxBuffer) != 0) {
   
			memset(msg.uartRxTemp, 0x00, sizeof(msg.uartRxTemp));
			memcpy(msg.uartRxTemp, uart1RxBuffer, strlen(uart1RxBuffer));
			memcpy(msg.uartRxName, str, strlen(str));
			memset(uart1RxBuffer, 0x00, strlen(uart1RxBuffer));
			osMessageQueuePut(osQueueUart1, &msg, 0, 0);
		}

		__HAL_UART_CLEAR_IDLEFLAG(&huart1);
		__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
		HAL_UART_Receive_DMA(&huart1, uart1RxBuffer, UARTRXBUFFERSIZE);
	}
	/* USER CODE END USART1_IRQn 0 */
	HAL_UART_IRQHandler(&huart1);
	/* USER CODE BEGIN USART1_IRQn 1 */

	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值