[其他ST产品] 使用STM32CUBE MX创建STM32F407工程 串口DMA加空闲中断任意长度收发

[复制链接]
924|15
 楼主| wangtaohui 发表于 2023-5-28 00:36 | 显示全部楼层 |阅读模式
使用STM32CUBE MX创建STM32F407工程 串口DMA加空闲中断任意长度收发

一、使用平台

    STM32F407VET6

    KEIL 5 5.25

    STM32CUBE MX 4.25

145636472318216533.png

334736472318962ece.png


 楼主| wangtaohui 发表于 2023-5-28 00:37 | 显示全部楼层
配置

    LED连接在单片机PB9,串口使用UART1,PA9,PA10。

1.打开stm32cube,新建工程
7158647231a15969b.png
10408647231aa68a05.png
使能外部晶振,串口,LED(GPIOB,9).
 楼主| wangtaohui 发表于 2023-5-28 00:37 | 显示全部楼层
2.配置时钟树
82730647231bfa3775.png
 楼主| wangtaohui 发表于 2023-5-28 00:37 | 显示全部楼层
3.详细配置

1.串口参数配置:
86604647231e5e41bc.png
 楼主| wangtaohui 发表于 2023-5-28 00:38 | 显示全部楼层
串口使用DMA,大大节省CPU开支。
94165647231f0a45a4.png
 楼主| wangtaohui 发表于 2023-5-28 00:43 | 显示全部楼层
串口使用DMA,大大节省CPU开支。 44584647233210dfec.png
 楼主| wangtaohui 发表于 2023-5-28 00:44 | 显示全部楼层
配置中断优先级:
68492647233623be60.png
 楼主| wangtaohui 发表于 2023-5-28 00:44 | 显示全部楼层
配置LED -pin 923946472336ddf249.png
 楼主| wangtaohui 发表于 2023-5-28 00:44 | 显示全部楼层
2.配置输出工程 85416647233781f70c.png
 楼主| wangtaohui 发表于 2023-5-28 00:44 | 显示全部楼层
 楼主| wangtaohui 发表于 2023-5-28 00:45 | 显示全部楼层
三、代码修改

1.

uart.h

头文件中添加UART结构体:

/* USER CODE BEGIN Private defines */
#define RX_LEN 1024  
         
typedef struct  
{  
uint8_t  RX_flag:1;        //IDLE receive flag
uint16_t RX_Size;          //receive length
uint8_t  RX_pData[RX_LEN]; //DMA receive buffer
}USART_RECEIVETYPE;  
   
extern USART_RECEIVETYPE UsartType;
/* USER CODE END Private defines */
 楼主| wangtaohui 发表于 2023-5-28 00:45 | 显示全部楼层
uart.c
  1. /* USER CODE BEGIN 0 */
  2. USART_RECEIVETYPE UsartType;
  3. /* USER CODE END 0 */
 楼主| wangtaohui 发表于 2023-5-28 00:45 | 显示全部楼层
  1. /* USER CODE BEGIN 1 */

  2. void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
  3. {  
  4.     uint32_t temp;  
  5.   
  6.     if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
  7.     {   
  8.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);  
  9.         HAL_UART_DMAStop(&huart1);  
  10.         temp = huart1.hdmarx->Instance->NDTR;  
  11.         UsartType.RX_Size =  RX_LEN - temp;   
  12.         UsartType.RX_flag=1;  
  13.         HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN);  
  14.     }  
  15. }
  16. /* USER CODE END 1 */
 楼主| wangtaohui 发表于 2023-5-28 00:45 | 显示全部楼层
在main函数中的while(1)之前添加串口DMA使能函数,开启串口空闲中断。

在主循环中添加FLAG检测,如果使用RTOS,则在进程中检测。
  1.   /* USER CODE BEGIN 2 */
  2.        
  3.         HAL_UART_Receive_DMA(&huart1, UsartType.RX_pData, RX_LEN);  
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
  5.        
  6.        
  7.   /* USER CODE END 2 */

  8.   /* Infinite loop */
  9.   /* USER CODE BEGIN WHILE */
  10.   while (1)
  11.   {

  12.   /* USER CODE END WHILE */

  13.   /* USER CODE BEGIN 3 */

  14.         if(UsartType.RX_flag)            // Receive flag
  15.                 {  
  16.                         UsartType.RX_flag=0;        // clean flag
  17.                         HAL_UART_Transmit_DMA(&huart1, UsartType.RX_pData, UsartType.RX_Size);
  18.                 }
  19.   }
  20.   /* USER CODE END 3 */
 楼主| wangtaohui 发表于 2023-5-28 00:45 | 显示全部楼层
最后别忘了  一定要在串口中断中调用串口空闲中断回调函数。
  1. void USART1_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USART1_IRQn 0 */
  4.         UsartReceive_IDLE(&huart1);
  5.   /* USER CODE END USART1_IRQn 0 */
  6.   HAL_UART_IRQHandler(&huart1);
  7.   /* USER CODE BEGIN USART1_IRQn 1 */

  8.   /* USER CODE END USART1_IRQn 1 */
  9. }
 楼主| wangtaohui 发表于 2023-5-28 00:46 | 显示全部楼层
OK,大功告成!!!!

工程下载地址:https://download.csdn.net/download/medojonh/10381613
您需要登录后才可以回帖 登录 | 注册

本版积分规则

43

主题

529

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部