目录
一、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