DMA+UART实现串口不定长接收和发送功能

简介

需要用到单片机的人基本上都需要用到串口功能,看了好多教程提供的是中断接收和发送功能。但是通过中断收发数据有不少弊端。其一:中断影响程序的运行速度。(想想发一个字节中断就中断一次,难受!!!)其二:频繁中断丢数据的概率大了很多。有没有方法解决这两个隐患尼?DMA( Direct Memory Access)直接存储器访问,强大的小老二。专门帮CPU干些劳苦的事。DMA最大的好处就是干啥只要老大一句话,乖乖的就去执行。下面介绍DMA+uart实现串口接收发送功能。
加群 912452346 下载源代码

基本功能了解

UART

好的,以下是一个 CubeIDE STM32 DMA 接收不定 Modbus 的示例: 1. 首先,需要在 CubeIDE 中配置 DMA串口。具体的配置方式可以参考 STM32 官方文档和示例代码。 2. 在代码中,需要定义一个接收缓冲区和一个接收计数器: ``` #define RX_BUFFER_SIZE 256 uint8_t rx_buffer[RX_BUFFER_SIZE]; uint16_t rx_counter = 0; ``` 3. 在 DMA 配置中,需要将数据传输的度设置为接收到的数据度。具体的配置代码如下: ``` /* Configure DMA */ hdma_usart_rx.Instance = DMA1_Stream5; hdma_usart_rx.Init.Channel = DMA_CHANNEL_4; hdma_usart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart_rx.Init.Mode = DMA_CIRCULAR; hdma_usart_rx.Init.Priority = DMA_PRIORITY_HIGH; hdma_usart_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_usart_rx) != HAL_OK) { Error_Handler(); } /* Configure DMA interrupt */ __HAL_DMA_ENABLE_IT(&hdma_usart_rx, DMA_IT_TC); /* Start DMA reception */ HAL_UART_Receive_DMA(&huart2, rx_buffer, RX_BUFFER_SIZE); ``` 4. 在 DMA 中断中,需要将接收到的数据度累加到接收计数器中,并进行数据帧解析。具体的代码如下: ``` void DMA1_Stream5_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma_usart_rx); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { /* Reset DMA reception */ HAL_UART_DMAStop(huart); HAL_UART_Receive_DMA(huart, rx_buffer, RX_BUFFER_SIZE); /* Process received data */ uint16_t len = RX_BUFFER_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx); for (uint16_t i = rx_counter; i < (rx_counter + len); i++) { if ((rx_buffer[i] == 0x01) && (rx_buffer[i + 1] == 0x03)) { /* Modbus data frame found, do something */ // ... } } rx_counter += len; } ``` 在上述代码中,我们在 DMA 中断中使用了 HAL_UART_RxCpltCallback() 回调函数来处理接收到的数据。当接收到完整的数据帧时,我们可以在 if 语句中进行数据处理。同时,需要注意在回调函数中重启 DMA 接收以保证能够接收到连续的数据帧。 希望以上示例代码能够帮助到您。如果您还有其他问题或疑问,欢迎随时向我提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值