STM32使用TIM闪烁LED——PWM方式

这次实验实现一个呼吸灯的效果,LED在第一秒内渐亮,在第二秒内渐暗,如此反复

控制LED的PWM波形阶梯数为100,即2秒内PWM的占空比从0%到100%范围内先递增后递减且递增/递减的幅度为1%

在设计STM32时,将定时器时钟7200分频后得到的10K时钟作为计数器时钟,并且设置周期为100,这样在一秒的时间可以产生100次中断,然后在中断中改变输出比较寄存器的值

#define USER_TIM_PSC            7200-1
#define USER_TIM_PERIOD            100-1

中断中还需使用到一个方向变量,控制输出比较寄存器在变化到最大和最小时改变增减方向

复制代码
void USER_TIM_IRQ_HANDLER(void)
{
    if(TIM_GetITStatus(USER_TIM, TIM_IT_Update) != RESET)
    {
        TIM_ClearITPendingBit(USER_TIM, TIM_IT_Update);
        
        if(pulse_width == 0)
            direction = 0;
        else if(pulse_width == 100)
            direction = 1;
        
        if(direction == 0)
            pulse_width++;
        else
            pulse_width--;
        TIM_SetCompare1(USER_TIM, pulse_width);
    }
}
复制代码

定时器配置时,选择输出比较模式为PWM1,向上计数,该模式下,当计数值小于比较寄存器值时输出有效电平,而如果是向下计数,则是计数值小于等于比较寄存器时为有效电平,有效电平可由寄存器配置

复制代码
void mini_tim_config(void)
{
    TIM_TimeBaseInitTypeDef tim_timebase_struct;
    TIM_OCInitTypeDef tim_oc_struct;
    GPIO_InitTypeDef gpio_struct;
    NVIC_InitTypeDef nvic_struct;
    
    GPIO_RCC_CMD(USER_TIM_GPIO_RCC, ENABLE);
    USER_TIM_RCC_CMD(USER_TIM_RCC, ENABLE);
    
    gpio_struct.GPIO_Mode = GPIO_Mode_AF_PP;
    gpio_struct.GPIO_Speed = GPIO_Speed_2MHz;
    gpio_struct.GPIO_Pin = USER_TIM_PIN;
    GPIO_Init(USER_TIM_GPIO, &gpio_struct);
    
    nvic_struct.NVIC_IRQChannel = USER_TIM_IRQ;
    nvic_struct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvic_struct);
    
    TIM_TimeBaseStructInit(&tim_timebase_struct);
    tim_timebase_struct.TIM_CounterMode = TIM_CounterMode_Up;
    tim_timebase_struct.TIM_Prescaler = USER_TIM_PSC;
    tim_timebase_struct.TIM_Period = USER_TIM_PERIOD;
    tim_timebase_struct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(USER_TIM, &tim_timebase_struct);
    
    TIM_OCStructInit(&tim_oc_struct);
    tim_oc_struct.TIM_OCMode = TIM_OCMode_PWM1;
    tim_oc_struct.TIM_OCPolarity = TIM_OCPolarity_High;
    tim_oc_struct.TIM_OutputState = TIM_OutputState_Enable;
    tim_oc_struct.TIM_Pulse = pulse_width;
    TIM_OC1Init(USER_TIM, &tim_oc_struct);
    
    TIM_OC1PreloadConfig(USER_TIM, TIM_OCPreload_Disable);
    TIM_ARRPreloadConfig(USER_TIM, ENABLE);
    
    TIM_Cmd(USER_TIM, ENABLE);
    
    TIM_ITConfig(USER_TIM, TIM_IT_Update, ENABLE);
}
复制代码

 

posted @   自由的青  阅读(3217)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示