STM32使用PWM驱动LED呼吸灯

你的糖来啦
2024-06-23 / 0 评论 / 15 阅读 / 正在检测是否收录...

使用PWM来实现LED呼吸灯的效果

步骤

  1. 开启并配置TIM和GPIO时钟
  2. GPIO需要设置成为复用推挽输出
  3. 根据实际需要配置合适的时基单元(PWM频率)
  4. 配置好输入比较寄存器

具体如下

注意:本代码是使用比较通道1,对用在PA0上输出PWM

主要代码 PWM.c

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
    //启动TIM GPIO
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    //需要使用GPIO来输出PWM PWM来自片上外设TIM 所以设置为复用推挽输出
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    //配置TIM
    //CK_PSC时钟频率 PSC分频 ARR自动重装
    //PWM频率 = CK_PSC/(PSC+1)/(ARR+1)
    //PWM占空比 = CCR/(ARR+1)
    //PWM分辨率 = 1/(ARR+1)
    TIM_InternalClockConfig(TIM2);
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //CK_PSC
    TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;    //ARR 
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
    
    TIM_OCInitTypeDef TIM_OCInitStructure;
    //初始化赋值 为了代码维护性
    TIM_OCStructInit(&TIM_OCInitStructure);
    //选择输出模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    //选择电频输出状态 高电频 低电平 这里是高
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    //输出状态 使能 使能 这里是使能
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    //占空比
    TIM_OCInitStructure.TIM_Pulse = 0;    //CCR
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);
    
    TIM_Cmd(TIM2,ENABLE);
}

//更改CCR占空比用的
void PWM_SetCompare1(uint16_t Compare)
{
    TIM_SetCompare1(TIM2,Compare);
}


main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
int main(void)
{
    /*模块初始化*/
    OLED_Init();        //OLED初始化
    PWM_Init();
    
    OLED_ShowString(1,1,"Pulse:");
    while (1)
    {
        for(uint16_t i = 0;i <= 100; i++)
        {
            PWM_SetCompare1(i);
            OLED_ShowNum(2,1,i,3);  //屏幕上显示占空比 可删除
            Delay_ms(20);
        }
        for(uint16_t i = 0;i <= 100; i++)
        {
            PWM_SetCompare1(100 - i);
            OLED_ShowNum(2,1,100 - i,3);
            Delay_ms(20);
        }
    }
}
0

评论 (0)

取消