打印
[活动]

【APM32F411V Tiny Board测评】2.定时器和PWM输出测试

[复制链接]
602|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
APM32F411有2个16位高级定时器、8个16位通用定时器、2个32位通用定时器

使用Timer9实现一个1ms周期的定时器,先配置一下系统时钟,开启外部高速晶振,PLL到120MHz

void ConfigSysClock(void)
{
    RCM_Reset();

    /* Open HSE 8MHz */
    RCM_ConfigHSE(RCM_HSE_OPEN);

    if(RCM_WaitHSEReady() == SUCCESS)
    {
        FMC_EnablePrefetchBuffer();
        FMC_ConfigLatency(FMC_LTNCY_4);

        RCM_ConfigAHB(RCM_AHB_DIV_1);
        RCM_ConfigAPB2(RCM_APB_DIV_1);
        RCM_ConfigAPB1(RCM_APB_DIV_2);

        RCM_ConfigPLL1(RCM_PLLSEL_HSE, 4,120,RCM_PLL_SYS_DIV_2,6);
        RCM_EnablePLL1();

        /* Wait for PLL1 Ready */
        while(RCM_ReadStatusFlag(RCM_FLAG_PLL1RDY) == RESET);

        /* Select PLL1 as System Clock */
        RCM_ConfigSYSCLK(RCM_SYSCLK_SEL_PLL);
        while(RCM_ReadSYSCLKSource() != RCM_SYSCLK_SEL_PLL);
        SystemCoreClockUpdate();
    }
    else
    {
        while(1);
    }
}
参考时钟树

Timer9在APB2上,时钟配置里APB2分频是1,Timer9基础频率为120MHz,配置Timer9和中断
void tim9_init()
{
    TMR_BaseConfig_T TMR_TimeBaseStruct;
    RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_TMR9);
    TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
    TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
    TMR_TimeBaseStruct.division = 119;
    TMR_TimeBaseStruct.repetitionCounter = 0;
    TMR_TimeBaseStruct.period = 999;
    TMR_ConfigTimeBase(TMR9, &TMR_TimeBaseStruct);
    TMR_EnableInterrupt(TMR9,TMR_INT_UPDATE);
    NVIC_EnableIRQRequest(TMR1_BRK_TMR9_IRQn, 0, 0);
    TMR_Enable(TMR9);
}
uint16_t timer9_count = 1000;
void TMR1_BRK_TMR9_IRQHandler(void)
{
    if(TMR_ReadIntFlag(TMR9, TMR_INT_UPDATE) == SET)
    {
        TMR_ClearIntFlag(TMR9, TMR_INT_UPDATE);
        if(timer9_count > 0)
            timer9_count -= 1;
        if(timer9_count == 0)
        {
            timer9_count = 1000;
            yuyy_LedToggle(YUYY_LED2);
            yuyy_LedToggle(YUYY_LED3);
        }
        LedChangeColor();
    }
}
运行效果

接下来通过PWM让这个RGB灯珠实现彩色变化

选用PA6 PA7 PB0作为RGB输出,分别对应Timer3的CH1、CH2、CH3


灯珠是共阳极的,这里采用PWM1模式,计数小于设定值时输出有效电平,设置低电平为有效电平
void pwm_init()
{
    TMR_BaseConfig_T TMR_TimeBaseStruct;
    TMR_OCConfig_T OCcongigStruct;
    GPIO_Config_T GPIO_ConfigStruct;
   
    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA);
    RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
   
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_6, GPIO_AF_TMR3);
    GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_TMR3);
    GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_0, GPIO_AF_TMR3);
   
    GPIO_ConfigStruct.pin = GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_ConfigStruct.mode = GPIO_MODE_AF;
    GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
    GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
    GPIO_Config(GPIOA, &GPIO_ConfigStruct);
    GPIO_ConfigStruct.pin = GPIO_PIN_0;
    GPIO_Config(GPIOB, &GPIO_ConfigStruct);
   
    RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR3);
    TMR_TimeBaseStruct.clockDivision = TMR_CLOCK_DIV_1;
    TMR_TimeBaseStruct.countMode = TMR_COUNTER_MODE_UP;
    TMR_TimeBaseStruct.division = 119;
    TMR_TimeBaseStruct.repetitionCounter = 0;
    TMR_TimeBaseStruct.period = 999; //频率1k 占空比调节0-1000
    TMR_ConfigTimeBase(TMR3, &TMR_TimeBaseStruct);
   
    OCcongigStruct.mode = TMR_OC_MODE_PWM1;              //PWM模式1,计数小于比较值时输出有效电平
    OCcongigStruct.outputState = TMR_OC_STATE_ENABLE;    //通道使能
    OCcongigStruct.idleState = TMR_OC_IDLE_STATE_SET;    //空闲高电平
    OCcongigStruct.polarity = TMR_OC_POLARITY_LOW;       //有效电平为低电平
    OCcongigStruct.outputNState = TMR_OC_NSTATE_DISABLE; //互补通道失能
    OCcongigStruct.nIdleState = TMR_OC_NIDLE_STATE_RESET;//互补通道空闲电平
    OCcongigStruct.nPolarity = TMR_OC_NPOLARITY_HIGH;    //互补通道有效电平
    OCcongigStruct.pulse = 0;                          //初始0%
    TMR_ConfigOC1(TMR3, &OCcongigStruct);
    TMR_ConfigOC2(TMR3, &OCcongigStruct);
    TMR_ConfigOC3(TMR3, &OCcongigStruct);
   
    TMR_ConfigOC1Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
    TMR_ConfigOC2Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
    TMR_ConfigOC3Preload(TMR3, TMR_OC_PRELOAD_ENABLE);
    TMR_EnableAutoReload(TMR3);
    TMR_Enable(TMR3);
    TMR_EnablePWMOutputs(TMR3);

    TMR_ConfigCompare1(TMR3,0);
    TMR_ConfigCompare2(TMR3,0);
    TMR_ConfigCompare3(TMR3,0);
}
实现彩色渐变函数
uint8_t ledstep = 0;
uint16_t pwm = 0;
void LedSetPwm(uint8_t ch,uint16_t pwm)
{
    if(ch == 0)
        TMR_ConfigCompare1(TMR3,pwm);
    else if(ch == 1)
        TMR_ConfigCompare2(TMR3,pwm);
    else if(ch == 2)
        TMR_ConfigCompare3(TMR3,pwm);
}
void LedChangeColor(void)
{
    uint8_t ch1 = 0;
    uint8_t ch2 = 1;
    if(ledstep >1)
    {
        ch1 = 2;
        ch2 = 0;
    }
    else if(ledstep >0)
    {
        ch1 = 1;
        ch2 = 2;
    }
    LedSetPwm(ch1,1000 - pwm);
    LedSetPwm(ch2,pwm);
    pwm += 1;
    if(pwm > 1000)
    {
        ledstep += 1;
        pwm = 0;
    }
    if(ledstep == 3)
        ledstep = 0;
}
在之前的1ms定时器中调用LedChangeColor,运行效果



使用特权

评论回复
沙发
HJLVVV| | 2024-8-21 09:35 | 只看该作者
大佬,我想用APM32F411输出一个互补PWM,有没有相似的案例能提供参考?跪求!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

149

主题

708

帖子

7

粉丝