stb988 发表于 2025-6-18 15:00

【灵动微电子MM32F0121测评】+3PWM驱动LED灯做呼吸灯

在之前做了开箱与串口打印,这次就做一个呼吸灯,用PWM波驱动开发板自带的LED,开发板的LED是在B14,B15 io口,
用TIM1驱动,关键代理如下
void TIM1_Configure(void)
{
    RCC_ClocksTypeDef       RCC_Clocks;
    GPIO_InitTypeDef      GPIO_InitStruct;
    TIM_OCInitTypeDef       TIM_OCInitStruct;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    uint32_t                TIM_ClockFrequency = 0;
    uint32_t                HPRE = 0, PPRE2 = 0;

    uint32_t TimerPeriod = 0, Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0;

    HPRE= READ_BIT(RCC->CFGR, RCC_CFGR_HPRE)>> RCC_CFGR_HPRE_Pos;
    PPRE2 = READ_BIT(RCC->CFGR, RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos;

    RCC_GetClocksFreq(&RCC_Clocks);

    if (HPRE < 8)
    {
      if (PPRE2 < 4)
      {
            TIM_ClockFrequency = RCC_Clocks.PCLK1_Frequency;
      }
      else
      {
            TIM_ClockFrequency = RCC_Clocks.PCLK1_Frequency * 2;
      }
    }
    else
    {
      if (PPRE2 < 4)
      {
            TIM_ClockFrequency = RCC_Clocks.PCLK1_Frequency * 2;
      }
      else
      {
            TIM_ClockFrequency = RCC_Clocks.PCLK1_Frequency * 4;
      }
    }

    /* Compute the value to be set in ARR regiter to generate signal frequency at 100 Khz */
    TimerPeriod = TIM_ClockFrequency / 100000;

    /* Compute CCR1 value to generate a duty cycle at 75% for channel 1 */
    Channel1Pulse = (uint32_t)750 * TimerPeriod / 1000;

    /* Compute CCR2 value to generate a duty cycle at 50% for channel 2 */
    Channel2Pulse = (uint32_t)500 * TimerPeriod / 1000;

    /* Compute CCR3 value to generate a duty cycle at 25% for channel 3 */
    Channel3Pulse = (uint32_t)250 * TimerPeriod / 1000;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    TIM_TimeBaseStructInit(&TIM_TimeBaseInitStruct);
    TIM_TimeBaseInitStruct.TIM_Prescaler         = 0;
    TIM_TimeBaseInitStruct.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period            = TimerPeriod;
    TIM_TimeBaseInitStruct.TIM_ClockDivision   = TIM_CKD_Div1;
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStruct);

    TIM_OCStructInit(&TIM_OCInitStruct);
    TIM_OCInitStruct.TIM_OCMode       = TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OutputState= TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_Pulse      = 0;
    TIM_OCInitStruct.TIM_OCPolarity   = TIM_OCPolarity_High;
    TIM_OCInitStruct.TIM_OCIdleState= TIM_OCIdleState_Set;

    TIM_OCInitStruct.TIM_Pulse = Channel1Pulse;
    TIM_OC1Init(TIM1, &TIM_OCInitStruct);

    TIM_OCInitStruct.TIM_Pulse = Channel2Pulse;
    TIM_OC2Init(TIM1, &TIM_OCInitStruct);

    TIM_OCInitStruct.TIM_Pulse = Channel3Pulse;
    TIM_OC3Init(TIM1, &TIM_OCInitStruct);


    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);



    GPIO_PinAFConfig(GPIOB, GPIO_PinSource14,GPIO_AF_7);   /* TIM1_CH1 */

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource15,GPIO_AF_7);   /* TIM1_CH2 */



    GPIO_StructInit(&GPIO_InitStruct);

    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_14 | GPIO_Pin_15 ;

    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;

    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_AF_PP;

    GPIO_Init(GPIOB, &GPIO_InitStruct);

    TIM_Cmd(TIM1, ENABLE);

    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}然后在例程中的这里改一下
void TIM1_PWM_Output_Sample(void)
{
        uint16_t i =0;
    printf("\r\nTest %s", __FUNCTION__);

    TIM1_Configure();

    while (1)
    {
         TIM1->CCR1 = 1440 - (i++%1440);

         TIM1->CCR2 = (i++%1440);



          PLATFORM_DelayMS(1);
    }
}下面上效果

AdaMaYun 发表于 2025-7-31 17:56

PWM驱动LED灯做呼吸灯
页: [1]
查看完整版本: 【灵动微电子MM32F0121测评】+3PWM驱动LED灯做呼吸灯