|
我想用 DMA 通过串口输出单个字符。 首先将 DMA 配置为普通单次模式,初始化代码如下: huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); hdma_usart2_tx.Instance = DMA1_Stream6; hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4; hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart2_tx.Init.Mode = DMA_NORMAL; hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; HAL_DMA_Init(&hdma_usart2_tx); __HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx); 主循环之外只添加了这段发送代码,while (1) 里只有 LED 闪烁逻辑: HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"b",1); 普通 DMA 模式下,串口只输出一次字符a,随后 LED 开始闪烁,字符b没有输出。 如果改成发送长字符串再加两个单字符: char testMessage[] = "test output of a longer string\r\n"; HAL_UART_Transmit_DMA(&huart2,(uint8_t)&testMessage,sizeof(testMessage)-1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t*)"b",1); 最终只能收到完整字符串,a和b依旧不会发送出来。 如果把 DMA 配置改成循环模式(DMA_CIRCULAR),其余初始化不变,再次执行单次发送代码: HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"b",1); 串口会持续不断重复输出a,LED 同步闪烁,b不出现。 如果同样搭配长字符串一起发送: char testMessage[] = "test output of a longer string\r\n"; HAL_UART_Transmit_DMA(&huart2,(uint8_t)&testMessage,sizeof(testMessage)-1); HAL_UART_Transmit_DMA(&huart2,(uint8_t)"a",1); HAL_UART_Transmit_DMA(&huart2,(uint8_t*)"b",1); 字符串会无限循环重复发送,a和b依旧无输出。 查阅手册 UM1725《STM32F4xx HAL 驱动说明》846 页关于串口 DMA 的描述: Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA() At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can add his own code by customization of function pointer HAL_UART_TxCpltCallback 为什么 DMA 模式只能发送一次数据,后续所有发送请求全部失效;循环 DMA 模式会无限重复第一条发送内容,后面的发送指令不生效? 麻烦各位帮忙解答一下。 |
串口DMA收发出现ORE错误
STM32 增加 WiFi + 以太网的低成本方案
在RS485通信中如何有效避免误码,距离5米,速率115200
STM32F103C8T6 上电后无法通过串口发出数据的问题?
UART中IDLE 中断与 RTO 接收超时中断有什么区别
I2C 错误代码含义
在 LwIP_HTTP_Server_Netconn_RTOS 工程中添加 USART3 功能时遇到问题
串口+DMA发数据
stm32使用hal库数据疑问
stm32使用hal库开发串口通讯问题
微信公众号
手机版
你这还没有理解DMA异步传输的本质吧。
HAL_UART_Transmit_DMA开启传输后,函数就立即返回了,这时候数据实际上还在传输过程中你就开始启动下一次HAL_UART_Transmit_DMA,这必然会导致第二次乃至后续的传输都直接返回BUSY的错误。
正确的做法是每次开启下次传输时确保上一次的传输已经完成。可用配合DMA传输完成中断实现。
对于你每次传输单个字节的情况,使用中断传输比使用DMA要更好,当然这也需要处理传输完成同步的问题。
然后很多系列都有例程可以参考。
[md]也就是说在下次传输前检测状态