[STM32F1] 串口DMA回传数据

[复制链接]
1510|18
 楼主| jsh560 发表于 2023-8-26 16:44 | 显示全部楼层 |阅读模式

屏幕截图 2023-08-26 000016.png

请教个问题:
使用USAT0 DMA空闲中断收发数据,都能成功,但发现数据的多的时候, 在新建的返回数据函数,在 HAL_UART_Transmit_DMA(&huart1, rxbuffer1,rxlen);                后需要延时50ms, 才能返回成功,否则返回数据有部门是错误的。

但有一个回调函数,是在中断响应函数里面调用的,
        if(huart == &huart1)  //判断是否为串口1产生中断
        {         
         HAL_UART_Transmit_DMA(&huart1, rxbuffer1,rxlen);//将接收到的不定长数据发送到上位机
             rxlen = 0;//清除数据长度计数
                 HAL_UART_Receive_DMA(&huart1,rxbuffer1,BUFFER_SIZE);//重新打开DMA接收
        }

在   HAL_UART_Transmit_DMA(&huart1, rxbuffer1,rxlen); 后就可以不加延时,请问这个是哪的原因勒?
屏幕截图 2023-08-25 235717.png
zyf部长 发表于 2023-8-27 12:08 | 显示全部楼层
需要延时50ms 才能返回成功
 楼主| jsh560 发表于 2023-8-27 21:43 | 显示全部楼层
zyf部长 发表于 2023-8-27 12:08
需要延时50ms 才能返回成功

回调函数里面就不需要延时勒
caoenq 发表于 2023-8-28 08:41 | 显示全部楼层
中断里面加延时是很危险的
elife 发表于 2023-8-28 09:27 | 显示全部楼层
因为串口传输数据需要时间,需要等待串口中断中DMA完成后,才可以再次DMA传输。DMA传输完成,会调用HAL_UART_TxCpltCallback函数,可以在该函数中设置完成标志,在大循环中判断标志再开启DMA传输。如果在中断回调函数中可以再次开启,说明HAL框架已经清除了标志,考虑到在中断中开始的问题了。另外HAL_UART_Transmit_DMA是有返回参数的,可以判断错误原因。
Mowergy 发表于 2023-9-2 19:32 | 显示全部楼层
要等待串口中断中DMA完成后,才可以再次DMA传输
Stahan 发表于 2023-9-2 21:02 | 显示全部楼层
中断加延迟会严重拖慢程序速度的
Jacquetry 发表于 2023-9-4 21:59 | 显示全部楼层
zyf部长 发表于 2023-8-27 12:08
需要延时50ms 才能返回成功

加延时很危险的吧
 楼主| jsh560 发表于 2023-9-12 22:26 | 显示全部楼层
**有大神路过,帮忙指点下咯。谢谢
Stahan 发表于 2023-9-13 23:21 | 显示全部楼层
发送跟接收不能一块进行吧
香水城 发表于 2023-9-14 09:37 | 显示全部楼层
没看明白你的问题。难道你不是基于IDLE事件 而是基于接收事件?

如果你基于IDLE事件来回传数据,是不需要什么延时的。
MessageRing 发表于 2023-9-14 23:18 | 显示全部楼层
为什么要加延时啊
 楼主| jsh560 发表于 2023-9-24 22:34 | 显示全部楼层
MessageRing 发表于 2023-9-14 23:18
为什么要加延时啊

我也不想加延时啊,如果不加延时,STM32收到的数据,再返回给串口助手,串口助手收到的数据就与发送的不对。所有开贴问大神有没有指点的?
我的逻辑是:PC串口助手下发数据到STM32串口空闲中断接收,接收后再把数据自动返回给串口助手。  不加延时错误就在串口助手收到的数据与发送的不对,在STM32上 发数据的程序里面加点延时,就能做到上发与返回数据一致不掉包。
 楼主| jsh560 发表于 2023-9-24 22:40 | 显示全部楼层
香水城 发表于 2023-9-14 09:37
没看明白你的问题。难道你不是基于IDLE事件 而是基于接收事件?

如果你基于IDLE事件来回传数据,是不需要 ...

是基于IDLE事件接收数据,接收完成后再主程序里面再把接收到的数据返回到上位机助手。  
网上下载的案例程序中,接收的数据是一个回调函数,数据也是接收完成后返回上位机,----里面不要延时就能返回数据。
我改了下 自己新建了一个子函数,如果数据数据太长,就需要在STM32返回数据的子函数里面加延时才能做到上位机下发的,  与STM32返回串口助手的收到的数据一致。 上面的程序截图中,有延时的函数就是自己写的,上面子函数就是下载案例中的回调函数,里面就没延时。
香水城 发表于 2023-10-23 16:03 | 显示全部楼层
jsh560 发表于 2023-9-24 22:40
是基于IDLE事件接收数据,接收完成后再主程序里面再把接收到的数据返回到上位机助手。  
网上下载的案例 ...

嗯,看到你说的两款代码了。

这要仔细比较两种代码写法 导致了哪些时序的差异。

感觉你的代码不加延时,立即重启通信 时有些地方似乎没准备好。

你不妨详细比较下两种代码写法的差异。
周半梅 发表于 2024-1-9 10:10 | 显示全部楼层

一种了解状态变化的简单方法
Clyde011 发表于 2024-1-9 15:15 | 显示全部楼层

错误的比较大的Ⅵ乘积结果
公羊子丹 发表于 2024-1-9 16:08 | 显示全部楼层

定时器输出引脚的设定
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

124

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部