DMA,即直接存储器访问,用于在外设与存储器之间以及存储器与存储器之间提供一种高速数据传输的方式。用在串口中就是它可以不经过cpu处理,直接把串口接收到的数据搬运到串口缓存区,就可以省去我们用串口接收中断一个一个把数据存到缓存区的步骤.下面开始操作先点
我只添加了接收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传输
}效果跟上次一样
我要赚赏金
