STM32串口IDLE中断接收+DMA(HAL库)

您所在的位置:网站首页 串口助手编写 STM32串口IDLE中断接收+DMA(HAL库)

STM32串口IDLE中断接收+DMA(HAL库)

2023-07-01 17:52| 来源: 网络整理| 查看: 265

目录

一、CubeMX配置

二、程序编写

三、最终结果

一、CubeMX配置

1、打开异步串口,配置相关参数:

2、使能发送和接收DMA,模式配置为单次发送,也就是每次发送完之后需要手动开启DMA,这样可以使得接收数据的过程更好控制;选择Memory地址自增,也就是每存一个数据,地址指针自动加1;数据宽度选择Byte:

 3、打开串口中断,并按需配置中断优先级,然后生成代码:

二、程序编写

1、首先在usart.h中,定义所需要用到的变量,这里我定义了一个串口数据结构体,并声明为外部变量:

#define BUFFER_SIZE 1024 //Receive datas size //Define struct of the receive data typedef struct { volatile uint16_t rx_len; volatile uint8_t recv_end_flag; uint8_t* rx_buf; }UART_RxData_t; extern UART_RxData_t rx_datas;

2、然后在usart.c中初始化串口数据结构体,并在MX_USART2_UART_Init串口初始化函数中调用串口空闲中断函数以及开启串口DMA接收:

/* USER CODE BEGIN 0 */ uint8_t rx_buffer[BUFFER_SIZE]={0};//Define receive array UART_RxData_t rx_datas = { //define receive data .recv_end_flag = 0, .rx_len = 0, .rx_buf = rx_buffer }; /* USER CODE END 0 */ /* USER CODE BEGIN USART2_Init 2 */ __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);//Enable IDLE interrupt HAL_UART_Receive_DMA(&huart2, rx_datas.rx_buf, BUFFER_SIZE);//Start RX DMA /* USER CODE END USART2_Init 2 */

 3、接着去到stm32f1xx_it.c中断函数文件中,找到串口中断函数USART2_IRQHandler,并添加如下代码:

/** * @brief This function handles USART2 global interrupt. */ void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ //IDLE interrupt if(RESET != __HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE)) { __HAL_UART_CLEAR_IDLEFLAG(&huart2); HAL_UART_DMAStop(&huart2); //Stop RX DMA //Get the receive datas len rx_datas.rx_len = BUFFER_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx); rx_datas.recv_end_flag = 1;//Mark the end of receive } /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ /* USER CODE END USART2_IRQn 1 */ }

 4、最后在主循环中判断接收标志位是否为1,再将数据发回到上位机:

/* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ if(rx_datas.recv_end_flag) { rx_datas.recv_end_flag = 0;//Clear flag //Send the datas of receive if(HAL_OK != HAL_UART_Transmit_DMA(&huart2, rx_datas.rx_buf, rx_datas.rx_len)) { Error_Handler(); } rx_datas.rx_len = 0; HAL_UART_Receive_DMA(&huart2, rx_datas.rx_buf, BUFFER_SIZE);//Start receive } } /* USER CODE END 3 */  三、最终结果

 

可以看到给下位机发了700多个字符也能全部发送回上位机。

PS.代码仅作为学习记录,至于为什么心血来潮用英文写注释,完全是因为用中文写注释的时候,我用VSCode打开用CubeMX生成的新Keil工程后,中文乱码了。。。没办法,只能当作好好学习英语了~~~

以上均为个人学习心得,如有错误,请不吝赐教~

THE END



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3