2. CubeMX配置PWM输出:时钟树设置、定时器配置、PWM通道引脚分配、参数计算
好,咱们正式开始动手配置。这一节我会带着你,一步步在CubeMX里把PWM输出给搭起来。别小看这个配置过程,我见过不少新手,甚至有些老手,都在这里栽过跟头。配置错了,后面调代码就是白费功夫。
2.1 时钟树设置——PWM的“心跳”来源
PWM信号的频率,说白了就是由定时器的时钟源决定的。你想想看,如果时钟源不准,那输出的PWM频率肯定也跑偏。
我个人习惯,在打开CubeMX后,第一件事就是点开Clock Configuration标签页。这里要做的,就是给定时器选一个合适的时钟源。
核心原则:定时器的时钟源,通常来自APB1或APB2总线。APB1最高频率一般是36MHz或45MHz(取决于具体型号),APB2最高频率通常是72MHz或90MHz。想要高频率PWM,优先选挂载在APB2上的定时器。
举个例子,我用的是STM32F103C8T6,它的APB2时钟最高72MHz。我一般会把TIM1(高级定时器)或TIM8挂在这里。如果只是做普通电机控制或LED调光,APB1上的TIM2、TIM3也完全够用。
这里有个坑,我曾经遇到过:
我曾经在项目里,把定时器的预分频器算错了,导致PWM频率只有预期的十分之一。查了半天,最后发现是APB1的时钟树配置里,分频系数设成了2,而我没注意到。所以,配置完时钟树后,一定要看一眼APB1/APB2的时钟频率,确认它是不是你想要的。
配置步骤很简单:
- 在Clock Configuration里,选择HSE或HSI作为系统时钟源。
- 设置PLL倍频系数,让系统时钟达到目标频率(比如72MHz)。
- 确认APB1和APB2的预分频系数,确保定时器时钟源正确。
嗯,这里要注意:如果你用的是STM32G0或G4系列,时钟树会更灵活,但原理是一样的——定时器的时钟源,决定了PWM的精度上限。
2.2 定时器配置——选对模式,算对参数
时钟树搞定后,咱们进入Pinout & Configuration标签页,找到你要用的定时器。比如我要用TIM2的通道1输出PWM,那就点开TIM2,在Mode里选择PWM Generation CH1。
这里有几个关键参数需要配置:
| 参数 | 说明 | 我的建议 |
|---|---|---|
| Prescaler (PSC) | 预分频器,用于降低定时器时钟频率 | 根据目标频率计算,一般设为0~65535 |
| Counter Mode | 计数模式:向上、向下、中心对齐 | 普通PWM用Up(向上计数) |
| Counter Period (ARR) | 自动重装载值,决定PWM周期 | 与PSC配合,算出目标频率 |
| Auto-reload Preload | 自动重装载预装载,建议Enable | 防止更新事件时出现毛刺 |
| Pulse | 占空比对应的计数值 | 初始设为ARR的一半,即50%占空比 |
参数计算其实就一个公式:
PWM频率 = 定时器时钟 / ( (PSC + 1) × (ARR + 1) )
举个例子:定时器时钟72MHz,想要输出1kHz的PWM,可以设PSC=71,ARR=999。这样算下来:72,000,000 / (72 × 1000) = 1000Hz,刚好1kHz。
我一般会先确定目标频率,然后反推PSC和ARR。比如做呼吸灯,频率50Hz就够了,PSC和ARR可以设大一些,让占空比调节更细腻。但如果是电机控制,频率可能需要10kHz以上,那PSC就得设小一点。
小技巧:如果你想要占空比调节精度高,那就把ARR设大一些。比如ARR=9999,那占空比就可以从0到9999精细调节。但要注意,ARR越大,PWM频率就越低,得在精度和频率之间找个平衡。
2.3 PWM通道引脚分配——别接错线
配置完定时器,接下来就是引脚分配。CubeMX会根据你选的定时器和通道,自动推荐可用的引脚。比如TIM2的通道1,默认可能是PA0,但如果你把PA0用作了其他功能,它就会自动切换到PA5或PA15。
我个人习惯,在Pinout View里,手动确认一下PWM输出引脚是不是我想要的。有时候CubeMX会自动分配一个不常用的引脚,导致你画PCB时还得改布局。
这里有个避坑指南:
我曾经在一个项目里,把TIM2的PWM输出分配到了PB3,结果发现PB3是JTDO引脚,调试器一连接就冲突。后来只能飞线解决。所以,分配引脚时,一定要避开调试接口(SWD/JTAG)和系统功能引脚(如BOOT0、NRST)。
另外,如果你用的是高级定时器(TIM1、TIM8),它们还有互补输出和刹车功能。这些功能在电机控制里很有用,但如果你只是做普通PWM,记得把Complementary Output和Break Input都关掉,不然配置会变得很复杂。
2.4 参数计算实战——手算一遍,心里有底
好,咱们来手算一个实际案例。假设我要用STM32F103,APB2时钟72MHz,TIM1输出一个20kHz的PWM,占空比可调范围0~100%。
- 确定目标频率:20kHz,周期50μs。
- 选择PSC:为了精度,我设PSC=0,这样定时器时钟就是72MHz。
- 计算ARR:ARR = (72,000,000 / 20,000) - 1 = 3600 - 1 = 3599。
- 占空比调节:Pulse值从0到3599,对应0%到100%占空比。
这样算下来,占空比调节精度是1/3600 ≈ 0.028%,相当细腻了。
注意:如果PSC=0,定时器时钟就是72MHz,那定时器的计数频率很高,功耗也会大一些。如果对功耗有要求,可以适当增大PSC,比如PSC=71,那定时器时钟就变成1MHz,ARR=49,频率还是20kHz,但精度就降到1/50=2%了。
嗯,这里要提醒一下:CubeMX里配置完参数后,可以在Parameter Settings里直接看到计算出的频率和占空比。但我还是建议你手算一遍,确认CubeMX算得对不对。我遇到过CubeMX版本bug,算出来的频率和实际不符的情况。
2.5 知识体系图:PWM配置核心流程
下面这张图,把整个PWM配置的流程串起来了。你可以对照着看,每一步都别漏掉。
2.6 常见配置错误与排查
配置过程中,我总结了几种最常见的错误,你遇到了可以对照着查:
| 错误现象 | 可能原因 | 解决方法 |
|---|---|---|
| PWM无输出 | 引脚未使能、定时器未使能、GPIO模式错误 | 检查GPIO配置为AF_PP,确认定时器时钟已使能 |
| PWM频率不对 | PSC或ARR计算错误、时钟树配置错误 | 手算一遍频率,确认APB时钟频率 |
| 占空比无法调节 | Pulse值超出ARR范围、CCR寄存器未更新 | 确保Pulse ≤ ARR,检查是否调用了__HAL_TIM_SET_COMPARE |
| PWM输出有毛刺 | Auto-reload Preload未使能、中断优先级冲突 | 使能预装载,检查中断优先级设置 |
我的经验:如果PWM没输出,先用示波器或逻辑分析仪抓一下引脚波形。如果没有仪器,可以用万用表测引脚电压——如果占空比设成50%,引脚电压应该是VCC的一半左右。这个方法虽然粗糙,但能快速判断PWM是否在工作。