硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1926|回复: 6
收起左侧

[有问必答] 串口DMA+空闲中断如何判断接收完一组数据?

[复制链接]

1

主题

0

回帖

3

积分

新手上路

积分
3
发表于 2025-1-27 17:21:40 | 显示全部楼层 |阅读模式
在学习使用环形缓冲区结合串口DMA+空闲中断接收数据的时候发现,比如我的环形缓冲区大小是10,那么在接收到一个数据的时候,此时触发的是串口的空闲中断,如果再接收4个数据,那么会触发一次DMA半满中断和一次串口空闲中断,再接收5个数据后只触发了一次DMA全满中断,不触发空闲中断。我是判断触发空闲中断的时候就认为接收完一组数据了,但是如果接受完一组数据后刚好触发了DMA全满中断,此时不会触发空闲中断,就丢失一次数据的处理,不知道怎么才能解决这个问题啊?
屏幕截图 2025-01-27 171850.png
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
122007
QQ
发表于 2025-2-1 05:22:29 | 显示全部楼层
空闲中断不适合作为帧结束,只能作为本次数据结束标识,帧结束还是需要做协议判断才合理。

触发空闲后,终止本次DMA接收,下次使用要重新启动DMA+空闲。

新的HAL库程序里面已经封装了对应的API,直接调用即可。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2025-2-18 09:59:52 | 显示全部楼层
我今天也碰到了这个问题,找了一下原因。(在既全满,也空闲时)在触发全满中断时,其实也触发了一次空闲中断,在UART的中断内部对数据长度进行了一次判定,其中有一条约束条件就是需要DMA当前接收的数据小于DMA设置的值,才能进行空闲回调。所以才导致全满时没有触发空闲回调
回复

使用道具 举报

46

主题

251

回帖

389

积分

高级会员

积分
389
发表于 2026-2-28 19:37:44 | 显示全部楼层
冬言 发表于 2025-2-18 09:59
我今天也碰到了这个问题,找了一下原因。(在既全满,也空闲时)在触发全满中断时,其实也触发了一次空闲中 ...

我也发现了,怎么办?完全不想写代码
回复

使用道具 举报

1万

主题

7万

回帖

12万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
122007
QQ
发表于 2026-3-1 09:24:32 | 显示全部楼层
snakeemail 发表于 2026-2-28 19:37
我也发现了,怎么办?完全不想写代码

使用函数HAL_UARTEx_ReceiveToIdle_DMA做超时接收整理:
1、半DMA传输完成中断UART_DMARxHalfCplt     调用  HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
2、DMA传输完成中断UART_DMAReceiveCplt       调用   HAL_UARTEx_RxEventCallback,标识继续为HAL_UART_RECEPTION_TOIDLE
3、如果传输期间触发了空闲,DMA又没有传输完成,调用串口中断HAL_UART_IRQHandler,空闲标识处理的HAL_UARTEx_RxEventCallback,并设置HAL_UART_RECEPTION_STANDARD
回复

使用道具 举报

46

主题

251

回帖

389

积分

高级会员

积分
389
发表于 2026-3-2 18:20:48 | 显示全部楼层
eric2013 发表于 2026-3-1 09:24
使用函数HAL_UARTEx_ReceiveToIdle_DMA做超时接收整理:
1、半DMA传输完成中断UART_DMARxHalfCplt      ...

谢谢。因为有时候我的数据,可能分两段发来。用如下方式实现。
1.DMA模式为cricle模式,
2. 关闭半中断,或者判断是半中断就退出
3. 依靠空闲事件和满事件,把写指针更新
4. 主程序发现写指针更新,就读,直到读指针等于写指针。
5.发生错误时,用abort函数重置,然后再重启空闲dma中断。
这样永远不用关dma,
迷糊的地方是,中断函数传来的size,当满中断时,它又变成0了。
其实最简单的方法,就是只开空闲接收中断,但是和dma发送有冲突。搞了半天,放弃了。就用上面的方法。
回复

使用道具 举报

0

主题

5

回帖

5

积分

新手上路

积分
5
发表于 2026-3-31 14:41:58 | 显示全部楼层
snakeemail 发表于 2026-3-2 18:20
谢谢。因为有时候我的数据,可能分两段发来。用如下方式实现。
1.DMA模式为cricle模式,
2. 关闭半中断 ...

可以直接用dma循环模式,用HAL_UARTEx_RxEventCallback传递的Size以及RxEventType的状态来判定是否是一完整数据。st的每个系列的单片机的hal库可能都有点区别,得实际写个demo测一下。
dma循环模式下的串口关半中断真的不会有问题吗?如果我外部一包数据超过了dma所最开始设置的size了,那不出问题了???(疑惑???)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2026-4-12 19:36 , Processed in 0.310630 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表