DMA
首先,DMA相当于CPU的弱智小助手,不会复杂的逻辑运算,不占用CPU的时间,DMA就是一个数据搬运工。
串口收发数据,不外乎就是,CPU需要发数据时,将数据丢给DMA,完事就不管了,收数据是,相当于你的微信收到消息一样,但消息早已经收到了,只是响了一下告诉CPU收到了数据。
其他基础配置,自己看着办。
__HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE); HAL_UART_Receive_DMA(&huart2,rx_buffer,RXBUFFERSIZE);
这个两个丢main函数里面,相当于开启了DMA接收,然后接收完要告诉CPU还是回到串口中断里去,做好事不留名。
uint8_t rx_buffer[RXBUFFERSIZE];//接收数组
volatile uint8_t rx_len = 0; //接收到的数据长度
volatile uint8_t recv_end_flag = 0; //接收结束标志位
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 */uint8_t tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位if((tmp_flag != RESET))//通过标志位判断接收是否结束{ recv_end_flag = 1; //置1表明接收结束__HAL_UART_CLEAR_IDLEFLAG(&huart2);//清除标志位HAL_UART_DMAStop(&huart2); uint8_t temp=__HAL_DMA_GET_COUNTER(&hdma_usart2_rx); rx_len =RXBUFFERSIZE-temp; //计算出数据长度
// HAL_UART_Transmit_DMA(&huart2, rx_buffer,rx_len);//将受到的数据发送出去HAL_UART_Receive_DMA(&huart2,rx_buffer,RXBUFFERSIZE);//开启DMA接收,方便下一次接收数据}/* USER CODE END USART2_IRQn 1 */
}
发送时
HAL_UART_Transmit_DMA(&huart2,(uint8_t *)"Hello\r\n",sizeof("Hello\r\n"));
接收时recv_end_flag =1;就是接收完成了
其他加DMA的原理几乎一样。