测试硬件: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会有计数。
|