天天看點

GD32定時器輸入捕獲例程官方的例程自己修改使用的

官方的例程

/**
    \brief      configure the GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
  */
void gpio_configuration(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_AF);

    /*configure PA6 (TIMER2 CH0) as alternate function*/
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
}

/**
    \brief      configure the nested vectored interrupt controller
    \param[in]  none
    \param[out] none
    \retval     none
  */
void nvic_configuration(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(TIMER2_IRQn, 1, 1);
}

/**
    \brief      configure the TIMER peripheral
    \param[in]  none
    \param[out] none
    \retval     none
  */
void timer_configuration(void)
{
    /* TIMER2 configuration: input capture mode -------------------
    the external signal is connected to TIMER2 CH0 pin (PA6)
    the rising edge is used as active edge
    the TIMER2 CH0CV is used to compute the frequency value
    ------------------------------------------------------------ */
    timer_ic_parameter_struct timer_icinitpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_TIMER2);

    timer_deinit(TIMER2);

    /* TIMER2 configuration */
    timer_initpara.prescaler         = 107;
    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(TIMER2,&timer_initpara);

    /* TIMER2  configuration */
    /* TIMER2 CH0 input capture configuration */
    timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_RISING;     //上升沿觸發
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter    = 0x0;
    timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER2);
    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0);
    /* channel 0 interrupt enable */
    timer_interrupt_enable(TIMER2,TIMER_INT_CH0);

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

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    gpio_configuration(); 
    gd_eval_com_init(EVAL_COM1);
    nvic_configuration();
    timer_configuration();

    while (1);
}

/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER2_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER2,TIMER_INT_CH0)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0);

        if(0 == ccnumber){
            /* read channel 0 capture value */
            readvalue1 = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0);
            ccnumber = 1;
        }else if(1 == ccnumber){
            /* read channel 0 capture value */
            readvalue2 = timer_channel_capture_value_register_read(TIMER2,TIMER_CH_0);

            if(readvalue2 > readvalue1){
                count = (readvalue2 - readvalue1); 
            }else{
                count = ((0xFFFF - readvalue1) + readvalue2); 
            }

            fre = (float)1000000 / count;
            printf("the value1 is %d,the value2 is %d\n",readvalue1,readvalue2);
            printf("the count is %d\n",count);
            printf("the frequence is %f\n",fre);
            ccnumber = 0;
        }
    }
}
           

自己修改使用的

void ACSig_In_Capture_Init(void)  //TIM2_CH0    AC_SIG-PB4
{
    timer_ic_parameter_struct timer_icinitpara;
    timer_parameter_struct timer_initpara;
	
	rcu_periph_clock_enable(RCU_TIMER2);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_AF);

	//重映射
	gpio_pin_remap_config(GPIO_TIMER2_PARTIAL_REMAP, ENABLE);	   
    gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_4);	
	
    nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
    nvic_irq_enable(TIMER2_IRQn, 1, 1);	
	
    /* TIMER2 configuration: input capture mode -------------------
    the external signal is connected to TIMER2 CH0 pin (PB4)
    the rising edge is used as active edge
    the TIMER2 CH0CV is used to compute the frequency value
    ------------------------------------------------------------ */   
    timer_deinit(TIMER2);

    /* TIMER2 configuration */
    timer_initpara.prescaler         = 215;
    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(TIMER2,&timer_initpara);

    /* TIMER2  configuration */
    /* TIMER2 CH0 input capture configuration */
    timer_icinitpara.icpolarity  = TIMER_IC_POLARITY_FALLING;     //下降沿
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter    = 0x4;                          //使能濾波功能 
    timer_input_capture_config(TIMER2,TIMER_CH_0,&timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(TIMER2);
    /* clear channel 0 interrupt bit */
    timer_interrupt_flag_clear(TIMER2,TIMER_INT_CH0);
    /* channel 0 interrupt enable */
    timer_interrupt_enable(TIMER2,TIMER_INT_CH0);

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

可以看到上面的例程使能了濾波功能,下面對濾波功能做一下介紹,并說明為什麼要用。

GD32定時器輸入捕獲例程官方的例程自己修改使用的

  輸入捕獲1濾波器CH0CAPFLT[3:0], 這個用來設定輸入采樣頻率和數字濾波器長度。 其中,fPCLK是定時器的輸入頻率(TIMxCLK) ,一般為 108Mhz,而 fDTS則是根據 TIMERx_CTL0 的 CKDIV[1:0]的設定來确定的,如果 CKD[1:0]設定為 00,那麼fDTS=fTIMER_CK=fPCLK。

GD32定時器輸入捕獲例程官方的例程自己修改使用的

  N 值就是濾波長度,舉個簡單的例子:假設 CH0CAPFLT[3:0]=0011,并設定 IC1 映射到通道 1 上,且為上升沿觸發,那麼在捕獲到上升沿的時候,再以fPCLK的頻率,連續采樣到 8 次通道 1 的電平,如果都是高電平,則說明确實是一個有效的觸發,就會觸發輸入捕獲中斷(如果開啟了的話) 。這樣可以濾除那些高電平脈寬低于 8 個采樣周期的脈沖信号,進而達到濾波的效果。

  此處我是用來采集下降沿信号,但是信号下降的比較慢。當我把濾波關掉,情況如下圖,藍色是采集信号,黃色是測試信号,進一次觸發中斷就翻轉一次黃色信号的電平。可以看到因為藍色信号下降太慢,在臨界處觸發了多次中斷。

GD32定時器輸入捕獲例程官方的例程自己修改使用的

  當我把濾波打開後,定時器就會采集多次才會觸發,這樣就可以解決信号邊沿慢的問題了。

繼續閱讀