You need to enable JavaScript to run this app. 基于HAL库的NUCLEO-F303K8定时器DMA输出PWM异常问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

基于HAL库的NUCLEO-F303K8定时器DMA输出PWM异常问题咨询

STM32驱动WS2811灯带PWM+DMA输出100%占空比问题排查

现象

在NUCLEO-F303K8开发板上,基于CubeMX+Keil配置TIM2通道2的DMA PWM输出,调用HAL_TIM_PWM_Start_DMA后,无论传入的数据源数组取值如何,对应引脚始终输出3.3V常高信号,占空比100%。

问题根因(对照你贴出的工程代码逐一对应)

  • DMA位宽配置完全不匹配
    你定义的数据源ws2811_data是32位无符号整型数组,但CubeMX默认的TIM2_CH2 DMA配置为8位/16位传输宽度。DMA搬运32位数据时会把完整数值拆成碎片写入CCR2寄存器,当写入的数值大于定时器周期值(你配置的ARR=20)时,PWM1模式会将输出强制拉到高电平,最终表现为引脚常高。
  • 定时器时序与寄存器赋值错位
    你在MX_TIM2_Init函数执行完成后才给htim2.Init.RepetitionCounter = 1赋值,此时定时器初始化流程早已结束,该赋值根本不会同步到硬件寄存器;且F303K8的TIM2为通用定时器,本身不具备重复计数器功能,该写法无任何实际作用。
    当前定时器参数下,计数频率为100kHz,单个计数周期10us,与WS2811要求的1.25us位周期偏差超过一个数量级,灯带本身也无法识别信号。
  • DMA传输模式为单次触发
    CubeMX默认的TIM PWM DMA配置为单次传输模式,传完预设长度的数据后DMA会停止工作,最后一次写入CCR2的数值如果大于ARR值,引脚就会一直保持高电平,不会回到初始状态。
  • CCR预装载被手动关闭
    你代码中通过__HAL_TIM_DISABLE_OCxPRELOAD关闭了比较寄存器的预装载功能,DMA写入CCR值时会立刻生效,无法和定时器计数边界对齐,极易出现输出锁死的异常。

具体修复步骤

  • 在CubeMX的DMA配置页,找到TIM2_CH2对应的DMA通道,将内存位宽与外设位宽均设置为32位,匹配CCR2寄存器的实际宽度与数组数据类型,不要沿用默认配置。
  • 修正定时器时序参数:
    当前系统时钟为8MHz HSI,无需PLL倍频。将定时器预分频设为0,ARR设为9,得到8MHz计数频率、1.25us的位周期,完全匹配WS2811的信号时序要求。对应编码值:逻辑0为高电平3个计数(0.375us),逻辑1为高电平6个计数(0.75us),替换原数组中随意填写的测试值。
  • 在CubeMX中将TIM DMA的工作模式设置为循环传输,避免单次传输完成后DMA停转导致输出锁死。
  • 删除代码中手动添加的RepetitionCounter赋值语句,同时删掉__HAL_TIM_DISABLE_OCxPRELOAD行,恢复CCR寄存器预装载功能,保证输出时序和定时器计数边界同步。
  • 重新生成代码后,先做基础功能验证:不接LED灯带,将ws2811_data数组所有值设为0,调用启动函数后用万用表测量引脚电平,确认输出常低;再将单个值设为9(与ARR相等),用示波器观察输出是否为50%占空比,确认DMA传输链路正常后再调整灯带编码逻辑。

注意:WS2811的编码要求为每24位对应一颗LED的GRB颜色值,数据发送完成后需保持至少50us的低电平完成复位,否则灯带无法正确锁存颜色数据。


内容的提问来源于stack exchange,提问作者VladimirChernyshev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 10:15:01