Stm32学习笔记(七)通用定时器PWM驱动LED呼吸灯

上篇文章用通用定时器实现了LED灯的闪烁,这次用通用定时器来产生PWM波,使LED呈现呼吸灯的效果。

一、PWM相关知识

        脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制。

        为了使STM32的TIMx生成PWM输出,除了基本的寄存器设置外,还需要使用三个主要寄存器:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)和捕获/比较寄存器(TIMx_CCR1~4)。下面是这些寄存器的简要介绍:

  1. 捕获/比较模式寄存器(TIMx_CCMR1/2)

    • TIMx_CCMR1控制CH1和CH2,TIMx_CCMR2控制CH3和CH4。
    • 模式设置位OCxM决定PWM模式,设置为110或111。
  2. 捕获/比较使能寄存器(TIMx_CCER)

    • 控制各输入输出通道的开关。我们使用CC2E位来使能PWM输出。
  3. 捕获/比较寄存器(TIMx_CCR1~4)

    • 这些寄存器的值与CNT的值比较,通过修改这些寄存器的值来控制PWM输出的脉宽。本实验使用TIM3的CH2,所以修改TIM3_CCR2实现PWM输出控制。

由于LED0连接在PB5引脚上,而TIM3_CH2默认连接在PA7上,所以要通过重映射功能将TIM3_CH2映射到PB5。STM32的重映射功能由AFIO_MAPR寄存器控制,需要设置TIM3_REMAP[1:0]为10,实现部分重映射。

二、代码相关

我们使用通用定时器TIM3模块来生成PWM信号。首先要对TIM3进行初始化配置,包括设置时钟分频、计数模式、自动重载值和预分频器等参数。然后初始化GPIO引脚,将其配置为复用功能输出,以输出PWM信号控制LED灯。

1.TIM3定时器初始化

通过配置定时器的时钟分频、计数模式、自动重装载值和预分频器等参数,对TIM3进行初始化设置。这些参数的配置决定了PWM信号的频率和占空比。

void TIM3_Int_Init(u16 arr, u16 psc) {
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 时钟使能

    TIM_TimeBaseStructure.TIM_Period = arr; // 设置自动重装载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler = psc; // 预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化TIM3

    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); // 使能TIM3更新中断

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; // TIM3中断
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 先占优先级0
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 从优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能IRQ通道
    NVIC_Init(&NVIC_InitStructure); // 初始化NVIC寄存器

    TIM_Cmd(TIM3, ENABLE); // 使能TIM3
}

 2.GPIO引脚配置

配置GPIO引脚,将PB5引脚设置为复用功能输出,用于输出TIM3的CH2通道的PWM信号。这一步将TIM3的PWM信号与LED的控制引脚连接,实现对LED的控制。

void TIM3_PWM_Init(u16 arr, u16 psc) {
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // 使能TIM3时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // 使能GPIO和AFIO时钟

    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); // TIM3部分重映射

    // 配置PB5为复用推挽输出
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // TIM3_CH2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始化GPIO

    // 初始化TIM3
    TIM_TimeBaseStructure.TIM_Period = arr; // 自动重装载寄存器周期的值
    TIM_TimeBaseStructure.TIM_Prescaler = psc; // 预分频值
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; // 时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化TIM3

    // 初始化TIM3 CH2 PWM模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // PWM模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 比较输出使能
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 输出极性高
    TIM_OC2Init(TIM3, &TIM_OCInitStructure); // 初始化TIM3 CH2

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); // 使能预装载寄存器

    TIM_Cmd(TIM3, ENABLE); // 使能TIM3
}

3.生成PWM信号

在主循环中,通过逐步增加或减少PWM值,实现LED的呼吸灯效果。通过条件判断改变PWM值的递增或递减方向,使LED的亮度呈现出渐变效果。

while (1) {
    delay_ms(10); // 延时10ms
    if (isIncreasing) {
        led0pwmval++; // 增加PWM值
    } else {
        led0pwmval--; // 减少PWM值
    }

    if (led0pwmval > 300) {
        isIncreasing = 0; // 达到最大值时,改变方向
    }
    if (led0pwmval == 0) {
        isIncreasing = 1; // 达到最小值时,改变方向
    }

    TIM_SetCompare2(TIM3, led0pwmval); // 设置TIM3 CH2的比较值,控制PWM占空比
}

看看效果:

呼吸灯

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值