PWM
PWM
STM32-PWM是定时器驱动,依靠的是定时器的计数功能
I.MX6U把计数功能内置到了PWM里面,直接IO复用就行
FIFO
stm32里面如果要改变占空比,就需要改变CCR寄存等器的值,但是直接访问寄存器会占用CPU,如果需要频繁改写占空比(比如呼吸灯),CPU可能因为被抢占无法执行其他代码,所以引入了FIFO这个来放比较值的区域
假设需求:让 LED 以 100kHz 的 PWM 频率呼吸(占空比从 10%→20%→30%→…→100%→10% 循环,每次切换间隔 10μs,需连续切换 10 次占空比)。
- STM32 实现:需 CPU 频繁手动写比较寄存器,效率低
STM32 的 PWM 模块没有 FIFO,流程是:
配置 TIM3 定时器:分频系数设为 0(假设主频 72MHz),周期值 720(则 PWM 频率=72MHz/(720+1)≈100kHz),确定 PWM 频率;
第一次写 TIM3_CCR1=72(占空比 10%),LED 按 10% 亮度亮;
等待 10μs 后,CPU 必须手动写 TIM3_CCR1=144(占空比 20%);
再等 10μs,CPU 手动写 TIM3_CCR1=216(占空比 30%);
...重复 10 次,直到占空比到 100%。
问题:10 次占空比切换,CPU 必须介入 10 次,且要严格卡 10μs 间隔——如果 CPU 同时在处理其他任务(如串口接收),很可能错过时机,导致 LED 亮度跳变(波形断层)。
- I.MX6U 实现:FIFO 预存占空比,模块自动读取,CPU 解放
I.MX6U 的 PWM 模块带 4 级 FIFO(可存 4 个占空比),流程是:
配置 PWM1 模块:内置计数单元的分频系数设为 0(假设主频 72MHz),周期值 720(PWM 频率≈100kHz),和 STM32 逻辑一致;
一次性把 4 个占空比写入 PWM1 的 FIFO:先写 72(10%)、再写 144(20%)、再写 216(30%)、再写 288(40%);
使能 PWM1:模块内部计数器开始工作,先读取 FIFO 第一个值(72)输出 10% 占空比;
当第一个占空比生效完成后,模块 自动读取 FIFO 下一个值(144),无需 CPU 干预;
当 FIFO 里只剩 1 个值时,模块触发“FIFO 半空中断”,CPU 再补写 4 个新占空比(50%→60%→70%→80%)到 FIFO;
...循环往复,完成 10 次占空比切换。
优势:10 次切换,CPU 只需介入 3 次(补写 FIFO),其余时间模块自动工作,即使 CPU 处理其他任务,也不会影响 PWM 波形连续性,高频场景下更稳定。

