硬汉嵌入式论坛

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

[UART] 串口DMA空闲接收中断怎么获得接收的字节数

[复制链接]

13

主题

6

回帖

45

积分

新手上路

积分
45
发表于 2025-5-14 14:21:46 | 显示全部楼层 |阅读模式
配置成串口1DMA空闲接收中断,
1、DMA是circular模式。DMA缓冲区大小100字节

测试时只发送2字节,接收的字节 = 100 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
接收的字节 = 2
接收的字节 = 4
接收的字节 = 6
。。。
是个累计的状态,circular模式下,在中断回调中是不是要把某个东西清空下才能得到正确的字节数
2、DMA是Normal模式。DMA缓冲区大小100字节

测试时只发送2字节,接收的字节 = 100 - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
接收的字节 = 2
接收的字节 = 2
接收的字节 = 2

.。。。
此时获取到的字节数是正确的。
用normal模式也可以满足需求,只是想再探究下circular模式下的原因是啥
回复

使用道具 举报

6

主题

162

回帖

180

积分

初级会员

积分
180
发表于 2025-5-14 18:35:10 | 显示全部楼层
回调函数void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)已经包含接收字节数Size的信息了,不需要自己计算。

正常只需要配置为Normal就可以了。在回调函数末尾,清空接收缓存区,再次启动DMA接收空闲即可。Circular连续计数是不是因为你没有重新配置接收?
回复

使用道具 举报

12

主题

62

回帖

98

积分

初级会员

积分
98
发表于 2025-5-15 09:02:56 | 显示全部楼层
有回调函数HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)可以用,DMA配置成循环模式,接受的字节是在100字节的缓冲区内累计的,接收的个数也是累计的。

第一次接收到[0-1],返回size=2;第二次接收到[2-3],返回size=4;以此类推
回复

使用道具 举报

45

主题

246

回帖

381

积分

高级会员

积分
381
发表于 2025-11-30 21:04:12 | 显示全部楼层
理解问题,当circle模式时,是偏移。初始化,wr=rd=0.
第一次接到get_dma_size=2,wr = (wr + get_dma_size) % dma_buf_size。
中断里面wr=2;
线程里面 while  (wr != rd) {
                 buf[i] = dma_buf[rd];
                 rd = (rd+1)%dma_buf_size
}
这样简化问题,只有空闲中断,线程里面相当于在读一个circle fifo
回复

使用道具 举报

45

主题

246

回帖

381

积分

高级会员

积分
381
发表于 2025-12-10 22:08:28 | 显示全部楼层
snakeemail 发表于 2025-11-30 21:04
理解问题,当circle模式时,是偏移。初始化,wr=rd=0.
第一次接到get_dma_size=2,wr = (wr + get_dma_si ...

再简化一点,如果dma开了一直不关,也不初始化,只要idle中断了,更新一下wr指针
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2026-1-10 17:24 , Processed in 0.074635 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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