STM32 入门:软件PWM呼吸灯
本文介绍了使用STM32F103C8T6微控制器实现软件PWM呼吸灯的方法。首先讲解了GPIO基础概念和配置步骤,包括时钟使能、初始化结构体设置等。然后阐述了软件PWM原理,通过改变占空比控制LED亮度。最后详细解析了代码实现,包括GPIO初始化、PWM函数和主循环逻辑,完整实现了LED由暗到亮再到暗的呼吸效果。该实例可作为STM32 GPIO和PWM开发的入门参考。
STM32 入门:软件PWM呼吸灯

STM32 微控制器因性能强、外设丰富且性价比高,成为嵌入式开发热门选择。掌握 GPIO 配置与操作,是 STM32 开发入门的关键。本文以 STM32F103C8T6 为例,结合软件 PWM 呼吸灯实例展开讲解。
一、GPIO 基础概念
GPIO 是 STM32 与外部交互的基础接口,可设为输入或输出模式。STM32F103C8T6 的 GPIO 端口(如 GPIOA、GPIOB、GPIOC 等)引脚能独立配置,满足多样化开发需求。
二、GPIO 配置步骤
在使用 GPIO 之前,需要对其进行一系列的配置,以确保其工作在预期的模式下。下面以配置 PC13 引脚为输出模式为例,详细介绍 GPIO 的配置步骤。
- 使能 GPIO 时钟:在 STM32 中,每个外设都有独立的时钟控制,GPIO 也不例外。要使用 GPIO,首先需要使能其对应的时钟。对于 PC13 引脚,其位于 GPIOC 端口,使用以下代码使能 GPIOC 的时钟:
RCC\_APB2PeriphClockCmd(RCC\_APB2Periph\_GPIOC, ENABLE);
这段代码通过调用RCC_APB2PeriphClockCmd函数,将 GPIOC 的时钟使能,确保后续对 GPIOC 端口的操作能够正常进行。
2. 配置 GPIO 初始化结构体:STM32 标准库提供了GPIO_InitTypeDef结构体,用于配置 GPIO 的各种参数。对于 PC13 引脚的输出配置,代码如下:
GPIO\_InitTypeDef GPIO\_InitStructure;
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_Out\_PP;
GPIO\_InitStructure.GPIO\_Pin = GPIO\_Pin\_13;
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;
-
GPIO_Mode_Out_PP表示将引脚配置为推挽输出模式。推挽输出模式可以直接输出高电平和低电平,适用于驱动一些需要较大电流的负载,如 LED 灯。 -
GPIO_Pin_13指定要配置的引脚为 PC13。 -
GPIO_Speed_50MHz设置引脚的输出速度为 50MHz,该速度可以满足大多数应用场景的需求。
- 初始化 GPIO:在完成
GPIO_InitTypeDef结构体的配置后,使用以下代码将配置应用到 GPIOC 端口的 PC13 引脚上:
GPIO\_Init(GPIOC, \&GPIO\_InitStructure);
GPIO_Init函数会根据GPIO_InitStructure结构体中的参数,对 GPIOC 端口的 PC13 引脚进行初始化,使其工作在设定的输出模式下。
三、软件 PWM 呼吸灯原理
PWM(Pulse Width Modulation)即脉冲宽度调制,是一种通过改变脉冲信号的占空比(高电平持续时间与周期的比值)来控制输出信号平均值的技术。在本实例中,通过软件 PWM 来控制 LED 灯的亮度,实现呼吸灯效果。其原理是通过不断改变 PWM 信号的占空比,使 LED 灯的亮度在最暗到最亮之间逐渐变化,从而产生呼吸灯的效果。
四、软件 PWM 呼吸灯代码解析
下面对实现软件 PWM 呼吸灯的代码进行详细解析。
- 定义相关参数:
\#define PWM\_PERIOD 1000 // PWM周期(ms),可根据需要调整
\#define STEP\_SIZE 10 // 亮度变化步进值,值越小变化越平滑
PWM_PERIOD定义了 PWM 信号的周期为 1000ms,即 1 秒。STEP_SIZE定义了每次亮度变化的步进值为 10,该值决定了呼吸灯亮度变化的平滑程度。
2. GPIO 初始化函数:
void gpio\_init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
该函数完成了 GPIOC 端口 PC13 引脚的初始化工作,使 PC13 引脚工作在推挽输出模式下,并将其初始状态设置为低电平,即 LED 灯熄灭。
3. 软件 PWM 函数:
void PWM(unsigned int duty\_cycle)
{
if(duty_cycle > PWM_PERIOD) {
duty_cycle = PWM_PERIOD; // 限制最大值
}
GPIO_SetBits(GPIOC, GPIO_Pin_13); // LED亮
delay_ms(duty_cycle);
GPIO_ResetBits(GPIOC, GPIO_Pin_13); // LED灭
delay_ms(PWM_PERIOD - duty_cycle); // 补足周期时间
}
PWM函数用于实现软件 PWM 功能。函数接收一个参数duty_cycle,表示 PWM 信号的占空比(0 - 1000)。首先,函数对duty_cycle进行检查,如果其值超过了PWM_PERIOD,则将其设置为PWM_PERIOD,以确保占空比在合理范围内。然后,通过GPIO_SetBits函数将 PC13 引脚置为高电平,使 LED 灯亮起,并保持duty_cycle毫秒;接着,通过GPIO_ResetBits函数将 PC13 引脚置为低电平,使 LED 灯熄灭,并保持PWM_PERIOD - duty_cycle毫秒,从而补足 PWM 周期的时间。
4. 主函数:
int main(void)
{
unsigned int brightness = 0; // 当前亮度值
unsigned int direction = 1; // 1表示变亮,0表示变暗
gpio_init();
delay_init();
while (1)
{
// 渐亮过程
if(direction) {
brightness += STEP_SIZE;
if(brightness >= PWM_PERIOD) {
brightness = PWM_PERIOD;
direction = 0; // 达到最亮后开始变暗
}
}
// 渐暗过程
else {
brightness -= STEP_SIZE;
if(brightness <= 0) {
brightness = 0;
direction = 1; // 达到最暗后开始变亮
}
}
PWM(brightness); // 以当前亮度值执行PWM
}
}
在主函数中,定义了两个变量brightness和direction,分别用于记录当前 LED 灯的亮度值和亮度变化的方向。通过调用gpio_init函数初始化 GPIO,调用delay_init函数初始化延时函数(delay_init函数在delay.h头文件中定义,用于提供精确的延时功能)。在无限循环中,根据direction的值判断是渐亮还是渐暗过程。如果是渐亮过程,则将brightness增加STEP_SIZE,当brightness达到PWM_PERIOD时,将direction设置为 0,表示开始渐暗;如果是渐暗过程,则将brightness减少STEP_SIZE,当brightness减到 0 时,将direction设置为 1,表示开始渐亮。最后,调用PWM函数,以当前的brightness值作为占空比,实现 LED 灯的呼吸灯效果。
总结:
通过对 STM32 基础 GPIO 配置与软件 PWM 呼吸灯实现的介绍,相信读者对 STM32 的 GPIO 操作有了更深入的理解。
更多推荐



所有评论(0)