天天看點

GD32F103定時器使用内部時鐘作為時鐘源

#include "Timer0.h"

#include "LED.h"

void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc);

//函數功能:通用定時器0中斷初始化

//這裡時鐘選擇為APB1的2倍,而APB1為36M

//arr:自動重裝值。

//psc:時鐘預分頻數

//Timer_Interrupt_Initializtion(TIMER0,50000,1080);//當arr=50000,psc=1080時,則為500ms,誤差為10us;

void Timer_Interrupt_Initializtion(uint32_t timer_periph,uint16_t arr,uint16_t psc)

{

    timer_parameter_struct TimerParameterStruct;

    switch(timer_periph)

    {

        case TIMER0:

        rcu_periph_clock_enable(RCU_TIMER0);      //使能TIMER0的APB2外設時鐘

          nvic_irq_enable(TIMER0_UP_IRQn, 2U, 0U);  //設定TIMER0_UP_IRQn的中斷優先級,搶占優先級為2,子優先級為0

        break;

    case TIMER1:

            rcu_periph_clock_enable(RCU_TIMER1);

          nvic_irq_enable(TIMER1_IRQn, 2U, 0U);  //設定TIMER1_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    case TIMER2:

            rcu_periph_clock_enable(RCU_TIMER2);

          nvic_irq_enable(TIMER2_IRQn, 2U, 0U);  //設定TIMER2_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    case TIMER3:

            rcu_periph_clock_enable(RCU_TIMER3);

          nvic_irq_enable(TIMER3_IRQn, 2U, 0U);  //設定TIMER3_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    case TIMER4:

            rcu_periph_clock_enable(RCU_TIMER4);

          nvic_irq_enable(TIMER4_IRQn, 2U, 0U);  //設定TIMER4_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    case TIMER5:

            rcu_periph_clock_enable(RCU_TIMER5);

          nvic_irq_enable(TIMER5_IRQn, 2U, 0U);  //設定TIMER5_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    case TIMER6:

            rcu_periph_clock_enable(RCU_TIMER6);

          nvic_irq_enable(TIMER6_IRQn, 2U, 0U);  //設定TIMER6_IRQn的中斷優先級,搶占優先級為2,子優先級為0

          break;

    default:

        break;

    }

    timer_deinit(timer_periph);                 //複位TIMERx

TIMERx配置開始

    TimerParameterStruct.period            = arr-1; //設定在下一個更新事件裝入活動的自動重裝載寄存器周期的值

    TimerParameterStruct.prescaler         = psc-1; //設定用來作為TIMx時鐘頻率除數的預分頻值(APB2時鐘分頻值)

    TimerParameterStruct.clockdivision     = TIMER_CKDIV_DIV1;   //設定時鐘分母值為1

    //計算公式:arr*psc/108000000/1,當arr=250,psc=108時,則為0.25ms,誤差為1us;

    TimerParameterStruct.counterdirection  = TIMER_COUNTER_UP;   //設定計數方向為"向上計數"

    TimerParameterStruct.alignedmode       = TIMER_COUNTER_EDGE; //設定為無中央對齊計數模式(邊沿對齊模式)

    TimerParameterStruct.repetitioncounter = 0;                  //設定"重複計數次數"為0

    timer_init(timer_periph,&TimerParameterStruct);//根據TimerParameterStruct所指向的參數初始化TIMERx的時間基數機關

TIMERx配置結束

    timer_counter_value_config(timer_periph,0);//設定TIMERx的計數器初始值為0

    //timer_counter_read(timer_periph);//讀取TIMERx的計數器值

  timer_auto_reload_shadow_enable(timer_periph);//使能TIMERx自動重裝載

    timer_flag_clear(timer_periph,TIMER_FLAG_UP);               //清除"TIMERx更新标志位"

    timer_interrupt_flag_clear(timer_periph,TIMER_INT_FLAG_UP); //清除"TIMERx更新中斷标志位"

    timer_interrupt_enable(timer_periph,TIMER_INT_UP);          //使能"TIMERx更新"産生中斷

  timer_internal_clock_config(timer_periph);//設定"内部時鐘"作為定時器時鐘

    //timer_slave_mode_select(timer_periph,TIMER_SLAVE_MODE_DISABLE);

    //設定"關閉從模式",如果TIMER計數器使能,則預分頻器直接由内部時鐘驅動

    timer_enable(timer_periph);//TIMERx計數器使能,開始工作

}

//函數功能:TIMER0更新中斷服務程式

void TIMER0_UP_IRQHandler(void)

{

    if( timer_interrupt_flag_get(TIMER0,TIMER_INT_FLAG_UP) )// 讀取更新中斷标志位

    {

        LED2_Toggle();

        timer_flag_clear(TIMER0,TIMER_FLAG_UP);               //清除"TIMER0更新标志位"

        timer_interrupt_flag_clear(TIMER0,TIMER_INT_FLAG_UP); //清除"更新中斷标志位"

    }

}