STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

这篇具有很好参考价值的文章主要介绍了STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 文章来源地址https://www.toymoban.com/news/detail-482247.html

参考帖子:https://blog.csdn.net/freedompoi/article/details/122350866

目前想要实现STM32F4自带的DMA双缓冲区,尝试过一版,结果不能预期,就使用了RxHalfCplt和RxCplt去实现DMA双缓冲区的效果。

现在有时间了,又重新实现STM32F4自带的DMA双缓冲区,作为参考。

 

MCU:STM32F429ZIT6

开发环境:STM32CubeMX+MDK5

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

此时,双击完后会关闭此界面,然后打开一个新界面。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

然后,我们开始基本配置。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

现在我们选择一个LED作为系统LED,该步骤可以忽略,只是本人喜欢这样子。以硬件原理图的LD3为例子。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

基本配置除了时钟树外,基本上已经配置好了。

现在配置时钟树

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

基本配置已经配置完,现在开始配置实验使用的内容。

配置USART1,打开USART中断。并打开DMA。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

配置FreeRTOS

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

配置完成,完善工程,生成工程。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

到此,STM32CubeMX工具的使用结束!可以发现在桌面已经生成了DMA_DoubleBuf工程。

 

使用MDK5打开SDCard_rw工程打开。点击魔法棒,勾选微库。选择对应的下载器,勾选下载完复位允许。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

在usart.h文件中,加入内容。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 1 /* USER CODE BEGIN Header */
 2 /**
 3   ******************************************************************************
 4   * @file    usart.h
 5   * @brief   This file contains all the function prototypes for
 6   *          the usart.c file
 7   ******************************************************************************
 8   * @attention
 9   *
10   * Copyright (c) 2023 STMicroelectronics.
11   * All rights reserved.
12   *
13   * This software is licensed under terms that can be found in the LICENSE file
14   * in the root directory of this software component.
15   * If no LICENSE file comes with this software, it is provided AS-IS.
16   *
17   ******************************************************************************
18   */
19 /* USER CODE END Header */
20 /* Define to prevent recursive inclusion -------------------------------------*/
21 #ifndef __USART_H__
22 #define __USART_H__
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 /* Includes ------------------------------------------------------------------*/
29 #include "main.h"
30 
31 /* USER CODE BEGIN Includes */
32 #include "cmsis_os.h"
33 #include <semphr.h>
34 /* USER CODE END Includes */
35 
36 extern UART_HandleTypeDef huart1;
37 
38 /* USER CODE BEGIN Private defines */
39 
40 #define UART_BUFF_SIZE  30
41  
42 #pragma pack(4)
43 typedef struct
44 {
45     uint16_t len;
46     uint8_t  data[UART_BUFF_SIZE];
47 }usart_multibuffer_data;
48 #pragma pack()
49 
50 /* USER CODE END Private defines */
51 
52 void MX_USART1_UART_Init(void);
53 
54 /* USER CODE BEGIN Prototypes */
55 void UART_DMA_MultiBuffer(void);
56 /* USER CODE END Prototypes */
57 
58 #ifdef __cplusplus
59 }
60 #endif
61 
62 #endif /* __USART_H__ */

在usart.c文件中,加入内容。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

  1 /* USER CODE BEGIN Header */
  2 /**
  3   ******************************************************************************
  4   * @file    usart.c
  5   * @brief   This file provides code for the configuration
  6   *          of the USART instances.
  7   ******************************************************************************
  8   * @attention
  9   *
 10   * Copyright (c) 2023 STMicroelectronics.
 11   * All rights reserved.
 12   *
 13   * This software is licensed under terms that can be found in the LICENSE file
 14   * in the root directory of this software component.
 15   * If no LICENSE file comes with this software, it is provided AS-IS.
 16   *
 17   ******************************************************************************
 18   */
 19 /* USER CODE END Header */
 20 /* Includes ------------------------------------------------------------------*/
 21 #include "usart.h"
 22 
 23 /* USER CODE BEGIN 0 */
 24 QueueHandle_t           queue_mes;  
 25 usart_multibuffer_data     uart_buf[2];
 26 
 27 //DMA 缓存0 传输结束回调函数
 28 void DMA_M0_RC_Callback(DMA_HandleTypeDef *hdma)
 29 {
 30     BaseType_t xHigherPriorityTaskWoken; 
 31  
 32     uart_buf[0].len = hdma->Instance->NDTR;
 33     xQueueSendFromISR(queue_mes,&uart_buf[0],&xHigherPriorityTaskWoken);
 34     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
 35 }
 36  
 37 //DMA 缓存1 传输结束回调函数
 38 void DMA_M1_RC_Callback(DMA_HandleTypeDef *hdma)
 39 {
 40     BaseType_t xHigherPriorityTaskWoken; 
 41  
 42     uart_buf[1].len = hdma->Instance->NDTR;
 43     xQueueSendFromISR(queue_mes,&uart_buf[1],&xHigherPriorityTaskWoken);
 44     portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
 45 }
 46  
 47 //DMA 传输错误回调函数
 48 void DMA_Error_Callback(DMA_HandleTypeDef *hdma)
 49 {
 50     //里面做一些异常处理
 51 }
 52 /* USER CODE END 0 */
 53 
 54 UART_HandleTypeDef huart1;
 55 DMA_HandleTypeDef hdma_usart1_rx;
 56 
 57 /* USART1 init function */
 58 
 59 void MX_USART1_UART_Init(void)
 60 {
 61 
 62   /* USER CODE BEGIN USART1_Init 0 */
 63 
 64   /* USER CODE END USART1_Init 0 */
 65 
 66   /* USER CODE BEGIN USART1_Init 1 */
 67 
 68   /* USER CODE END USART1_Init 1 */
 69   huart1.Instance = USART1;
 70   huart1.Init.BaudRate = 115200;
 71   huart1.Init.WordLength = UART_WORDLENGTH_8B;
 72   huart1.Init.StopBits = UART_STOPBITS_1;
 73   huart1.Init.Parity = UART_PARITY_NONE;
 74   huart1.Init.Mode = UART_MODE_TX_RX;
 75   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 76   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 77   if (HAL_UART_Init(&huart1) != HAL_OK)
 78   {
 79     Error_Handler();
 80   }
 81   /* USER CODE BEGIN USART1_Init 2 */
 82 
 83   /* USER CODE END USART1_Init 2 */
 84 
 85 }
 86 
 87 void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
 88 {
 89 
 90   GPIO_InitTypeDef GPIO_InitStruct = {0};
 91   if(uartHandle->Instance==USART1)
 92   {
 93   /* USER CODE BEGIN USART1_MspInit 0 */
 94 
 95   /* USER CODE END USART1_MspInit 0 */
 96     /* USART1 clock enable */
 97     __HAL_RCC_USART1_CLK_ENABLE();
 98 
 99     __HAL_RCC_GPIOA_CLK_ENABLE();
100     /**USART1 GPIO Configuration
101     PA9     ------> USART1_TX
102     PA10     ------> USART1_RX
103     */
104     GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
105     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
106     GPIO_InitStruct.Pull = GPIO_NOPULL;
107     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
108     GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
109     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
110 
111     /* USART1 DMA Init */
112     /* USART1_RX Init */
113     hdma_usart1_rx.Instance = DMA2_Stream2;
114     hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
115     hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
116     hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
117     hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
118     hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
119     hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
120     hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
121     hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
122     hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
123     hdma_usart1_rx.XferCpltCallback = DMA_M0_RC_Callback;
124     hdma_usart1_rx.XferM1CpltCallback = DMA_M1_RC_Callback;
125     hdma_usart1_rx.XferErrorCallback = DMA_Error_Callback;
126     if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
127     {
128       Error_Handler();
129     }
130 
131     __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
132 
133     /* USART1 interrupt Init */
134     HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
135     HAL_NVIC_EnableIRQ(USART1_IRQn);
136   /* USER CODE BEGIN USART1_MspInit 1 */
137 
138   /* USER CODE END USART1_MspInit 1 */
139   }
140 }
141 
142 void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
143 {
144 
145   if(uartHandle->Instance==USART1)
146   {
147   /* USER CODE BEGIN USART1_MspDeInit 0 */
148 
149   /* USER CODE END USART1_MspDeInit 0 */
150     /* Peripheral clock disable */
151     __HAL_RCC_USART1_CLK_DISABLE();
152 
153     /**USART1 GPIO Configuration
154     PA9     ------> USART1_TX
155     PA10     ------> USART1_RX
156     */
157     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
158 
159     /* USART1 DMA DeInit */
160     HAL_DMA_DeInit(uartHandle->hdmarx);
161 
162     /* USART1 interrupt Deinit */
163     HAL_NVIC_DisableIRQ(USART1_IRQn);
164   /* USER CODE BEGIN USART1_MspDeInit 1 */
165 
166   /* USER CODE END USART1_MspDeInit 1 */
167   }
168 }
169 
170 /* USER CODE BEGIN 1 */
171 //使能DMA
172 void UART_DMA_MultiBuffer(void)
173 {
174     uint32_t u32wk0;
175     
176     SET_BIT(huart1.Instance->CR3,USART_CR3_DMAR);
177     HAL_DMAEx_MultiBufferStart_IT(&hdma_usart1_rx,
178                                   (uint32_t)(&huart1.Instance->DR),
179                                   (uint32_t)&uart_buf[0].data[0],
180                                   (uint32_t)&uart_buf[1].data[0],
181                                    UART_BUFF_SIZE);
182         
183     //这里是解决DMA在启动时,如果接收到大量数据会出现死机的问题
184     u32wk0 = huart1.Instance->SR;  
185     u32wk0 = huart1.Instance->DR;
186     UNUSED(u32wk0);
187 }
188 
189 /* USER CODE END 1 */

在main函数中,加入内容。

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 1 /**
 2   * @brief  The application entry point.
 3   * @retval int
 4   */
 5 int main(void)
 6 {
 7   /* USER CODE BEGIN 1 */
 8 
 9   /* USER CODE END 1 */
10 
11   /* MCU Configuration--------------------------------------------------------*/
12 
13   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
14   HAL_Init();
15 
16   /* USER CODE BEGIN Init */
17 
18   /* USER CODE END Init */
19 
20   /* Configure the system clock */
21   SystemClock_Config();
22 
23   /* USER CODE BEGIN SysInit */
24 
25   /* USER CODE END SysInit */
26 
27   /* Initialize all configured peripherals */
28   MX_GPIO_Init();
29   MX_DMA_Init();
30   MX_USART1_UART_Init();
31   /* USER CODE BEGIN 2 */
32     queue_mes = xQueueCreate(10, sizeof(usart_multibuffer_data));
33     UART_DMA_MultiBuffer(); 
34   /* USER CODE END 2 */
35 
36   /* Init scheduler */
37   osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */
38   MX_FREERTOS_Init();
39   /* Start scheduler */
40   osKernelStart();
41 
42   /* We should never get here as control is now taken by the scheduler */
43   /* Infinite loop */
44   /* USER CODE BEGIN WHILE */
45   while (1)
46   {
47     /* USER CODE END WHILE */
48 
49     /* USER CODE BEGIN 3 */
50   }
51   /* USER CODE END 3 */
52 }

在freertos.c文件中

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 1 extern usart_multibuffer_data uart_buf[2];
 2 extern QueueHandle_t queue_mes;  
 3 usart_multibuffer_data queue_data;
 4 
 5 /* USER CODE BEGIN Header_StartDefaultTask */
 6 /**
 7   * @brief  Function implementing the defaultTask thread.
 8   * @param  argument: Not used
 9   * @retval None
10   */
11 /* USER CODE END Header_StartDefaultTask */
12 void StartDefaultTask(void *argument)
13 {
14   /* USER CODE BEGIN StartDefaultTask */
15     BaseType_t ret = pdFALSE;
16   /* Infinite loop */
17   for(;;)
18   {
19     ret = xQueueReceive(queue_mes,&queue_data,portMAX_DELAY);
20     if(ret == pdTRUE)
21     {
22         HAL_UART_Transmit(&huart1,queue_data.data,queue_data.len,100);
23     }
24   }
25   /* USER CODE END StartDefaultTask */
26 }

 

实验效果

STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收

 

时代越来越好,开发效率越来越高,希望能帮助到你!!!

还有就是,开源万岁。

 

到了这里,关于STM32F429 Discovery开发板应用:使用FreeRTOS队列+DMA双缓存实现串口数据接收的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32F429移植microPython笔记

    https://micropython.org/download/官网 下载后放在linux中。 解压命令: 进入micropython目录下,进入mpy-cross目录,先编译MicroPython cross-compiler,在终端输入: 进入/ports/stm32/boards目录中,将目录STM32F429DISC拷贝一份为MY_STM32F429DISC。 然后进入MY_STM32F429DISC目录中修改mpconfigboard.h和stm32f4xx_ha

    2024年02月01日
    浏览(39)
  • GD32F470 移植STM32F429工程 Keil调试笔记

    keil版本:5.25 安装 GigaDevice.GD32F4xx_DFP.3.0.4.pack Keil.STM32F4xx_DFP.2.15.0.pack 1、原项目为STM32F429 工程,切换到GD32F470 只需在 Options for Target\\\"“对话框的Device菜单中选中“GD32F470II”,重新编译即可,一般不会有编译错误。 2、将项目工程在切换回STM32F429,在 Options for Target”\\\"对话框的D

    2024年02月09日
    浏览(40)
  • STM32F103xx / STM32F429VET6最小系统原理图

    STM32F429VET6核心板原理图 2023.12.09修改内容:打板后由于更换学习方向并未进行测试,所给原理图仅供参考,给出PDF下载链接,未设置积分和会员下载:https://download.csdn.net/download/m0_51294753/88611702。 一、前言 先前使用过的是STM32F1系列,只使用和绘制过STM32F103C8T6和STM32F103ZET6的板

    2023年04月24日
    浏览(37)
  • STM32F429IGT6使用CubeMX配置SPI通信(W25Q256芯片)

    1、硬件电路 需要系统性的看一下W25Q256芯片手册  2、设置RCC,选择高速外部时钟HSE,时钟设置为180MHz 3、配置SPI 4、生成工程配置   5、读写流程图 5、相关代码 6、实验现象 没有问题!

    2024年02月12日
    浏览(37)
  • 【STM32F429】HAL库的PWM中断,精确控制脉冲数,控制步进电机

    这两天在调步进电机,希望是使得步进电机每次都达到期望的高度。在查了一天的资料,发现大部分上传的资料都是使用CubeMX生成的,可复制性很高,但未免有失可读性,故上传我的心得经验。 本来原子哥的例程里有整合度很高的,已经封装好的精确控制步进电机前进距离的

    2024年02月08日
    浏览(41)
  • STM32F407 移植 FreeRTOS

    本实验是基于正点原子 STM32F407ZG 探索者开发板完成的,所以需要一个STM32F407ZG 探索者开发板 用于移植的基础工程(下面会讲) FreeRTOS源码(下面会讲) 本实验所有用到的代码:基于正点原子STM32F407的FreeRTOS移植工程.zip 1.1 移植前准备 1.1.1 基础工程 由于后续需要用到 LED、

    2024年02月08日
    浏览(58)
  • 搭建STM32F407的Freertos系统(基于STM32CubeMX)

           本人长期开发Linux、Windows上应用软件,一直以来MCU开发有所接触,但较少(最近项目需要,小公司么,都得会,被逼的),好在有STM32CubeMX这样工具,貌似就是我想要的工具。         本次demo目标立下:         1. 搭建或移植FreeRTOS到STM32上,毕竟对于长期在Linux环境

    2024年02月10日
    浏览(51)
  • 五、修改官方FreeRTOS例程(STM32F1)

    (1)进入FreeRTOS官网:FreeRTOS官网 (2)下载FreeRTOS。(选择带示例的下载) (1)下载后解压的FreeRTOS文件如下图所示。 (2)删除下图中红框勾选的文件。 FreeRTOS-Plus,FreeRTOS的生态文件,非必需的。 tools,这里面是亚马逊相关的文件,不需要。 (3)删除\\\"FreeRTOSv202212.01FreeRTOSDemo\\\"目录下用不到

    2024年02月11日
    浏览(35)
  • FreeRTOS移植STM32超详细(以STM32F103ZE为例)

    我刚学FreeROTS时想移植到STM32,找了网上很多资料,但大多都不是很完整,于是我把我自己的移植过程分享出来,供大家参考。 我们以STM32F103ZE,正点原子的跑马灯实验为例, 准备工作: 跑马灯实验工程 FreeRTOS文件源码(可在官方下载)     第一步  移植文件到工程 首先在工

    2024年02月08日
    浏览(29)
  • 【学习日记】【FreeRTOS】FreeRTOS 移植到 STM32F103C8

    本文基于野火 FreeRTOS 教程,内容是关于 FreeRTOS 官方代码的移植的注意事项,并将野火例程中 STM32F103RC 代码移植到 STM32F103C8。 两个下载链接: 官 网 代码托管 Source:内核源码,我们需要的主要内容 根目录:这里的 C 文件都是由 C 语言编写的,所以在各种单片机上是通用的

    2024年02月11日
    浏览(40)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包