前面三篇教程里,我们手头的小灯泡只有两种极端的宿命:要么完全亮,要么完全灭。
那如果我想让小灯泡变得像有生命一样,温柔地“一呼一吸”呢? 肯定有聪明的小伙伴会说:“我知道!给它输入一个一半的电压,比如 1.65V,不就半亮了吗?” 想法很棒,但是我们使用的 STM32F103C8T6 引脚只有 0 和 1(0V 和 3.3V),它根本输出不了中间的电压呀喵~
那怎么办呢?这就轮到今天的新魔法登场啦——定时器与 PWM 输出!(。・ω・。)ノ♡
1. 什么是 PWM?
听名字又是缩写,别怕别怕,我们用人话来解释: 既然灯泡只有全亮和全灭,那我们只要用“单身二十年的手速”,在一秒钟里把灯疯狂开关上千次!
比如在 1ms 的时间里:
- 让它亮 0.1ms,灭 0.9ms,我们的眼睛由于“视觉暂留”就会觉得它很暗;
- 让它亮 0.9ms,灭 0.1ms,我们的眼睛就会觉得它很亮!
这种利用“通电时间的长短”来控制有效功率的技术,就叫做 PWM 啦喵~
这里有两个最核心的概念: 看图: 
- “周期 / 频率”:开关一次总共花多长时间。比如一秒钟重复 1000 次,频率就是 1000Hz(1kHz),太慢了眼睛会看到在闪烁,太快了硬件吃不消。
- “占空比”:在一个周期里,“高电平亮灯的时间”占整个周期的百分比(0% 就是完全熄灭,100% 就是完全点亮,50% 就是半亮)。
2. 定时器参数与计算公式
那我们怎么用 STM32 的定时器来生成精准的 PWM 呢? 单片机的主频是 72MHz。 定时器里有两个关键小齿轮:
- “PSC(预分频器)”:把飞快的心跳减速,相当于分频;
- “ARR(自动重装载值)”:计数器数到多少算一个周期,相当于时钟走一圈的刻度。
计算公式超级简单:
我们来凑一个最舒服的整数组合:
- 把 PSC 设成
71(变成 ,也就是 1 微秒数一下); - 把 ARR 设成
999(从 0 数到 999 刚好数了 1000 下,也就是 1000 微秒 = 1ms)。
这样算出来 PWM 频率正好是 1kHz,而且一个周期刚好被切成了 1000 份! 占空比调节范围就是 0 到 1000,比如写 500 就是正好 50% 占空比,简直太治愈了喵~ (=´ω`=)
💡 哎等等,板载的那个 PC13 呢? 很遗憾,PC13 是个没有硬件定时器连通的残疾引脚,根本输出不了硬件 PWM! 所以这次我们要拿一个散装小 LED(或者接个面包板),正极插在 PA0 上,负极接地 GND(还记得第一期说的长脚正短脚负喵~)。
3. CubeMX 工程配置
打开我们熟悉的 CubeMX,选择我们的 STM32F103C8T6,老规矩配好时钟和调试口。
在左侧找到 Timers -> 点击 TIM2:
- 把
Clock Source选为Internal Clock; - 把
Channel 1选为PWM Generation CH1(你会发现右边芯片的 PA0 自动变绿啦!)。
在下面的参数配置里:
Prescaler填71;Counter Period填999;- 再往下拉展开
PWM Generation Channel 1:Mode选PWM mode 1;Pulse填0(默认占空比为 0,先不亮)。
配置好工程,点击生成代码,打开 Keil 工程! 
4. 编写代码让它呼吸起来!
写代码环节到啦! 首先,在 main.c 的 while 循环前面,必须先启动定时器的 PWM 功能:
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
/* USER CODE END 2 */那怎么在运行中修改占空比呢?HAL 库提供了一个超方便的宏定义:
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, pwm_value);只要改变 pwm_value(范围 0 ~ 1000),亮度就会跟着变啦!
现在我们让它一呼一吸起来,在 while(1) 里写上:
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// 逐渐变亮(吸气~)
for (int i = 0; i <= 1000; i += 10)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, i);
HAL_Delay(15);
}
// 逐渐变暗(呼气~)
for (int i = 1000; i >= 0; i -= 10)
{
__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, i);
HAL_Delay(15);
}
}
/* USER CODE END 3 */
下载、烧录,看一眼面包板上的小灯泡! 是不是像睡着的小猫咪一样,极其丝滑温和地一呼一吸啦?(=^・ω・^=)
学会了 PWM 以后不光能做呼吸灯,还能拿去控制舵机转角度、电机调转速,玩法多得很呢!
完结撒花!(=^・ω・^=)
快去享受你的第一个呼吸灯吧喵~
