STM32通用定時器配置
一、STM32通用定時器原理
STM32 系列的CPU,有多達8個定時器,其中TIM1和TIM8是能夠產生三對PWM互補輸出的高階定時器,常用於三相電機的驅動,它們的時鐘由APB2的輸出產生。其它6個為普通定時器,時鐘由
下圖是STM32參考手冊上時鐘分配圖中,有關定時器時鐘部分的截圖:
從圖中可以看出,定時器的時鐘不是直接來自APB1或APB2,而是來自於輸入為APB1或APB2的一個倍頻器,圖中的藍色部分。
下面以通用定時器2的時鐘說明這個倍頻器的作用:當APB1的預分頻係數為1時,這個倍頻器不起作用,定時器的時鐘頻率等於APB1的頻率;當APB1的預分頻係數為其它數值(即預分頻係數為2、4、8或16)時,這個倍頻器起作用,定時器的時鐘頻率等於APB1的頻率兩倍。
可能有同學還是有點不理解,OK,我們舉一個例子說明。假定AHB=36MHz,因為APB1允許的最大頻率為
當預分頻係數=1時,APB1=36MHz,TIM2~7的時鐘頻率=36MHz(倍頻器不起作用);
當預分頻係數=2時,APB1=18MHz,在倍頻器的作用下,TIM2~7的時鐘頻率=36MHz。
有人會問,既然需要TIM2~7的時鐘頻率=36MHz,為什麼不直接取APB1的預分頻係數=1?答案是:APB1不但要為TIM2~7提供時鐘,而且還要為其它外設提供時鐘;設定這個倍頻器可以在保證其它外設使用較低時鐘頻率時。
Stm32外設使用者手冊,如圖:
再舉個例子:當AHB=72MHz時,APB1的預分頻係數必須大於
TIMER_cfg(); //定時器的配置
//開啟定時器2
TIM_Cmd(TIM2,ENABLE);
voidTimer_Config(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_DeInit(TIM2);
TIM_TimeBaseStructure.TIM_Period=2000-1; //自動重灌載暫存器的值
TIM_TimeBaseStructure.TIM_Prescaler=(36000-1); //時鐘預分頻數
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //取樣分頻
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除溢位中斷標誌
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE); /開啟時鐘
}
我們每個語句都來解釋一下。首先我們想使用定時器,就必須使能定時器的時鐘,這就是函式RCC_APB1PeriphClockCmd();,通過它開啟 RCC_APB1Periph_TIM2。
TIM_DeInit(TIM2);該函式主要用於復位TIM2定時器,使之進入初始狀態。
然後我們對自動重灌載暫存器賦值,TIM_Period的大小實際上表示的是需要經過TIM_Period次計數後才會發生一次更新或中斷。接下來需要設定時鐘預分頻數TIM_Prescaler,這裡有一個公式,我們舉例來說明:例如時鐘頻率=72MHZ/(時鐘預分頻+1)。說明當前設定的這個TIM_Prescaler,直接決定定時器的時鐘頻率。通俗點說,就是一秒鐘能計數多少次。比如算出來的時鐘頻率是2000,也就是
一秒鐘會計數2000次,而此時如果TIM_Period設定為4000,即4000次計數後就會中斷一次。由於時鐘頻率是一秒鐘計數2000次,因此只要2秒鐘,就會中斷一次。
再往後的程式碼,還有一個需要注意的,TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;就是我們一般採用向上計數模式,即每次計數就會加1,直到暫存器溢位發生中斷為止。最後別忘了,需要使能定時器!!
發生中斷時間=(TIM_Prescaler+1)* (TIM_Period+1)/FLK
用上述公式可算出:發生中斷時間 (2000-1+1)*(36000-1+1)/72000000=1 秒
步驟五:編寫中斷服務程式。同樣需要注意的,一進入中斷服務程式,第一步要做的,就是清除掉中斷標誌位。由於我們使用的是向上溢位模式,因此使用
的函式應該是:TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);。