欢迎光临
我们一直在努力

【嵌入式】STM32 硬件 PWM 学习文档

STM32 硬件 PWM 学习文档(以 STM32F103VB + PA1/TIM2_CH2/LED17 为例)

1. 学习目标

本文档用于梳理 STM32 硬件 PWM 的基础概念、参数计算方法、配置思路,以及本次实验中
用例:PA1 -> TIM2_CH2 -> LED17 的实际应用过程。

通过本文档,应能回答下面几个问题:

  • 什么是 PWM
  • STM32 的硬件 PWM 是怎么产生的
  • 为什么 PSC、ARR、CCR 要这样配置
  • PWM 频率 和 占空比 分别由什么决定
  • 为什么某个 LED 能不能做硬件 PWM,要看引脚有没有 TIMx_CHx
  • 为什么 PA1 可以做 LED17 的硬件 PWM

2. 本次实验背景

本次实验使用芯片为:

  • STM32F103VB

板上 LED17 对应到 MCU 的:

  • PA1

而 PA1 具备复用功能:

  • TIM2_CH2

因此可以将 PA1 配置为定时器 2 的通道 2 输出脚,使用 TIM2_CH2 输出硬件 PWM,进而控制 LED17 的亮度变化。


3. 什么是 PWM

PWM,全称:

Pulse Width Modulation(脉冲宽度调制)

它的核心思想是:

在一个固定周期内,通过控制高电平持续时间所占的比例,来控制输出的平均效果。

例如,一个周期为 10ms:

  • 高电平持续 1ms,低电平持续 9ms,占空比为 10%
  • 高电平持续 5ms,低电平持续 5ms,占空比为 50%
  • 高电平持续 9ms,低电平持续 1ms,占空比为 90%

对于 LED 来说,人眼看到的不是每一个瞬间的高低电平,而是一个“平均亮度”:

  • 占空比越大,通常越亮
  • 占空比越小,通常越暗

4. 硬件 PWM 和软件 PWM 的区别

4.1 软件 PWM

软件 PWM 的典型做法是:

  • 定时器周期性进入中断
  • 在中断里手动控制 GPIO 输出高低电平
  • 通过程序计算亮灭时间比例,模拟 PWM

特点:

  • 实现直观
  • 所有 GPIO 都可以尝试模拟
  • 但 CPU 参与较多
  • 中断负担更重

4.2 硬件 PWM

硬件 PWM 的典型做法是:

  • 使用定时器内部的 PWM 模式
  • 定时器自动产生 PWM 波形
  • 通过 TIMx_CHx 对应引脚直接输出

特点:

  • 波形由硬件自动产生
  • CPU 不需要反复翻转 GPIO
  • 更稳定、更高效
  • 但只能用具备 TIMx_CHx 功能的引脚

4.3 本次实验属于

PA1 -> TIM2_CH2 -> LED17 的实验,属于:

硬件 PWM

∵ PWM 波形由 TIM2 的通道 2 直接输出到 PA1,不是通过中断手动翻转 GPIO 实现的。


5. STM32 硬件 PWM 的本质

STM32 硬件 PWM 的本质可以理解为:

  • 定时器以一定速度计数
  • 计数器从 0 开始不断累加
  • 当计数值小于某个比较值时,输出一种电平
  • 当计数值大于等于该比较值时,输出另一种电平
  • 当计数到周期上限后,重新回到 0,开始下一个周期
  • 因此,硬件 PWM 的核心不是普通 GPIO,而是:

    • 定时器计数
    • 比较寄存器
    • 输出通道

    6. PWM 须掌握的几个核心概念

    6.1 系统时钟

    系统时钟是 MCU 运行的基础时钟来源。

    本次实验中,使用简单的时钟配置:

    • HSI = 8MHz

    也就是说,很多外设的基础时钟,都与这 8MHz 有关。


    6.2 定时器时钟

    定时器本身并不是凭空计数的,它的计数速度来自输入时钟。

    在入门阶段,可以先简单理解成:

    定时器拿到一个时钟后,经过预分频,再开始计数。


    6.3 Prescaler(预分频器,PSC)

    PSC 的作用是:

    把输入给定时器的时钟先“减慢”

    公式为:

    定时器计数频率 = 定时器输入时钟 / (PSC + 1)

    注意这里一定是:

    PSC + 1

    不是直接除以 PSC。

    例如:

    • 输入时钟 = 8MHz
    • PSC = 7

    那么:

    定时器计数频率 = 8MHz / (7 + 1) = 1MHz

    说明:

    定时器现在每 1us 计一次数
    每秒1M次
    f= 1/T


    6.4 Period(自动重装值,ARR)

    在这里插入图片描述

    ARR 的作用是:

    决定计数器数到多少后重新从 0 开始

    例如:

    • ARR = 999

    那么计数过程为:

    0, 1, 2, … , 999

    总共是 1000 个计数。

    因此,一个完整 PWM 周期的计数长度为:

    ARR + 1


    6.5 Compare(比较值,CCR)

    CCR 的作用是:

    决定一个 PWM 周期中,高电平持续多长时间

    在常见的 PWM1 模式下,可以简单理解为:

    • 当 CNT < CCR 时,输出高电平
    • 当 CNT >= CCR 时,输出低电平

    因此:

    • CCR 越大,高电平持续越久
    • 占空比越大

    6.6 计数器(CNT)

    CNT 是定时器当前正在计到的值。

    比如:

    • 当前 CNT = 100
    • 当前 CCR = 500

    若采用 PWM1 模式,则因为 100 < 500,输出保持高电平。

    当 CNT 继续增加,到 500 及以上后,输出会切换为低电平。


    7. PWM 频率和占空比公式

    7.1 PWM 频率公式

    PWM 频率由下面公式决定:

    PWM频率 = 定时器输入时钟 / ((PSC + 1) × (ARR + 1))

    这说明:

    • PSC 影响计数速度
    • ARR 影响一个周期有多少个计数
    • 两者共同决定 PWM 的频率

    7.2 占空比公式

    占空比由下面公式决定:

    占空比 = CCR / (ARR + 1)

    这说明:

    • ARR 决定总周期长度
    • CCR 决定高电平持续时间
    • 两者共同决定占空比

    8. 举例为什么本次实验这样配置参数

    本次实验采用的参数是:

    • 系统时钟:8MHz
    • PSC = 7
    • ARR = 999

    目标是:

    • 产生一个大约 1kHz 的 PWM
    • 同时保留较高的占空比分辨率,便于 LED 调光更平滑

    9. 参数计算过程详解

    9.1 第一步:先确定系统时钟

    本次实验使用最简单的内部高速时钟:

    HSI = 8MHz


    9.2 第二步:先决定计数频率

    为了便于理解和计算,先将定时器计数频率设置为:

    1MHz

    为什么选 1MHz?

    因为:

    • 1MHz 表示每 1us 计一次数
    • 时间单位直观
    • 后续算周期和占空比都方便

    根据公式:

    定时器计数频率 = 定时器输入时钟 / (PSC + 1)

    代入:

    1MHz = 8MHz / (PSC + 1)

    得到:

    PSC + 1 = 8
    PSC = 7

    所以设置:

    PSC = 7


    9.3 第三步:确定 PWM 周期

    目标 PWM 频率设为:

    1kHz

    也就是:

    每秒 1000 个周期
    每个周期 1ms

    前面已经把计数频率设成了:

    1MHz

    即:

    每 1us 计一次数

    那么一个 1ms 周期内,需要计数:

    1ms = 1000us

    也就是:

    1000 次

    由于定时器从 0 开始计数,所以:

    ARR = 1000 – 1 = 999

    因此设置:

    ARR = 999


    9.4 第四步:验证 PWM 频率

    将参数代入频率公式:

    PWM频率 = 8MHz / ((7 + 1) × (999 + 1))
    = 8MHz / (8 × 1000)
    = 1kHz

    所以该配置是正确的。


    10. 为什么不选别的参数组合

    实际上,并不是只有这一组参数能得到 1kHz PWM。

    例如,也可以这样:

    • PSC = 79
    • ARR = 99

    因为:

    8MHz / (79 + 1) = 100kHz
    100kHz / (99 + 1) = 1kHz

    最终频率也是 1kHz。

    但是这两种配置的差别在于:

    配置一:PSC = 7, ARR = 999

    优点:

    • 计数频率 1MHz,时间分辨率高
    • ARR = 999,占空比可调范围大约有 1000 档
    • LED 调光更细腻

    配置二:PSC = 79, ARR = 99

    特点:

    • 计数频率较低
    • ARR = 99,占空比只有大约 100 档
    • 调节会更粗一些

    因此,在 LED 呼吸灯这类应用中,通常更偏向:

    在 PWM 频率满足要求的前提下,让 ARR 稍大一些,从而获得更高的占空比分辨率


    11. 为什么修改 CCR 就能改变 LED 亮度

    假设当前:

    • ARR = 999

    那么一个周期总共是 1000 个计数。

    情况 1:CCR = 100

    占空比 = 100 / 1000 = 10%

    这意味着:

    • 一个周期中只有约 10% 的时间输出高电平
    • LED 平均亮度较低

    情况 2:CCR = 500

    占空比 = 500 / 1000 = 50%

    这意味着:

    • 一个周期中约一半时间输出高电平
    • LED 亮度中等

    情况 3:CCR = 900

    占空比 = 900 / 1000 = 90%

    这意味着:

    • 大部分时间输出高电平
    • LED 平均亮度较高

    因此,修改 CCR 就是在修改占空比,而占空比决定 LED 的平均亮度。


    12. 为什么 PA1 必须配置为复用推挽输出

    做硬件 PWM 时,PA1 不能再当普通 GPIO 使用,而要把该引脚交给定时器通道来控制。

    因此必须配置为:

    GPIO_MODE_AF_PP

    含义为:

    • AF:Alternate Function,复用功能
    • PP:Push Pull,推挽输出

    如果配置成普通推挽输出:

    GPIO_MODE_OUTPUT_PP

    那 PA1 只是一个普通 GPIO,无法输出 TIM2_CH2 的 PWM 波形。

    所以这一步是硬件 PWM 成功输出的关键条件之一。


    13. 为什么要使用 TIM2_CH2

    因为本次 LED17 接到的是:

    • PA1

    而 PA1 具备的定时器通道功能是:

    • TIM2_CH2

    所以如果想让 LED17 走硬件 PWM,必须满足下面这个链路:

    TIM2 -> CH2 -> PA1 -> LED17

    也就是说,硬件 PWM 不是任意 GPIO 都能做,而是要看该引脚有没有对应的 TIMx_CHx 功能。


    14. 如何判断某个 LED 能不能做硬件 PWM

    判断步骤通常如下:

    第一步:看原理图

    确认该 LED 接到了 MCU 的哪个引脚。

    第二步:看该引脚复用功能

    确认该引脚是否具备:

    TIMx_CHx

    例如:

    • PA1 -> TIM2_CH2
    • PA0 -> TIM2_CH1

    第三步:确认工程里能否将该引脚配置为复用输出

    如果具备 TIMx_CHx,则可以尝试配置为硬件 PWM。

    第四步:若没有 TIMx_CHx

    则通常不能直接做硬件 PWM,只能考虑:

    • 软件 PWM
    • 或更换到支持 PWM 的引脚

    15. 为什么本次 LED17 能做 PWM

    本次实验中:

    • LED17 -> PA1
    • PA1 具备 TIM2_CH2

    因此满足硬件 PWM 的基本条件。

    虽然板级原理图中 LED17 还经过了反相器等外围电路,但这不影响:

    • PA1 输出 PWM 波形
    • 定时器使用 TIM2_CH2

    只是可能会影响最终看到的亮暗逻辑方向。

    也就是说:

    • 占空比变大,可能看起来越来越亮
    • 也可能因为板级反相,表现为越来越暗

    但这不影响硬件 PWM 已经正确输出。


    16. 为什么要选 1kHz 作为 LED PWM 频率

    LED 做 PWM 调光时,频率不能太低。

    如果频率过低,容易出现:

    • 肉眼可见闪烁
    • 视觉体验差

    1kHz 是一个很常见、也很适合入门实验的频率,因为它:

    • 足够高,不容易明显闪烁
    • 参数容易计算
    • 调试方便

    当然,并不是只能选 1kHz,实际应用中还可能使用:

    • 500Hz
    • 2kHz
    • 5kHz

    但对学习阶段来说,1kHz 是一个很好的起点。


    17. 一次完整的 PWM 参数设计思路

    以后遇到 PWM 配置问题,可以按下面这个流程思考。

    第一步:确定系统时钟

    例如:

    8MHz

    第二步:确定目标 PWM 频率

    例如:

    1kHz

    第三步:先选一个好理解的定时器计数频率

    例如:

    1MHz

    这时:

    PSC = 8MHz / 1MHz – 1 = 7

    第四步:再根据 PWM 频率算 ARR

    因为:

    1MHz / 1kHz = 1000

    所以:

    ARR = 1000 – 1 = 999

    第五步:根据占空比算 CCR

    例如,若想要 50% 占空比:

    CCR = 1000 × 50% = 500

    这样整组参数就完整了。


    18. 与本次实验相关的关键结论

    18.1 参数结论

    本实验设置:

    • PSC = 7
    • ARR = 999

    可得到:

    • 定时器计数频率:1MHz
    • PWM 频率:1kHz

    18.2 占空比调节方式

    通过修改:

    • CCR

    即可改变占空比,从而改变 LED17 的平均亮度。

    18.3 引脚配置要求

    PA1 必须配置为:

    • 复用推挽输出

    不能配置为普通 GPIO 输出。

    18.4 引脚前提

    某 LED 想做硬件 PWM,必须先确认其对应引脚具有:

    • TIMx_CHx

    而 PA1 具备:

    • TIM2_CH2

    所以可以实现硬件 PWM。


    19. 容易混淆的几个点

    19.1 为什么公式里总是 +1

    无论是:

    • PSC
    • ARR

    都要注意,硬件计数通常是从 0 开始的。

    所以:

    • PSC = 7 实际表示 8 分频
    • ARR = 999 实际表示一个周期共 1000 个计数

    这是初学者最容易写错的地方之一。


    19.2 PWM 频率和占空比不要混淆

    PWM 频率由什么决定

    由:

    • 输入时钟
    • PSC
    • ARR

    决定

    占空比由什么决定

    由:

    • CCR
    • ARR

    决定

    因此:

    • 改 PSC、ARR,主要是在改 PWM 有多快
    • 改 CCR,主要是在改 LED 有多亮

    19.3 并不是所有 GPIO 都能直接输出硬件 PWM

    只有当引脚带有:

    TIMx_CHx

    这类复用功能时,才适合直接做硬件 PWM。

    如果没有该功能,则通常只能:

    • 做普通 GPIO
    • 做软件 PWM

    20. 本次实验的理解模型

    可以把 PWM 的参数理解成三层:

    第一层:PSC

    决定定时器“走得有多快”

    第二层:ARR

    决定“走多少步算一个周期”

    第三层:CCR

    决定“这个周期里有多少步保持高电平”

    这个模型非常适合初学者建立整体认知。


    21. 小结

    本次基于 STM32F103VBT6 和 PA1/TIM2_CH2/LED17 的硬件 PWM 学习,核心结论如下:

  • PWM 本质上是在固定周期内控制高电平持续时间比例的技术
  • STM32 的硬件 PWM 由定时器自动产生,不需要 CPU 反复翻转 GPIO
  • PWM频率 = 定时器时钟 / ((PSC+1) × (ARR+1))
  • 占空比 = CCR / (ARR+1)
  • PSC 用于分频,ARR 用于确定周期,CCR 用于确定占空比
  • 本实验中 8MHz -> PSC=7 -> 1MHz计数频率 -> ARR=999 -> 1kHz PWM
  • PA1 因为具备 TIM2_CH2 功能,所以可以用于硬件 PWM 输出
  • PA1 必须配置为复用推挽输出,不能配置为普通 GPIO 输出
  • 通过动态修改 CCR,即可实现 LED17 的亮度调节和呼吸灯效果

  • 22. 适合后续继续学习的方向

    在掌握本文内容后,可以继续学习下面几个方向:

    • PWM1 和 PWM2 模式的区别
    • 边沿对齐模式与中心对齐模式
    • 高级定时器与普通定时器的区别
    • 多通道 PWM 同步输出
    • 通过按键切换占空比档位
    • 通过 DMA 自动修改 CCR 实现更平滑呼吸灯
    • PWM 驱动蜂鸣器、电机、舵机的不同参数配置思路
    赞(0)
    未经允许不得转载:171主机测评 » 【嵌入式】STM32 硬件 PWM 学习文档
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址