基于STM32的PWM驱动LED呼吸灯

一,PWM基本原理

所谓PWM,就是脉冲宽度调制技术,其具有两个很重要的参数:频率和占空比。频率,就是周期的倒数;占空比,就是高电平在一个周期内所占的比例。如当周期T=T1+T2;T1为高电平时间,T2为低电平时间,此时频率F的值为1/(T1+T2),占空比D的值为T1/(T1+T2)。通过改变单位时间内脉冲的个数可以实现调频;通过改变占空比可以实现调压。占空比越大,所得到的平均电压也就越大,幅值也就越大;占空比越小,所得到的平均电压也就越小,幅值也就越小,如动图演示所示。PWM方波的示意图如下图所示:

                             

二,PWM基本结构及配置PWM步骤

第1步,RCC开启时钟,把我们要用的TlM外设和GPIO外设的时钟打开。

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    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);

第2步,配置时基单元,包括时钟源选择

    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;
    TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1;
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

第3步,配置输出比较单元

void TIM_OC1Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC3Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
void TIM_OC4Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);

OC就是Output Compare(输出比较)OC1,OC2,OC3,OC4,一个函数配置一个单元(输出比较通道),上面这四个函数用于设置输出PWM时用到的参数,包括选择PWM输出模式,选择输出极性,设置比较值。注意:设置输出时是按输出通道分的库函数。即需要初始化哪个通道,就调用哪个函数。不同的通道对应的GPIO口也是不一样的。

    TIM_OCInitTypeDef  TIM_OCInitStructure;配置参数                      TIM_OCStructInit(&TIM_OCInitStructure);//用来给输出比较结构体成员赋一个默认值的,下面        就可以再更改你想改的值就行了。可以避免结构体成员没有配置完整。
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);

第4步,配置GPIO

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;    //GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

第五步,运行控制,启动计数器,这样就能输出PWM了。
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);

这四个函数是用来单独更改CCR寄存器值的函数,可以运行的时候,更改占空比。TIM_Cmd(TIM2, ENABLE);
TIM_SetCompare1(TIM2, Compare1);

第6步,主程序
    while(1)
    {
        for (uint8_t i = 0; i < 100; i ++)
        {
            PWM_SetCompare1(i);
            delay_ms(10);
        }
        for (uint8_t i = 0; i < 100; i ++)
        {
            PWM_SetCompare1(100 - i);
            delay_ms(10);
        }
        delay_ms(500);
    }

  • 6
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
好的,让我来回答你的问题。 首先,STM32F401是一款基于ARM Cortex-M4内核的微控制器,它具有丰富的外设和强大的性能。PWM(脉冲宽度调制)是一种常用的数字信号调制技术,可以用来控制LED等外设的亮度。 下面是一个简单的呼吸控制程序,使用了STM32CubeMX和HAL库。假设我们使用的是PA5引脚来驱动LED: 1. 配置TIM2为PWM模式,设置周期和分辨率 ```c void MX_TIM2_Init(void) { TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 0; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 999; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_PWM_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } HAL_TIM_MspPostInit(&htim2); } ``` 2. 在main函数中初始化TIM2和GPIOA ```c int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_TIM2_Init(); HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); while (1) { for (int i = 0; i <= 999; i++) { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, i); HAL_Delay(2); } for (int i = 999; i >= 0; i--) { __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, i); HAL_Delay(2); } } } ``` 3. 在主循环中,使用for循环逐步增加或减小PWM占空比,从而实现呼吸效果。 上述代码可以实现一个简单的呼吸效果,你可以根据实际需求进行修改。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值