STM32中有关PWM的问题

请问改变PSC和ARR的值对PWM波有什么影响,改变PSC和ARR的值能改变呼吸灯完成一次呼吸循环的周期吗,呼吸灯的周期是怎么算出来的,PWM波的周期对呼吸灯的周期有影响吗,一定要使用延时才能让呼吸的效果更加明显吗?
在研究如何调整呼吸灯的周期时,发现了很多自己不懂的。
如果我想设置呼吸灯完成一次呼吸的周期为5秒,那么我该如何设置?

【以下回答由 ChatGPT 生成】

回答:

  1. PSC(预分频器)和ARR(自动重装载寄存器)的值会影响PWM波的频率和占空比。PSC决定了TIMx clock的频率被多少分频,ARR决定了TIMx counter的计数上限。修改PSC和ARR的值可以改变PWM波的频率和占空比,具体计算方式如下:

  2. PWM波频率 = TIMx clock频率 / (PSC + 1)

  3. PWM波占空比 = (无效计数器数值 / ARR) × 100%

  4. PSC和ARR的值可以改变呼吸灯完成一次呼吸循环的周期。呼吸灯周期的计算方式如下:

  5. 呼吸灯周期 = PWM波的周期 × (1 + 呼吸变化的步数)

其中,呼吸变化的步数是指呼吸灯从亮到暗或从暗到亮变化的步数,可以根据需要自行设置。

呼吸灯周期的计算方式可以根据具体需求进行调整,比如可以根据呼吸变化的速度和流畅度来调整呼吸灯周期。

  1. PWM波的周期会影响呼吸灯的周期,因为呼吸灯的周期取决于PWM波的周期。如果PWM波的周期较长,呼吸灯变化的速度也会比较慢;如果PWM波的周期较短,呼吸灯变化的速度会较快。

  2. 不一定需要使用延时函数才能让呼吸效果更加明显。可以通过调整呼吸灯周期、占空比和呼吸变化的步数来实现呼吸效果的改变。延时函数可以用于控制呼吸变化的速度,但也可以通过其他方式实现,比如使用定时器中断和计数器,根据需要进行相应的操作。

下面给出一个示例代码,展示如何设置STM32的PWM功能和实现呼吸灯效果。

#include "stm32f4xx.h"

void PWM_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);

    TIM_TimeBaseInitStruct.TIM_Period = 999; // PWM波的周期为1ms
    TIM_TimeBaseInitStruct.TIM_Prescaler = 4199; // PSC的值为4199,频率为84MHz / (4199 + 1) = 20kHz
    TIM_TimeBaseInitStruct.TIM_ClockDivision = 0;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);

    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse = 500; // 占空比50%,PWM波占高电平500个计数器周期
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStruct);

    TIM_Cmd(TIM3, ENABLE);
}

void BreathLED(uint32_t period)
{
    uint32_t step = 100; // 呼吸变化的步数
    uint32_t delay = period / step; // 延时时间

    for (uint32_t i = 0; i <= step; i++) {
        TIM3->CCR1 = (1000 * i) / step; // 设置占空比
        delay_ms(delay); // 延时
    }
    for (uint32_t i = step; i > 0; i--) {
        TIM3->CCR1 = (1000 * i) / step; // 设置占空比
        delay_ms(delay); // 延时
    }
}

int main(void)
{
    PWM_Init();

    while (1) {
        BreathLED(5000); // 设置呼吸灯周期为5秒
    }
}

上述代码使用了TIM3通道1作为PWM输出,使用了GPIOA的第6引脚作为PWM输出引脚。通过修改PSC和ARR的值可以改变PWM波的频率和占空比。通过调用BreathLED函数可以实现呼吸灯效果,其中period参数表示呼吸灯周期的长度,单位为毫秒。

请注意,以上示例代码仅供参考,请根据实际的开发板和需求进行适当的调整和更改。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^