扫码加入

  • 正文
  • 相关推荐
申请入驻 产业图谱

STM32 TIM+DMA 输出 PWM 波形异常?一文讲清 32 位定时器的坑

4小时前
174
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

你是不是也遇到过:同样的 TIM+DMA PWM 代码,TIM3 正常,TIM2 波形就乱了?从 F1 移植到 F4,明明配置一模一样,就是出问题?

ST 官方 LAT1259 这篇笔记直接点破真相:TIM2 是 32 位定时器,DMA 位宽不匹配会直接导致 CCR 值异常。这篇文章用最接地气的工程视角,把问题、原因、解决方法一次性讲透,以后遇到 32 位 TIM 用 DMA 再也不踩坑。

资料获取:【应用笔记】LAT1259 STM32使用DMA产生PWM时波形异常分析

1. 典型故障现象(一模一样就是同款问题)

  • STM32F4 系列,TIM2 + DMA 输出 PWM 波形异常
  • TIM3 + DMA 完全正常
  • 代码从 F1 移植过来,F1 没问题,F4 就异常
  • PWM 占空比错乱、波形失真、CCR 值超出 ARR
  • 检查配置:时钟、通道、DMA、PWM 模式全一样

2. 根因:TIM2 是 32 位计数器,DMA 位宽不配

LAT1259 给出最核心结论:

  • TIM2 / TIM5 是 32 位定时器
  • TIM1 / TIM3 / TIM4 等是 16 位定时器

客户的错误:

给32 位 TIM2配置了 DMA HalfWord(16 位) 传输。

而 STM32 的 AHB 总线规则:

32 位外设不支持 byte/halfword 写操作,总线会强制扩展成 32 位,导致数据错乱。

结果就是:

CCR 寄存器高 16 位 = 低 16 位,值直接翻倍甚至乱跳,PWM 直接畸形。

3. 为什么 TIM3 就没问题?

因为 TIM3 是 16 位定时器,DMA 配置 HalfWord(16 位)刚好匹配,所以正常。

F1 为什么没问题?

因为 F1 根本没有 32 位定时器,所以不会触发这个问题。

4. 10 秒解决方法(一步到位)

4.1 DMA 配置必须改

TIM2(32 位)DMA 设置:

  • 外设位宽:Word(32bit)
  • 内存位宽:Word(32bit)

4.2 存放 CCR 的数组必须是 32 位

// 正确:32位数组
uint32_t ccr_value_32[] = {10,20,30,40,50,60,70,80,90};

// 错误:16位数组会导致数据异常
uint16_t ccr_value_16[] = {10,20,30,...};

4.3 启动 DMA 函数保持不变

HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, ccr_value_32, 9);

改完这两处,TIM2 PWM 立刻恢复正常。

5. 工程师一句话总结(记这个就够)

  • 16 位定时器 ←→ DMA HalfWord(16 位)
  • 32 位定时器(TIM2/TIM5) ←→ DMA Word(32 位)

位宽必须匹配,否则波形必乱!

6. LAT1259 最终结论

  1. TIM2、TIM5 是32 位计数器,DMA 必须用Word(32bit)
  2. 16 位定时器用HalfWord(16bit)
  3. AHB 总线不支持 32 位外设的窄位宽写入,会导致数据异常
  4. F1 无 32 位 TIM,所以不会出现该问题
  5. 数组类型必须与位宽一致:32 位 TIM → uint32_t 数组

相关推荐