当前位置: 首页 > news >正文

DMA + TIM 触发异常?别只怪时钟,看看 Update 与 TRGO

摘要:TIM 触发 DMA 搬运 ADC 数据,示波器看 ADC 在采样,但 DMA 缓冲区数据错位?不是 DMA 配置错了,而是 TIM 的Update Event​ 与TRGO​ 信号没对齐。本文解析 TIM 触发 DMA 的“隐形条件”。


一、问题描述(现象)

**TIM 配置 1kHz 触发 ADC;

DMA 配置 Circular 模式搬运;

运行一段时间后,ADC 数据在缓冲区里错位、重复或丢失。**

很多工程师的排查方向是:

  1. DMA Burst 长度不对?

  2. 内存地址没对齐?

  3. ADC 采样时间太短?


二、原理分析

1. 物理模型

TIM 触发 DMA 的信号链:

TIM Counter -> Update Event (UEV) -> TRGO (Trigger Output) -> DMA Request -> DMA Transfer

2. 核心参数

  • UEV (Update Event):计数器溢出/下溢时产生的事件。

  • TRGO (Trigger Output):TIM 输出给其他外设的信号。

  • DMA Request:DMA 控制器接收到的请求源。

3. 反直觉真相

“Update Interrupt Enable” 不等于 “DMA Trigger”。

  • 你开启了TIM_IT_UPDATE,只能进中断。

  • 你没配置TRGO = Update,DMA 永远收不到触发信号。

  • 结果:DMA 靠“猜”或者靠“相邻通道的副作用”在跑,迟早错位。


三、工程级解决方案

方案 1:明确配置 TRGO(最关键)

必须显式指定 TIM 的触发输出。

// STM32 HAL 示例 htim1.Init.RepetitionCounter = 0; HAL_TIM_Base_Init(&htim1); // 关键:选择 Update 作为 TRGO __HAL_TIM_SET_TRGO(&htim1, TIM_TRGO_UPDATE);

方案 2:DMA 与 TIM 的同步点

DMA 传输发生在UEV 之后,不是 CNT=0 的瞬间。

正确时序:

  1. CNT 计数到 ARR。

  2. 产生 UEV。

  3. 触发 DMA。

  4. DMA 读取 ADC->DR。

错误理解:

认为 DMA 在 CNT=0 时触发 → 采样窗口未结束,数据未稳定。

方案 3:防止“鬼触发”

如果使用 TIM 的One Pulse Mode

  • DMA 只会触发一次。

  • 必须手动重启 TIM,或改用 Continuous 模式。


四、选型避坑建议

  1. TRGO 源的选择

    • TIM_TRGO_UPDATE:最常用,适合周期性采样。

    • TIM_TRGO_OC1:适合相位可控的触发。

  2. DMA Stream 优先级

    • TIM 触发的 DMA 建议设为Very High,防止被 SPI/UART 抢占导致错位。

  3. 双缓冲(Double Buffer)

    • 高频采样(> 100kHz)强烈建议开启 DMA 双缓冲。


五、总结 Checklist

  • [ ] 是否配置了TIM_TRGO_UPDATE

  • [ ] DMA 请求是否映射到了正确的 TIM 触发源?

  • [ ] 是否在 Circular 模式下验证了长时间运行的稳定性?

  • [ ] ADC 采样时间是否足够在 TIM 周期内完成?


六、写在最后(关注我,少走弯路)

我是 gqqsherry,一个拒绝调包、专注底层逻辑的嵌入式工程师。

TIM + DMA + ADC 是嵌入式里“铁三角”级别的联动,任何一个环节没对齐,数据就全乱。

关注我的专栏《嵌入式底层避坑指南》,下一篇我们将深入解析《编码器模式转得乱七八糟?别只怪电机,看看 TI1/TI2 极性》

👉下一篇预告:《编码器计数忽多忽少?别只怪码盘,看看 TIM 的输入滤波与极性》

原创文章,转载请注明出处。

http://www.cnnetsun.cn/news/2872473.html

相关文章:

  • S12S调试模块与时钟管理实战:从硬件断点到PLL配置避坑指南
  • 用C++递归搞定分数求和:从《信息学奥赛一本通》1209题看通分与约分的优雅实现
  • 微信聊天记录恢复终极指南:WechatDecrypt完整解决方案
  • 垂直领域AI Agent:专业化的创新机遇
  • 如何在5分钟内搭建专业的语音转字幕平台:Whisper-WebUI完整指南
  • Boson NetSim 11 跨子网通信实战:从拓扑搭建到路由验证
  • 免费解锁WeMod Pro会员的终极指南:Wand-Enhancer完整使用教程
  • WinForms桌面程序XML配置式多语言切换工具包(支持窗体实时刷新)
  • MasterGo AI,真正服务于实际业务生产
  • 按键即启的科技感Canvas能量线动画,支持实时调节与响应式适配
  • Rust 环境配置实战:从零开始,用 VS Code 高效搭建开发工作流
  • 歌颂一下csdn,别不让我发文
  • Java电商系统课程设计全套材料:含可运行源码、MySQL数据库脚本与需求文档
  • 【实践指南】利用MSPA与景观连通性分析,精准识别生态安全网络核心源地
  • CircuitPython真的‘阉割’了性能?手把手教你移植MicroPython的framebuf和zlib模块
  • 避开这些坑:Mentor Tessent Shell灰盒/黑盒模型在Scan Retargeting中的正确用法
  • 一个更现实的降本方向,不是重练 MoE,而是先让一半专家别上场
  • Redis 分布式锁进阶第十七篇讲解
  • BIMserver:开源建筑信息模型服务器的革命性解决方案
  • 如何利用BiocManager高效管理Bioconductor软件包生态?
  • LinkedIn语义搜索系统:两阶段架构与工业级优化实践
  • 微信聊天记录永久保存神器:5分钟搞定你的数字记忆银行
  • Unity游戏本地化终极指南:5个简单步骤实现多语言自动翻译
  • 别再死记硬背公式了!用Python+NumPy手把手模拟MCMC采样(附完整代码)
  • 释放AMD Ryzen隐藏性能:电源调试神器的终极指南
  • 外贸行业用什么CRM系统好
  • Matlab图像复原实操包:车牌清晰化、去模糊、去噪、去雾、灰度调整、运动模糊修复全涵盖
  • 避坑指南:鸿蒙 PC 部署 AtomCode Skills 压测工具 wrk
  • Chrome for Testing:Web自动化测试的终极浏览器版本管理解决方案
  • OpenBlock Desktop:5分钟快速上手的硬件图形化编程工具