【STM32】定时器基础整理:PSC、ARR、CCR 与 PWM 输出
文章目录
- [【STM32】定时器基础整理:PSC、ARR、CCR 与 PWM 输出](#【STM32】定时器基础整理:PSC、ARR、CCR 与 PWM 输出)
-
- 一、前言
- 二、定时器整体认识
-
- [2.1. PSC:预分频器](#2.1. PSC:预分频器)
- [2.2. CNT:计数器](#2.2. CNT:计数器)
- [2.3. ARR:自动重装载寄存器](#2.3. ARR:自动重装载寄存器)
- [2.4. CCR:捕获/比较寄存器](#2.4. CCR:捕获/比较寄存器)
- [三、更改 预分频系数 & 自动重装载寄存器](#三、更改 预分频系数 & 自动重装载寄存器)
-
- [3.1 更改 预分频系数 PSC](#3.1 更改 预分频系数 PSC)
- [3.2 更改 自动重装载寄存器 ARR](#3.2 更改 自动重装载寄存器 ARR)
- [四、`cubeMX` 配置 `systick` & `timer`](#四、
cubeMX配置systick&timer) -
- [3.1 `cubeMX` 配置`systick`](#3.1
cubeMX配置systick) - [3.2 `cubeMX` 配置 `timer`](#3.2
cubeMX配置timer)
- [3.1 `cubeMX` 配置`systick`](#3.1
- 五、定时器的输出功能
- 六、使用PWM控制三色灯
-
- [5.1 硬件电路](#5.1 硬件电路)
- 5.2`cubeMX`配置
- [5.3 PWM HAL 函数](#5.3 PWM HAL 函数)
本文基于
DshanMCU-103开发板,学习韦东山 STM32 HAL 课程中定时器相关内容后整理。
一、前言
STM32 定时器是比较重要的外设之一,后面很多功能都会用到它,比如定时中断、PWM 输出、LED 调光、电机调速、舵机控制、输入捕获、编码器测速等。
刚开始学习定时器时,不建议一上来就死磕寄存器。更好的方式是先理解它的整体工作流程:
text
定时器时钟
↓
PSC 预分频
↓
CNT 计数
↓
数到 ARR 后溢出/重装载
↓
产生更新事件 / 输出 PWM / 触发中断
本文主要整理 STM32F103 中定时器的基础知识,包括定时器的基本原理、PSC/CNT/ARR/CCR 的关系、时基中断、PWM 输出、HAL 常用函数,以及关键寄存器的简单对应关系,方便后续项目开发时快速查阅。
二、定时器整体认识
建议先看下面这张总览图:
| 总览图 |
|---|
![]() |
|
STM32 定时器本质上可以理解为一个"自动计数器"。
2.1. PSC:预分频器
PSC 的作用是把定时器输入时钟分频,让 CNT 计数变慢。
计算公式:
text
计数频率 = 定时器时钟频率 / (PSC + 1)
注意这里是 PSC + 1,不是直接除以 PSC。
例如定时器时钟是 72 MHz:
text
PSC = 71
计数频率 = 72 MHz / (71 + 1)
= 1 MHz
这表示 CNT 每 1 us 加 1。
2.2. CNT:计数器
CNT 表示当前计数值。
在向上计数模式下,CNT 会从 0 开始不断加 1:
text
0 → 1 → 2 → 3 → ... → ARR
当 CNT 数到 ARR 后,会重新回到 0。
2.3. ARR:自动重装载寄存器
ARR 决定 CNT 数到多少重新开始。
定时周期可以这样计算:
text
定时周期 = (ARR + 1) / 计数频率
例如:
text
计数频率 = 1 MHz
ARR = 999
那么:
text
定时周期 = (999 + 1) / 1 MHz
= 1000 us
= 1 ms
定时周期 = (PSC + 1) * (ARR + 1) / 定时器输入时钟频率
也就是说,每 1 ms 会产生一次更新事件。
2.4. CCR:捕获/比较寄存器
CCR 常用于 PWM 输出。
在 PWM 模式 1、向上计数时,可以简单理解为:
text
当 CNT < CCR 时,输出高电平
当 CNT >= CCR 时,输出低电平
所以:
text
CCR 越大,高电平持续时间越长
CCR 越小,高电平持续时间越短
注意:CCR 不是控制电压高度,而是控制比较点的位置,也就是高电平持续多久。
三、更改 预分频系数 & 自动重装载寄存器
3.1 更改 预分频系数 PSC
| 更改 预分频系数 PSC |
|---|
![]() |
3.2 更改 自动重装载寄存器 ARR
| 简易计数器 | 影子寄存器 |
|---|---|
![]() |
![]() |
更新 ARR 后,什么时候起作用,取决于影子寄存器(真正起作用的寄存器) ,通过设置ARPE寄存器,可调整 ARR 才写入影子寄存器的时机
| ARPE=0 | ARPE=1 |
|---|---|
| ARR 立马写入影子寄存器; 马上起作用 | CNT计数器 溢出后,自动重装载寄存器 ARR 才写入影子寄存器 溢出后起作用 |
四、cubeMX 配置 systick & timer
3.1 cubeMX 配置systick
systick |
|---|
![]() |
cubeMX 配置 systick |
|---|
![]() |
c
main > HAL_Init > HAL_InitTick(TICK_INT_PRIORITY); >HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U); //1ms 产生一次中断
SysTick_Handler > HAL_IncTick(); > uwTick += uwTickFreq; // 中断服务函数,每产生一次中断,+1
3.2 cubeMX 配置 timer
cubeMX 配置 timer |
|---|
![]() |
五、定时器的输出功能
4个CCR 一个CCR ==> PWM 的输出有 2 种:正常输出 & 互补输出。所谓互补输出就是引脚信号跟正常输出情况下的电平是相反的。
| 高级定时器原理图 | PWM输出 |
|---|---|
![]() |
![]() |
设置 AutoReload (ARR ) |
设置 CCR | PSC |
|---|---|---|
| 决定 PWM 周期 | 决定高电平时间(占空比) | 影响计数速度 |
| PWM |
|---|
![]() |
六、使用PWM控制三色灯
5.1 硬件电路
| 三色灯 | 三色灯硬件原理图 |
|---|---|
![]() |
![]() |
全彩 LED 由三个 LED 组成,它们的颜色分别是红、 绿、蓝。它的接口电路如下:当PA2、 PA15、 PB3 为低电平时, 全彩 LED 里的红、绿、蓝就会发光。调整这些引脚的占空比,就可以调配出不同的颜色。
5.2cubeMX配置
cubeMX配置 TIM2 的 三个通道CH1/CH2/CH3 |
|---|
![]() |
5.3 PWM HAL 函数
c
/* 启动PWM:
* htim: 哪个定时器?
* Channel:哪个通道,取值有TIM_CHANNEL_1到TIM_CHANNEL_4, TIM_CHANNEL_ALL*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel);
/* 停止PWM:
* htim: 哪个定时器?
* Channel:哪个通道,取值有TIM_CHANNEL_1到TIM_CHANNEL_4, TIM_CHANNEL_ALL*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel);
c
/* 配置PWM:
* htim: 哪个定时器?
* Channel:哪个通道,取值有TIM_CHANNEL_1到TIM_CHANNEL_4, TIM_CHANNEL_ALL*/
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig, uint32_t Channel);
/* 配置 PWM 时,配置参数为"TIM_OC_InitTypeDef" 类型,它的定义如下 */
typedef struct
{
uint32_t OCMode; /* 模式,通常设置为 TIM_OCMODE_PWM1 */
uint32_t Pulse; /* 有效电平的宽度,单位为时钟个数 */
uint32_t OCPolarity; /* 输出信号有效电平是高还是低, TIM_OCPOLARITY_HIGH 或 TIM_OCPOLARITY_LOW */
uint32_t OCNPolarity; /* 互补输出信号有效电平是高还是低, TIM_OCPOLARITY_HIGH 或 TIM_OCPOLARITY_LOW */
uint32_t OCFastMode; /* 是否使用快速模式,通常设置为 TIM_OCFAST_DISABLE */
uint32_t OCIdleState; /* 空闲是引脚的输出电平 */
uint32_t OCNIdleState; /* 空闲时互补引脚的输出电平 */
} TIM_OC_InitTypeDef;`












