为啥dma只接收最后一个字符
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥dma只接收最后一个字符相关的知识,希望对你有一定的参考价值。
通常采用DMA做USART接收固定长度的数据,或通过DMA完成固定数量的不间断数据流。不固定长度数据接收需要起始符和结尾符,这样就需要在每一次RX的中断后做字符检测(可参考MODBUS-ASCii),或采用接收最后一个字符后停顿超过预定时间来检测数据完结,同样需要RX中断(可参考MODBUS-RTU)。这跟用DMA减少中断开销的原意违背。如真想用DMA,可以试试这方法,前提是主循环没有太多对实时性影响的工作:
不采用DMA完成中断,在主循环里polling当前DMA的计数器得知最新一个数据在Buffer的位置,然后检测结尾符,if收到结尾符后对buffer所有数据做处理。
细节你可以自行分析一下,看看跟你原程序有没有矛盾。 参考技术A
因为cubeMX/CubeIDE生成的代码顺序导致了bug.
以下是cube自动生成的初始化代码:
/* Initialize all configured peripherals */MX_GPIO_Init();
MX_USART1_UART_Init();
MX_DMA_Init();
/* USER CODE BEGIN 2 */
但是这样会导致DMA出问题. 需要将DMA的初始化放到UART初始化的前面:
/* Initialize all configured peripherals */MX_GPIO_Init();
MX_DMA_Init();//交换顺序
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
然后就正常了.
并记住,每次重新生成代码后都要手动更改顺序
为啥 UART w/DMA 只接收发送数据的最后一个字节?
【中文标题】为啥 UART w/DMA 只接收发送数据的最后一个字节?【英文标题】:Why is UART w/DMA only receiving last byte of sended data?为什么 UART w/DMA 只接收发送数据的最后一个字节? 【发布时间】:2021-10-24 16:39:36 【问题描述】:
这是应该继续接收字节的UARTEx_RxEventCallback()
函数。在这里您可以在 Hercules 屏幕中看到,我发送了123456789
,但它只接收到最后一个字节。为什么会这样。我的 DMA 设置设置为正常(不是循环)、外设到内存、字节。 NVIC 中断复选框已启用。一切都设置好了。
这是我的主要任务。
【问题讨论】:
请将您的代码发布为文本而不是图像。见meta.***.com/a/285557/413337 在第一张图片中,代码无关紧要。您必须查看屏幕截图的右侧。这是我问题的重要部分。这里实际上没有与代码相关的问题! 【参考方案1】:由于初始化顺序,您的 DMA 无法正常工作,您必须在 UART/USART 之前初始化 DMA,如下所示:
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART3_UART_Init();
【讨论】:
【参考方案2】:看起来你没有增加内存地址,所以数据总是复制到数组的第一个元素。 hdma_usart3_rx.Init.MemInc 应该是 DMA_MINC_ENABLE
【讨论】:
请在您的回答中提供更多详细信息。正如目前所写的那样,很难理解您的解决方案。 我确实增加了内存地址:hdma_usart3_rx.Init.MemInc = DMA_MINC_ENABLE;
以上是关于为啥dma只接收最后一个字符的主要内容,如果未能解决你的问题,请参考以下文章
我在用STM32串口DMA接收数据时,为啥在接收过程中,我的程序停止运行了,接收完成后又开始运行,求解?
STM32中串口DMA实验里,为啥选择通道4(选择串口的发送端,而不是接收端)?