EFM32提供的開發套件常式裡好像沒有關於定時器的常式,這兩天在調試過程中用到了定時器,雖然使用定時器很容易,但是在定時器的配置、中斷的設定過程中還是花費了一些時間。現在我把定時器的使用過程和配置程式貼上來,方便以後有人用到時可以很快的添加到自己的項目中。
1、初始化定時器,如果只做定時應用,只需要設定定時器的時鐘、定時模式、Top寄存器。
void InitTimer1(void){ TIMER_Init_TypeDef init_timer; //首先定義一個用於定時器初始化的結構體 CMU_ClockEnable(cmuClock_TIMER1, true); //開啟定時器Timer1的時鐘 CMU_ClockEnable(cmuClock_HFPER, true); //開啟高速外設時鐘 TIMER_TopSet(TIMER1,16250); //設定Timer1的Top寄存器,用於設定定時器的定時周期
//當計數器的值增加到和此值相等時,將會置位定時器的IF寄存器中的OF溢出中斷標誌位
//Top寄存器必須在調用TIMER_Init函數前進行設定
//設定定時器 init_timer.enable = true; /* Enable timer when init complete. */ //開啟定時器 init_timer.debugRun = false; /* Stop counter during debug halt. */ //調試暫停時,定時器停止運行 init_timer.prescale = timerPrescale8; /* prescaling 8 */ //分頻係數為8 init_timer.clkSel = timerClkSelHFPerClk; /* Select HFPER clock. */ //選擇高速外設時鐘 init_timer.count2x = false; /* Not 2x count mode. */ //關閉雙通道計數 init_timer.ati = false; /* No ATI. */ //關閉ati init_timer.fallAction = timerInputActionNone; /* No action on falling input edge. */ //下降沿無動作 init_timer.riseAction = timerInputActionNone; /* No action on rising input edge. */ //上升沿無動作 init_timer.mode = timerModeUp; /* Up-counting. */ //增加數模式 init_timer.dmaClrAct = false; /* Do not clear DMA requests when DMA channel is active. */ // init_timer.quadModeX4 = false; /* Select X2 quadrature decode mode (if used). */ // init_timer.oneShot = false; /* Disable one shot. */ // init_timer.sync = false; /* Not started/stopped/reloaded by other timers. */ // TIMER_Init(TIMER1,&init_timer); //初始化定時器 TIMER_IntEnable(TIMER1,TIMER_IEN_OF); //開啟溢出中斷}
2、添加定時中斷函數,EFM32的庫函數已經將此函數和Timer1中斷源進行關聯,只需要添加此函數即可。
void TIMER1_IRQHandler(void){ TIMER_IntClear(TIMER1,TIMER_IFC_OF); //清除定時中斷標誌 BSP_LedToggle(0); //LED翻轉,}
3、最後,在主函數main中開啟全域中斷。
INT_Disable(); //關閉全域中斷 /* Enable TIMER1 interrupt in NVIC. */ NVIC_EnableIRQ(TIMER1_IRQn); //開啟Timer1中斷 InitTimer1(); //設定Timer1 /* Initialization done, enable interrupts globally. */ INT_Enable(); //開啟全域中斷
將以上代碼添加到程式中,調試運行就能進入到定時中斷TIMER1_IRQHandler函數中。我的電路中外部晶振為26M,定時器設定時選擇8分頻,所以定時器的時鐘頻率為26M/8=3.25MHz,16250*(1/3.25M)=5ms,即定時周期為5ms,用示波器測試,驅動LED的脈衝寬度為5ms。
以上程式用到了庫中的em_int.h、em_timer.c,需要將這兩個檔案添加到工程中。