1.1 按照內(nèi)核、外核、特定、常規(guī)分為4大類:
1)內(nèi)核定時器:Systick
2)外設(shè)定時器:特定應(yīng)用定時器+常規(guī)定時器
3)特定應(yīng)用定時器:LPTIM,RTC,WTD,HRTIM
- 常規(guī)定時器:基本定時器TIM6&TIM7)、通用定時器(TIM2
TIM5,TIM9TIM14)、高級定時器(TIM1&TIM8)
**1.2 CPU時序 **
此處我們提一下學(xué)習(xí)單片機原理的課程時,提到的幾個CPU時序。
振蕩周期:為單片機提供定時信號的振蕩源的周期。
狀態(tài)周期:1個狀態(tài)周期=2個振蕩周期
**機器周期:1個機器周期=6個狀態(tài)周期=12個振蕩周期**
指令周期:完成1條指令所占用的全部時間,以機器周期為單位。
以12MHz外接晶振為例
振蕩周期=1/12us,相當(dāng)于1/12*10^6,所以單位為us;
狀態(tài)周期=1/6us
機器周期=1us
指令周期=1~4us
STM32共有14組常規(guī)定時器,其實也可以稱為計數(shù)器,定時器/計數(shù)器的工作過程是自動完成的,不需要CPU的參與,互相獨立,執(zhí)行不同的任務(wù),可以增加單片機的效率。
二、定時器中斷原理
2.1 何為定時器中斷:定時器中斷是由單片機中的定時器溢出而申請的中斷。
提到中斷,必須滿足幾個要素: 中斷源 , 中斷請求 , 中斷優(yōu)先級 。 使CPU發(fā)生中斷的事件稱為中斷源,中斷源向CPU發(fā)出中斷請求,CPU暫時中斷原來執(zhí)行的事件A轉(zhuǎn)去執(zhí)行事件B,事件B處理完成后繼續(xù)返回原先中斷的位置(該過程稱為中斷返回,原先中斷的地方稱為斷點),繼續(xù)執(zhí)行原先的事件。
2.2 中斷流程可以用下圖表示:
2.3 中斷優(yōu)先級
在 《嵌入式學(xué)習(xí)(八)—STM32中斷優(yōu)先級分組與搶占優(yōu)先級和響應(yīng)優(yōu)先級的關(guān)系》 這篇文章里,介紹了STM32中的 中斷優(yōu)先級分組、中斷優(yōu)先級(搶占優(yōu)先級&響應(yīng)優(yōu)先級) 、嵌套向量中斷控制器NVIC等概念,那么我們定時器中斷也必須滿足這個規(guī)則---定時器中斷也要用NVIC來設(shè)置其中斷組別、搶占優(yōu)先級、響應(yīng)優(yōu)先級。
STM32中斷分組有5種
#define NVIC_PriorityGroup_0 ((uint32_t)0x700)
/*!< 0 bits for pre-emption priority 4 bits for subpriority */
#define NVIC_PriorityGroup_1 ((uint32_t)0x600)
/*!< 1 bits for pre-emption priority 3 bits for subpriority */
#define NVIC_PriorityGroup_2 ((uint32_t)0x500)
/*!< 2 bits for pre-emption priority 2 bits for subpriority */
#define NVIC_PriorityGroup_3 ((uint32_t)0x400)
/*!< 3 bits for pre-emption priority1 bits for subpriority */
#define NVIC_PriorityGroup_4 ((uint32_t)0x300)
/*!< 4 bits for pre-emption priority 0 bits for subpriority */
在函數(shù)中要調(diào)用
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
實現(xiàn)對某一個中斷的中斷分組和優(yōu)先級配置。
與定時器配置緊密相關(guān)的就是自動重裝載計數(shù)器(CNT)和預(yù)分頻器(PSC),初始化定時器就是對定時器的CNT、PSC進行設(shè)置。下面介紹一下與本文密切相關(guān)的幾個通用定時器的寄存器
三、定時器相關(guān)寄存器及中斷編程
3.1****定時器相關(guān)寄存器
3.1.1 控制寄存器TIMx_CR1
位0 CEN:計數(shù)器使能,0:禁止計數(shù)器,1,使能計數(shù)器
注意:只有事先通過軟件將CEN位置去,才可以使用外部時鐘、門控模式、編碼器模式,而觸發(fā)模式可以通過硬件自動將CEN置1;在單脈沖模式下,當(dāng)發(fā)生更新事件時會自動將CEN位清零。
本實驗中,我們只用到了TIMx_CR1的最低位,也就是計數(shù)器使能位,該位必須置1,才能讓定時器開始計數(shù)。
3.1.2 DMA中斷使能寄存器 TIMx_DIER
位0 UIE:更新中斷使能,0:禁止更新中斷,1:使能更新中斷
TIMx_DIER是一個16bit的寄存器,對于要實現(xiàn)的中斷試驗,我們僅關(guān)心第0bit,因為定時器中斷實驗要用到定時器的更新中斷,所以將該位置為1,表示允許更新時間所產(chǎn)生的中斷。
3.1.3預(yù)分頻寄存器TIMx_PSC
位0:15 PSC:預(yù)分頻器值。(范圍是0~65535)
表示計數(shù)器時鐘頻率CK_INT 等于Fck_psc/(PSC[15:0]+1).PSC包含在每次發(fā)生更新事件時要裝載到實際預(yù)分頻器寄存器的值。(84MHz的CK_INT,那計數(shù)器的時鐘頻率為84/(PSC[15:0]+1)MHz,計數(shù)器時鐘的取值范圍為(0.00128~84)MHz,那么計數(shù)器時鐘周期為0.012us(84MHz)~781us(0.001MHz);
***這個地方要注意:預(yù)分頻值=實際分頻值-1,***如果要設(shè)定實際分頻值為8400(定時器的工作頻率為10kHz),那我們設(shè)定預(yù)分頻值為8399
也再復(fù)習(xí)一下定時器的時鐘知識:
1.STM32總的有3種時鐘源,分為 內(nèi)部時鐘、外部時鐘、鎖相環(huán)倍頻輸出時鐘, 包含LSI,LSE,HSI,HSE等;
2.系統(tǒng)時鐘為168MHz,其他時鐘都是通過分頻(系統(tǒng)時鐘除以一個分頻系數(shù))給系統(tǒng)的各板塊使用;
3.看下圖三個紅色框的部分,系統(tǒng)時鐘(以F407系列為例)是168MHZ,通過設(shè)置不同的分頻值給AHB總線,看第一個紅框,可以設(shè)置為1.2...512,然后AHB總線再分頻給APB分線,看第二個紅框,再次分頻的值可以為1.2.4.8.16,上面的是直接分頻過后給APBx外設(shè)時鐘使用,我們重點看第二根線,注意第三個紅框,如果APBx的分頻值設(shè)置為1,那么APBx的定時器時鐘的時鐘頻率設(shè)置為與APB一樣,如果是其他的數(shù)字,那么設(shè)置為APB的時鐘頻率的兩倍。通過查手冊知道兩個基本定時器的時鐘頻率都歸屬于APB線上的,且APB1和APB2的分頻系數(shù)都不為1(可以通過中找到配置),因此基本定時器的時鐘頻率已經(jīng)確定。
看下面這張圖,在文件system.stm324fxx.c中可以找到,
第一行表示系統(tǒng)時鐘來源是HSE,之前提過,它是高速外部時鐘,由外部晶振產(chǎn)生,第二三行表示系統(tǒng)時鐘設(shè)置為168MHZ(由外部時鐘HSE倍頻實現(xiàn),具體這里不深究),第四五六行,分別表示AHB,APB1,APB2的分頻系數(shù),即分別設(shè)置為168MHZ,42MHZ,84MHZ。
注意,如前所述APB1的分頻值為4,不為1,故其包含的基本定時器模塊的時鐘頻率需乘2,即42×2為84MHZ。由此我們得知基本定時器的時鐘源為84MHZ。
1)內(nèi)部時鐘(CK_INT)
2)外部時鐘模式1:外部輸入引腳(TIx)
3)外部時鐘模式2:外部觸發(fā)輸入(ETR)用于TIM2.TIM3.TIM4
- 內(nèi)部觸發(fā)輸入(ITRx),使用定時器A作為B定時器的預(yù)分頻(A為B提供時鐘)
這些時鐘,具體選擇哪個可以通過TIMx_SMCR寄存器的相關(guān)位來設(shè)置,CK_INT時鐘是從APB1倍頻來的,除非APB1的時鐘分頻數(shù)設(shè)置為1,否則通用定時器TIMx的時鐘是APB1時鐘的2倍,當(dāng)APB1時鐘不分頻時,通用定時器的時鐘就等于APB1的時鐘,這里還要注意的就是高級定時器以及TIM9~TIM11的時鐘是來自APB2。
3.1.4 TIMx_CNT計數(shù)器
位15:0 CNT[15:0]:計數(shù)器值,該寄存器存儲了當(dāng)前寄存器的計數(shù)值。范圍為065535,可以計時的范圍是051s(假定是分頻PSC設(shè)為65535,計數(shù)器時鐘頻率是84/65536MHz,每個時鐘脈沖周期為781us)
3.1.5自動重載寄存器(TIMx_ARR)
位15:0 ARR[15:0]:自動重載值。
ARR是要裝載到實際自動重載寄存器的值。需要注意,該寄存器在物理上實際對應(yīng)著2個寄存器,一個是程序員可以直接配置的,另外一個是程序員看不到的,這個看不到的寄存器叫影子寄存器,在《STM32F4xx中文參考手冊》里面有提到,事實上真正起作用的是影子寄存器,根據(jù)TIMx_CR1寄存器中的APRE位的設(shè)置:APRE=0,預(yù)裝載寄存器的內(nèi)容可以隨時傳送到影子寄存器,此時兩者是連通的;而APRE=1時,每一次更新事件(UEV)時,才能把預(yù)裝載寄存器ARR的內(nèi)容傳送到影子寄存器。
3.1.6狀態(tài)寄存器(TIMx_SR)
位0 UIF:更新中斷標(biāo)志。
- 該位在發(fā)生更新事件時通過硬件置1,但需要通過軟件清零。0:未發(fā)生更新,1:更新中斷掛起
- 上溢或者下溢(對于TIM2~TIM5)以及當(dāng)TIMx_CR1寄存器UDIS=0時,
- TIMx_CR1中的寄存器中的URS=0且UDIS=0,并且由軟件使用TIMx_EGR寄存器中的UG位重新初始化CNT時。TIMx_CR1寄存器中的URS=0&UDIS=0,并且由CNT由觸發(fā)事件重新初始化。
3.2定時器中斷編程
3.2.1編程步驟
1)TIM3時鐘使能,通過APB1ENR的第1位來設(shè)置TIM3的時鐘,APB1的分頻系數(shù)是4,那么APB1為168/4=42MHz,TIM3時鐘是APB1時鐘的2倍,等于84MHz.
2)設(shè)置TIM3_ARR和TIM3_PSC的值,通過這兩個寄存器,設(shè)置自動重裝值和分頻系數(shù),這兩個參數(shù)加上時鐘頻率決定了定時器的溢出事件。
3)設(shè)置TIM3_DIER允許更新中斷。因為我們要使用TIM3的更新中斷,所以設(shè)置DIER的UIE位為1,使能更新中斷
4)允許TIM3工作。設(shè)置好定時器參數(shù)后,還需要開啟定時器,通過TIM3_CR1的CEN位來設(shè)置
5)TIM3中斷分組設(shè)置。配置完定時器后,因為要產(chǎn)生中斷,必須要設(shè)置NVIC相關(guān)寄存器,以使能TIM3中斷。
6)編寫中斷服務(wù)函數(shù)。在中斷產(chǎn)生后,通過狀態(tài)寄存器的值來判斷此次產(chǎn)生的中斷屬于什么類型,然后執(zhí)行相關(guān)的操作,這里采用的是更新(溢出)中斷,所以要關(guān)注狀態(tài)寄存器的SR的最低位,在處理完成之后,將TIM3_SR的最低位寫0,來清除該中斷標(biāo)志。
以下是定時器3的中斷測試代碼
//通用定時器3中斷初始化
//時鐘選擇為APB1的2倍,APB1=42MHz
//arr:自動重載值
//psc:時鐘預(yù)分頻數(shù)
//定時器溢出時間:Tout=((arr+1)*(psc+1))/ft
//ft=定時器的工作頻率,MHz
void TIM3_Int_Init(u16 arr,u16 psc)
{
RCC- >APB1ENR|=1< 1;//TIM3時鐘使能
TIM3- >ARR=arr; //設(shè)定計數(shù)器自動重裝值
TIM3- >PSC=psc; //預(yù)分頻器
TIM3- >DIER|=1< 0; //允許更新中斷
TIM3- >CR1|=0x01; //使能定時器3
MY_NVIC_Init(1,3,TIM3_IRQn,2);//搶占1,子優(yōu)先級3,組2 }
//定時器3中斷服務(wù)程序
void TIM3_IRQHandler(void)
{
if(TIM3- >SR&0X0001)//溢出中斷
{
LED1=!LED1;
}
TIM3- >SR&=~(1< 0);//清除中斷標(biāo)志位
}
-
鎖相環(huán)
+關(guān)注
關(guān)注
35文章
584瀏覽量
87767 -
寄存器
+關(guān)注
關(guān)注
31文章
5343瀏覽量
120363 -
PSC
+關(guān)注
關(guān)注
0文章
15瀏覽量
7749 -
定時器中斷
+關(guān)注
關(guān)注
0文章
49瀏覽量
11183 -
stm32定時器
+關(guān)注
關(guān)注
0文章
13瀏覽量
2294
發(fā)布評論請先 登錄
相關(guān)推薦
評論