单片机/MCU论坛
直播中

qjp1988113

11年用户 343经验值
擅长:测量仪表 嵌入式技术 处理器/DSP 控制/MCU EDA/IC设计
私信 关注
[文章]

【"RV-STAR 开发板免费试用"免费试用】+定时器中断+PWM控制RGB灯 分享

`下面弄一下定时器,定时器在一个MCU当中还是很重要的。
GD32VF103VX里面包含了4个定时器,最高工作频率可达108M。
发现RGB的3个LED引脚是连在PA1/PA2/PA3正好在tiMER1的CH1/CH2/CH3
上面。
TM1.png
我们先做普通的定时器中断,让红灯每300ms闪烁一次:

void gd_rvstar_timer1_init(void)
{
        timer_parameter_struct timer_initpara;


        /* ----------------------------------------------------------------------------
        TIMER1 Configuration:
        TIMER1CLK = SystemCoreClock/54000 = 2KHz.//一个节拍 500us
        TIMER1CAR = 600                        //载入值600*500us=300ms
        ---------------------------------------------------------------------------- */
        rcu_periph_clock_enable(RCU_TIMER1);


        timer_deinit(TIMER1);


        timer_update_source_config(TIMER1, TIMER_UPDATE_SRC_REGULAR);


        /* initialize TIMER init parameter struct */
        timer_struct_para_init(&timer_initpara);
        /* TIMER1 configuration */
        timer_initpara.prescaler         = 53999;
        timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
        timer_initpara.counterdirection  = TIMER_COUNTER_UP;
        timer_initpara.period            = 600;
        timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
        timer_init(TIMER1, &timer_initpara);


        timer_interrupt_enable(TIMER1, TIMER_INT_UP);
        /* Timer Start */
        timer_enable(TIMER1);
}

void TIMER1_IRQHandler()
{
    uint16_t cnt;


    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_UP)){
        /* clear update interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);


                /* set led to GREEN */
                gd_rvstar_led_off(LED1);
                gd_rvstar_led_off(LED2);
                gd_rvstar_led_toggle(LED3);
    }
}

在面函数里面注册该中断:
ECLIC_Register_IRQ(TIMER1_IRQn, ECLIC_NON_VECTOR_INTERRUPT,
                            ECLIC_LEVEL_TRIGGER, 3, 0, NULL);
__enable_irq();
编译下载,现象如下:
时间间隔300ms
SBQ.jpg

接下来,我们通过PWM模式控制RGB灯。此时原来定义的普通引脚就不能用了,复用到PWM通道上了。
关闭了定时器的中断,当然,打开也没问题。
修改定时器初始化代码:
void gd_rvstar_timer1_pwm_init(void)
{
        timer_parameter_struct timer_initpara;
        timer_oc_parameter_struct timer_ocinitpara;

        //PWM引脚定义
        rcu_periph_clock_enable(RCU_GPIOA);
        rcu_periph_clock_enable(RCU_AF);
        /*Configure PA1 PA2 PA3(TIMER1 CH1 CH2 CH3) as alternate function*/
        gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, LEDG_PIN);
        gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, LEDR_PIN);
        gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, LEDB_PIN);

        /* ----------------------------------------------------------------------------
        TIMER2 Configuration:
        TIMER1CLK = SystemCoreClock/108 = 1MHz.//一个节拍1us
        TIMER1CAR = 1000                       //载入值1000*1us=1ms
        ---------------------------------------------------------------------------- */
        rcu_periph_clock_enable(RCU_TIMER1);

        timer_deinit(TIMER1);

        timer_update_source_config(TIMER1, TIMER_UPDATE_SRC_REGULAR);

        /* initialize TIMER init parameter struct */
        timer_struct_para_init(&timer_initpara);
        /* TIMER1 configuration */
        timer_initpara.prescaler         = 108-1;
        timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
        timer_initpara.counterdirection  = TIMER_COUNTER_UP;
        timer_initpara.period            = 255-1;
        timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
        timer_initpara.repetitioncounter = 0;
        timer_init(TIMER1, &timer_initpara);

        //timer_interrupt_enable(TIMER1, TIMER_INT_UP);


        /* initialize TIMER channel output parameter struct */
        timer_channel_output_struct_para_init(&timer_ocinitpara);
        /* CH0, CH1 and CH2 configuration in PWM mode */
        timer_ocinitpara.outputstate  = TIMER_CCX_ENABLE;
        timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
        timer_ocinitpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
        timer_ocinitpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
        timer_ocinitpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
        timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

        timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocinitpara);
        timer_channel_output_config(TIMER1,TIMER_CH_2,&timer_ocinitpara);
        timer_channel_output_config(TIMER1,TIMER_CH_3,&timer_ocinitpara);


        /* CH1 configuration in PWM mode0 */
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,255);
        timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);

        /* CH2 configuration in PWM mode0 */
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,255);
        timer_channel_output_mode_config(TIMER1,TIMER_CH_2,TIMER_OC_MODE_PWM0);
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);

        /* CH3 configuration in PWM mode0 */
        timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_3,255);
        timer_channel_output_mode_config(TIMER1,TIMER_CH_3,TIMER_OC_MODE_PWM0);
        timer_channel_output_shadow_config(TIMER1,TIMER_CH_3,TIMER_OC_SHADOW_DISABLE);

        /* auto-reload preload enable */
        timer_auto_reload_shadow_enable(TIMER1);

        /* Timer Start */
        timer_enable(TIMER1);
}

void gd_rvstar_rgb_init(int temp1,int temp2,int temp3)
{
         /* CH1 duty cycle set */
         timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,(255-temp2));


         /* CH2 duty cycle set */
         timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_2,(255-temp1));


         /* CH3 duty cycle set */
         timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_3,(255-temp3));
}



在main函数里面添加PWM初始化:
gd_rvstar_timer1_pwm_init();
while里面添加:
for(cnt = 255; cnt >=0; cnt--)
{
    gd_rvstar_rgb_init(cnt, 0, 0);
    delay_1ms(5);
}
for(cnt = 255; cnt >=0; cnt--)
{
    gd_rvstar_rgb_init(0, cnt, 0);
    delay_1ms(5);
}
for(cnt = 255; cnt >=0; cnt--)
{
    gd_rvstar_rgb_init(0, 0, cnt);
    delay_1ms(5);
}

编译下载,现象如下:

WW.gif





` REED.gif

回帖(1)

12345678QWERTY

2020-10-19 13:36:08
不错,值得一看
举报

更多回帖

发帖
×
20
完善资料,
赚取积分