[APM32E0] APM32 USART RX使用DMA接收的数据帧判断方法

[复制链接]
 楼主| Reli-eng-z 发表于 2025-6-25 20:34 | 显示全部楼层 |阅读模式
本帖最后由 Reli-eng-z 于 2025-7-8 10:46 编辑

APM32 USART RX使用DMA接收的数据帧判断方法


1. 概述

在使用APM32系列微控制器的USART配合DMA进行数据接收时,如何准确判断一帧数据的接收完成是一个关键问题。本文介绍几种常用的方法及其实现原理。

2. 数据帧接收完成判断方法

2.1 固定长度数据帧接收

适用场景:数据帧长度固定且已知。

实现方法:
1. 配置DMA接收固定长度的数据
2. DMA传输完成中断(TC中断)触发表示接收完成

优点:实现简单,资源消耗少。

缺点:不适用于变长数据帧。

2.2 空闲中断(Idle Interrupt)配合DMA

实现步骤:
1. 使能USART的空闲中断
2. 配置DMA进行循环接收或足够长的线性接收
3. 当检测到总线空闲(1个字符时间无数据)时触发空闲中断
4. 在中断中通过DMA的当前计数器值计算接收到的数据长度
94782685bec98210ba.png
```c
// 空闲中断处理示例
void USARTx_IRQHandler(void)
{
    if(USART_GetITStatus(USARTx, USART_IT_IDLE) != RESET)
    {
        USART_ClearITPendingBit(USARTx, USART_IT_IDLE); // 清除空闲中断标志
        uint16_t remainCnt = DMA_GetCurrDataCounter(DMAy_Streamx); // 获取剩余未传输数据量
        uint16_t recvLen = TOTAL_BUF_SIZE - remainCnt; // 计算实际接收长度
        // 处理接收到的数据...
    }
}
```

优点:适用于变长数据帧,硬件自动检测。

缺点:需要USART支持空闲检测功能。

2.3 超时(Timeout)机制

实现方法:
1. 配置DMA接收并启用传输完成中断
2. 每次接收到数据时重置超时定时器
3. 如果在设定时间内没有新数据到达,判定为帧接收完成
```c
// 定时器中断处理示例
void TIMx_IRQHandler(void)
{
    if(TIM_GetITStatus(TIMx, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(TIMx, TIM_IT_Update);
        // 超时处理,判定为帧接收完成
        uint16_t recvLen = TOTAL_BUF_SIZE - DMA_GetCurrDataCounter(DMAy_Streamx);
        // 处理数据...
    }
}

// USART接收中断中重置定时器
void USARTx_IRQHandler(void)
{
    if(USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)
    {
        // 读取数据或直接清除标志
        USART_ReceiveData(USARTx);
        TIM_SetCounter(TIMx, 0); // 重置超时计数器
    }
}
```

优点:可灵活调整超时时间,适用于不规则数据帧。

缺点:需要额外定时器资源。

2.4 协议指定长度+DMA

实现方法:
1. 第一阶段:接收固定长度的帧头(包含长度信息)
2. 第二阶段:根据帧头中的长度信息配置DMA接收剩余数据

```c
// 示例处理流程
void DMA_IRQHandler(void)
{
    if(DMA_GetITStatus(DMAy_Streamx, DMA_IT_TC) != RESET)
    {
        DMA_ClearITPendingBit(DMAy_Streamx, DMA_IT_TC);

        if(phase == PHASE_HEADER)
        {
            // 解析头部获取数据长度
            dataLen = parseHeader(rxBuffer);
            // 重新配置DMA接收剩余数据
            DMA_Config(dataLen);
            phase = PHASE_DATA;
        }
        else
        {
            // 完整帧接收完成
            processFrame();
            // 重置为接收头部状态
            DMA_Config(HEADER_LEN);
            phase = PHASE_HEADER;
        }
    }
}
```
85400685becbf3bbfe.png
优点:适用于有明确协议的通信。

缺点:实现较复杂,需要协议支持。

3. 方法对比与选择建议

[td]
方法适用场景硬件要求实现复杂度
固定长度DMA固定长度帧基本DMA功能
空闲中断+DMA变长帧USART空闲中断
超时机制不规则帧/无明确结束标志额外定时器
协议指定长度+DMA有明确协议的通信基本DMA功能

推荐方案:
1. 对于简单应用,优先考虑空闲中断+DMA方案
2. 对于高可靠性要求场景,建议结合协议指定长度和超时机制
3. 固定长度方案仅适用于特定场景

4. 注意事项

1. DMA缓冲区应足够大以避免溢出
2. 考虑数据对齐问题,特别是使用DMA
3. 在多任务环境中,处理好数据访问的互斥问题
4. 对于高波特率通信,及时处理接收完成事件以避免数据覆盖
5. 实现适当的错误处理机制(如校验失败、超时等)

5. 总结

APM32 USART使用DMA接收数据时,可通过多种方式判断帧接收完成。选择合适的方法需要综合考虑通信协议特点、硬件资源及可靠性要求。在实际应用中,往往需要结合多种机制来实现稳定可靠的数据接收。


29634685beca8ef995.png
霜咬回响 发表于 2025-6-27 10:55 | 显示全部楼层
我们使用固定帧长的方式进行双机通讯,但我们也要加入超时机制。
 楼主| Reli-eng-z 发表于 2025-6-27 15:49 | 显示全部楼层
霜咬回响 发表于 2025-6-27 10:55
我们使用固定帧长的方式进行双机通讯,但我们也要加入超时机制。

有道理
永恒回声 发表于 2025-6-28 16:21 | 显示全部楼层
话说,如果开启了DMA的接收,我可不可以中断接收啊?
即我通过超时来判断关闭此帧数据。
VelvetNight 发表于 2025-6-29 08:41 | 显示全部楼层
DMA我在使用的时候总觉得对其不放心。
空闲帧的判断总怕出现问题!
 楼主| Reli-eng-z 发表于 2025-6-29 14:33 | 显示全部楼层
VelvetNight 发表于 2025-6-29 08:41
DMA我在使用的时候总觉得对其不放心。
空闲帧的判断总怕出现问题!

有经验啊
HeartbeatEcho 发表于 2025-6-29 16:06 | 显示全部楼层
楼主真厉害,把平时遇到的应用场景全部列出来了。
楼主是做什么行业的啊?
VelvetNight 发表于 2025-6-29 16:11 | 显示全部楼层

楼主过奖了。
看了楼主的帖子,才知道楼主是真正的大佬
 楼主| Reli-eng-z 发表于 2025-6-29 16:27 | 显示全部楼层
VelvetNight 发表于 2025-6-29 16:11
楼主过奖了。
看了楼主的帖子,才知道楼主是真正的大佬

感谢
FrostShimmer 发表于 2025-6-29 16:50 | 显示全部楼层
做一回科代表!
2.1 固定长度数据帧接收
2.2 空闲中断(Idle Interrupt)配合DMA
2.3 超时(Timeout)机制
2.4 协议指定长度+DMA

固定长度DMA固定长度帧基本DMA功能低
空闲中断+DMA变长帧USART空闲中断中
超时机制不规则帧/无明确结束标志额外定时器中
协议指定长度+DMA有明确协议的通信基本DMA功能高


楼主的实力也太强了吧
FrostShimmer 发表于 2025-6-29 16:51 | 显示全部楼层
这个帖子妥妥的精华帖
 楼主| Reli-eng-z 发表于 2025-6-29 17:29 | 显示全部楼层
FrostShimmer 发表于 2025-6-29 16:51
这个帖子妥妥的精华帖

好好学习
记忆花园 发表于 2025-6-30 19:14 | 显示全部楼层
文章写得确实很全面。
待我逐一实践一下
 楼主| Reli-eng-z 发表于 2025-7-1 08:38 | 显示全部楼层
记忆花园 发表于 2025-6-30 19:14
文章写得确实很全面。
待我逐一实践一下

perfect
 楼主| Reli-eng-z 发表于 2025-7-1 08:38 | 显示全部楼层
HeartbeatEcho 发表于 2025-6-29 16:06
楼主真厉害,把平时遇到的应用场景全部列出来了。
楼主是做什么行业的啊? ...

芯片行业
HeartbeatEcho 发表于 2025-7-3 14:54 | 显示全部楼层
还是你们做芯片行业的卷啊!
FrostShimmer 发表于 2025-7-3 19:31 | 显示全部楼层
协议指定长度+DMA有明确协议的通信基本DMA功能

试试这个方案去。
 楼主| Reli-eng-z 发表于 2025-7-4 15:43 | 显示全部楼层
懒癌晚期患者 发表于 2025-7-4 21:22 | 显示全部楼层
这些方法都很实用,特别是空闲中断+DMA方案,对于变长数据帧的处理非常有效。
复古留声机 发表于 2025-7-7 12:44 | 显示全部楼层
这些方法都很实用,尤其是空闲中断+DMA方案,对于变长数据帧的处理非常有效。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

63

主题

184

帖子

1

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