问答

汇集网友智慧,解决技术难题

21ic问答首页 - GD32A503 TIMER 上溢UP中断与CAP中断优先级有一定几率反转问题

2A 中断优先级 timer ap GD32 MCU

GD32A503 TIMER 上溢UP中断与CAP中断优先级有一定几率反转问题

hsyy2024-06-18
测试硬件:GD32A503CC测试外设:TIMER0_CH1
测试准备:PE5输入高频PWM
中断优先级配置:UP中断高于CH1中断
void nvic_configuration(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(TIMER0_BRK_UP_TRG_CMT_IRQn, 1, 0);
    nvic_irq_enable(TIMER0_Channel_IRQn, 1, 1);
}

测试定时器配置:配置TIMER0_CH1为双沿输入捕获模式,使能TIMER0 UP上溢与CH1中断。
void timer_configuration(void)
{
    /* TIMER1 configuration: input capture mode -------------------
    the external signal is connected to TIMER0 CH1 pin (PE5)
    the rising edge is used as active edge
    the TIMER1 CH0CV is used to compute the frequency value
    ------------------------------------------------------------ */
    timer_ic_parameter_struct timer_icinitpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER0);

    timer_deinit(TIMER0);
    /* TIMER0 configuration */
    timer_struct_para_init(&timer_initpara);
    timer_initpara.prescaler         = 99;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 65535;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(TIMER0, &timer_initpara);

    /* TIMER0 configuration */
    /* TIMER0 CH1 input capture configuration */
    timer_channel_input_struct_para_init(&timer_icinitpara);
    timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_BOTH_EDGE;
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter    = 0x0;
    timer_input_capture_config(TIMER0, TIMER_CH_1, &timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER0);
    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_UP);
    /* channel 0 interrupt enable */
    timer_interrupt_enable(TIMER0, TIMER_INT_UP);
    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH1);
    /* channel 0 interrupt enable */
    timer_interrupt_enable(TIMER0, TIMER_INT_CH1);

    /* TIMER0 counter enable */
    timer_enable(TIMER0);
}

中断处理:
__IO uint16_t u16_cap_tick = 0;
__IO uint32_t u32_cap_tick = 0;
__IO uint32_t u32_cap_tick_pre = 0;
__IO uint16_t ovf_cont = 0;
__IO uint32_t err_cnt = 0;


void TIMER0_BRK_UP_TRG_CMT_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_UP)) {
        /* clear channel1 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_UP);

        /* count overflow value */
        ovf_cont++;


    }
}


void TIMER0_Channel_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH1)) {
        /* clear channel1 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH1);

        /* read channel 1 capture value */
        u16_cap_tick = timer_channel_capture_value_register_read(TIMER0, TIMER_CH_1);

        u32_cap_tick_pre = u32_cap_tick;
        u32_cap_tick = u16_cap_tick + (ovf_cont << 16);

        if(u32_cap_tick_pre > u32_cap_tick)
        {
          err_cnt++;
        }
    }
}

出现问题:TIMER0 CNT接近上溢时发生CH1捕获中断, 捕获中断有一定几率先于UP中断处理,导致err_cnt计数错误。
示例中,err_cnt会有计数。
回答 +关注 1
1828人浏览 11人回答问题 分享 举报
11 个回答

您需要登录后才可以回复 登录 | 注册