我只添加了接收DMA
中断配置
然后生成
代码首先打开空闲中断,同时设置DMA传输,我们直接设置为缓存区的长度
Clear_Usart(&usart1_rx);//初始化串口结构体 __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);//使能空闲中断 HAL_UART_Receive_DMA(&huart2, (uint8_t*)usart1_rx.rx_buff, RX_BUF_MAX_LEN);//设置DMA传输,串口2的数据搬运到缓存中
下边是中断函数
void USART2_IRQHandler(void) { /* USER CODE BEGIN USART2_IRQn 0 */ /* USER CODE END USART2_IRQn 0 */ HAL_UART_IRQHandler(&huart2); /* USER CODE BEGIN USART2_IRQn 1 */ if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET)//产生空闲中断(说明接收完) { __HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除空闲中断标志(否则会一直不断进入中断) HAL_UART_DMAStop(&huart2);//停止本次DMA传输 usart1_rx.len = RX_BUF_MAX_LEN - __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);//计算接收到的数据长度 usart1_rx.flag = 1; if(usart1_rx.len == 0){//防止误入 usart1_rx.flag = 0; HAL_UART_Receive_DMA(&huart2, (uint8_t*)usart1_rx.rx_buff, RX_BUF_MAX_LEN);//设置DMA传输,串口2的数据搬运到缓存中 HAL_UART_DMAResume(&huart2);//恢复DMA传输 } } /* USER CODE END USART2_IRQn 1 */ }
把重新接收放进主程序里,以防丢包
if(usart1_rx.flag){//判断接收完成 printf("%s\r\n",usart1_rx.rx_buff);//打印出数据 if(strstr((const char *)usart1_rx.rx_buff, "LED_ON") != NULL){//如果匹配到数据LED_ON HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET); printf("Turn on the LED\r\n"); } else if(strstr((const char *)usart1_rx.rx_buff, "LED_OFF") != NULL){//如果匹配到数据LED_OFF HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET); printf("Turn off the LED\r\n"); } else {//不匹配打印error printf("error\r\n"); } Clear_Usart(&usart1_rx);//清空串口结构体 HAL_UART_Receive_DMA(&huart2, (uint8_t*)usart1_rx.rx_buff, RX_BUF_MAX_LEN);//设置DMA传输,串口2的数据搬运到缓存中 HAL_UART_DMAResume(&huart2);//恢复DMA传输 }效果跟上次一样