這一課我們將介紹CKS32F4XX系列產(chǎn)品的定時(shí)器使用,CKS32F4XX的定時(shí)器功能十分強(qiáng)大,包含2個(gè)高級控制定時(shí)器,8個(gè)普通定時(shí)器,2個(gè)基礎(chǔ)定時(shí)器,以及兩個(gè)看門狗定時(shí)器和一個(gè)系統(tǒng)定時(shí)器,總共15個(gè)定時(shí)器之多。關(guān)于定時(shí)器部分內(nèi)容的講解我們將分3個(gè)部分展開,本節(jié)將介紹定時(shí)器的基本特征和定時(shí)操作。
1、計(jì)數(shù)器分辨率:指定時(shí)器一個(gè)計(jì)數(shù)周期,例如同樣是84Mhz的工作時(shí)鐘,
對于TIM2,其分辨率的范圍為:1*(1000ns/ 84)~(2^32)*(1000ns/84);
對于TIM3,其分辨率的范圍為:1*(1000ns/84)~(2^16)*(1000ns/84)。
2、計(jì)數(shù)器類型:這個(gè)參數(shù)按照計(jì)數(shù)的方向來劃分:
向上計(jì)數(shù)指的是從0開始到1,2...直到自己設(shè)置的計(jì)數(shù)上限值N,達(dá)到后再次從0開始計(jì)數(shù),周而復(fù)始;
向下計(jì)數(shù)指的是從設(shè)置的計(jì)數(shù)上限值N開始到N-1,N-2,...直到0,達(dá)到后再次從N開始計(jì)數(shù),周而復(fù)始;向上向下計(jì)數(shù)指的是從0,1,2...N,然后再從N,N-1,N-2...0,周而復(fù)始。
3、預(yù)分頻系數(shù):可以通過設(shè)置該系數(shù)來配置時(shí)基,如定時(shí)器工作在84Mhz下,配置不分頻則一個(gè)計(jì)數(shù)時(shí)基為11.9ns,配置成2分頻則一個(gè)計(jì)數(shù)時(shí)基為23.8ns。
4、產(chǎn)生DMA請求:定時(shí)器的更新會發(fā)出DMA請求,這是因?yàn)樵贒MA通道中為Timer預(yù)留了一個(gè)通道。
5、捕獲比較通道:捕獲就是定時(shí)器可以捕捉到通道的上升沿或者下降沿信號,比較就是定時(shí)器可以將計(jì)數(shù)器的值和裝載值做比較,關(guān)于這部分將會在下后續(xù)章節(jié)展開。
6、互補(bǔ)輸出:互補(bǔ)輸出指的是輸出的兩個(gè)通道兩個(gè)波形完全相反,通常運(yùn)用在橋式電路中的互補(bǔ)PWM輸出,這一部分將在后續(xù)章節(jié)展開。
7、最大接口時(shí)鐘和最大工作時(shí)鐘:定時(shí)器的時(shí)鐘來源是APB,通過APB預(yù)分頻器的配置,最大工作時(shí)鐘可以是PCLKx的兩倍。
CKS32F4XX定時(shí)器的定時(shí)操作
定時(shí)器的定時(shí)操作原理其實(shí)很簡單,就像家里用的微波爐一樣,需要加熱食物時(shí),先設(shè)定一個(gè)加熱時(shí)間,然后按下開關(guān),開始計(jì)時(shí),當(dāng)達(dá)到我們設(shè)置的定時(shí)時(shí)間以后,微波爐就會停止工作,并會有一個(gè)聲音提示我們,定時(shí)時(shí)間到了。當(dāng)然,在完成定時(shí)操作之前,必須要對Timer進(jìn)行一些配置,下面我們以timer3為例,為大家演示。
1、Timer3時(shí)鐘使能
TIM3時(shí)鐘來自于APB1域,我們通過APB1總線下的時(shí)鐘使能函數(shù)來使能TIM3的時(shí)鐘。調(diào)用的函數(shù)是:
//>>使能TIM3時(shí)鐘 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);typedefstruct
2、定時(shí)器參數(shù)初始化
在庫函數(shù)中定時(shí)器的初始化通過TIM_TimeBaseInit實(shí)現(xiàn)的:
voidTIM_TimeBaseInit(TIM_TypeDef*TIMx, TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct);
參數(shù)結(jié)構(gòu)體指針,結(jié)構(gòu)體類型為TIM_TimeBaseInitTypeDef,下面是結(jié)構(gòu)體的定義:
typedefstruct { uint16_tTIM_Prescaler; uint16_tTIM_CounterMode; uint16_tTIM_Period; uint16_tTIM_ClockDivision; uint8_tTIM_RepetitionCounter; }TIM_TimeBaseInitTypeDef;typedefstruct
這個(gè)結(jié)構(gòu)體一共有5個(gè)成員變量,要說明的是,對于通用定時(shí)器只有前面四個(gè)參數(shù)有用,最后參數(shù)TIM_RepetitionCounter是高級定時(shí)器才有用的,后續(xù)章節(jié)會詳解,在此不贅述。
第一個(gè)參數(shù)TIM_Prescaler是用來設(shè)置分頻系數(shù)的,對應(yīng)上表中的預(yù)分頻系數(shù)。
第二個(gè)參數(shù)TIM_CounterMode是用來設(shè)置計(jì)數(shù)方式,如上表所述,可以設(shè)置為向上計(jì)數(shù),向下計(jì)數(shù)方式還有向上向下計(jì)數(shù)(中央對齊計(jì)數(shù))方式,比較常用的是向上計(jì)數(shù)TIM_CounterMode_Up和向下計(jì)數(shù) TIM_CounterMode_Down。
第三個(gè)參數(shù)是設(shè)置自動重載計(jì)數(shù)周期值,可以通俗的理解成要定時(shí)的次數(shù),這個(gè)是根據(jù)定時(shí)時(shí)間和時(shí)基做除法換算得到的,比如定時(shí)器現(xiàn)在計(jì)數(shù)1次,時(shí)間經(jīng)過了250ns,要定時(shí)100us,那自動重載計(jì)數(shù)周期值為400。
第四個(gè)參數(shù)是用來設(shè)置時(shí)鐘分頻因子,這個(gè)參數(shù)與定時(shí)器的其他功能有密切,本節(jié)操作先按照TIM_CKD_DIV1來配置(不分頻)。
針對TIM3初始化范例代碼格式:
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period=5000; TIM_TimeBaseStructure.TIM_Prescaler=7199; TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, TIM_TimeBaseStructure);
3、設(shè)置TIM3_DIER允許更新中斷
因?yàn)槲覀円_(dá)到定時(shí)時(shí)間到后有一個(gè)到時(shí)提醒的效果,這就需要用到TIM3的更新中斷,在庫函數(shù)里面定時(shí)器中斷使能是通過TIM_ITConfig函數(shù)來實(shí)現(xiàn)的:
voidTIM_ITConfig(TIM_TypeDef*TIMx,uint16_tTIM_IT,FunctionalStateNewState);
第一個(gè)參數(shù)是選擇定時(shí)器號,取值為 TIM1~TIM17。
第二個(gè)參數(shù)非常關(guān)鍵,是用來指明我們使能的定時(shí)器中斷的類型,定時(shí)器中斷的類型有很多種,包括更新中斷TIM_IT_Update,觸發(fā)中斷TIM_IT_Trigger,以及輸入捕獲中斷等等。
第三個(gè)參數(shù)就很簡單了,就是失能還是使能。
例如我們要使能TIM3的更新中斷,格式為:
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
4、TIM3中斷優(yōu)先級設(shè)置
在定時(shí)器中斷使能之后,因?yàn)橐a(chǎn)生中斷,必不可少的要設(shè)置NVIC(向量中斷控制器)來設(shè)置中斷優(yōu)先級。關(guān)于NVIC_Init函數(shù)實(shí)現(xiàn)中斷優(yōu)先級的設(shè)置請到NVIC章節(jié)參考,這里就不重復(fù)講解。
5、使能TIM3
配置好定時(shí)器后,不要忘記開啟定時(shí)器,就像按下微波爐的開關(guān)一樣,定時(shí)器才會進(jìn)入工作狀態(tài),在固件庫里面使能定時(shí)器的函數(shù)是通過TIM_Cmd函數(shù)來實(shí)現(xiàn)的:
voidTIM_Cmd(TIM_TypeDef*TIMx,FunctionalStateNewState)
這個(gè)函數(shù)非常簡單,比如我們要使能定時(shí)器3,方法為:
//>>使能TIMx外設(shè) TIM_Cmd(TIM3,ENABLE);
6、編寫中斷服務(wù)函數(shù)
最后,要編寫定時(shí)器中斷服務(wù)函數(shù),類似于聽到微波爐結(jié)束工作的聲音后,我們需要進(jìn)行把加熱的食物取出或者繼續(xù)加熱等操作,通過該函數(shù)來處理定時(shí)器產(chǎn)生的相關(guān)中斷。在中斷產(chǎn)生后,通過狀態(tài)寄存器的值來判斷此次產(chǎn)生的中斷屬于什么類型。然后執(zhí)行相關(guān)的操作,我們這里使用的是更新(溢出)中斷,在處理完中斷之后應(yīng),該向TIM3_SR的最低位寫0,來清除該中斷標(biāo)志,在固件庫函數(shù)里面,用來讀取中斷狀態(tài)寄存器的值判斷中斷類型的函數(shù)是:ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t)
該函數(shù)的作用是,判斷定時(shí)器TIMx的中斷類型 TIM_IT是否發(fā)生中斷。比如,我們要判斷定時(shí)器3 是否發(fā)生更新(溢出)中斷,方法為:
if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){}IT_Update)!=RESET){}
固件庫中清除中斷標(biāo)志位的函數(shù)是:
voidTIM_ClearITPendingBit(TIM_TypeDef*TIMx,uint16_tTIM_IT)
該函數(shù)的作用是,清除定時(shí)器TIMx的中斷TIM_IT 標(biāo)志位。使用起來非常簡單,比如我們在TIM3的溢出中斷發(fā)生后,我們要清除中斷標(biāo)志位,方法是:
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
這里需要說明一下,固件庫還提供了兩個(gè)函數(shù)用來判斷定時(shí)器狀態(tài)以及清除定時(shí)器狀態(tài)標(biāo)
志位的函數(shù)TIM_GetFlagStatus 和TIM_ClearFlag,他們的作用和前面兩個(gè)函數(shù)的作用類似。只 是在TIM_GetITStatus函數(shù)中會先判斷這種中斷是否使能,使能了才去判斷中斷標(biāo)志位,而TIM_GetFlagStatus 直接用來判斷狀態(tài)標(biāo)志位。通過以上幾個(gè)步驟,我們就可以達(dá)到我們的目的了,使用通用定時(shí)器的更新中斷,來實(shí)現(xiàn)定時(shí)并產(chǎn)生定時(shí)中斷信號。
代碼實(shí)例
/**通用定時(shí)器3中斷初始化
>>arr:自動重裝值。psc:時(shí)鐘預(yù)分頻數(shù)
>>定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us.
>>Ft=定時(shí)器工作頻率,單位:Mhz
這里使用的是定時(shí)器3**/
voidTIM3_Int_Init(u16arr,u16psc) { TIM_TimeBaseInitTypeDefTIM_TimeBaseInitStructure; NVIC_InitTypeDefNVIC_InitStructure; //>>①使能TIM3時(shí)鐘 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //>>自動重裝載值 TIM_TimeBaseInitStructure.TIM_Period=arr; //>>定時(shí)器分頻 TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //>>向上計(jì)數(shù)模式 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //②初始化定時(shí)器TIM3 TIM_TimeBaseInit(TIM3, TIM_TimeBaseInitStructure); //③允許定時(shí)器3更新中斷 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //定時(shí)器3中斷 NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //搶占優(yōu)先級1 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //響應(yīng)優(yōu)先級3 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //④初始化NVIC NVIC_Init( NVIC_InitStructure); //⑤使能定時(shí)器3 TIM_Cmd(TIM3,ENABLE); } //⑥定時(shí)器3中斷服務(wù)函數(shù) voidTIM3_IRQHandler(void) { //>>溢出中斷 if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) { } //>>清除中斷標(biāo)志位 TIM_ClearITPendingBit(TIM3,TIM_IT_Update); }
這里列出了一個(gè)中斷服務(wù)函數(shù)和一個(gè)定時(shí)器3中斷初始化函數(shù),中斷服務(wù)函數(shù)中,在每次中斷后,判斷 TIM3的中斷類型,如果中斷類型正確,則執(zhí)行自己需要執(zhí)行的操作并清除中斷標(biāo)志,TIM3_Int_Init 函數(shù)就是執(zhí)行我們上面介紹的那5個(gè)步驟,使得 TIM3開始工作,并開啟中斷。這里我們分別用標(biāo)號①~⑤來標(biāo)注定時(shí)器初始化的五個(gè)步驟。該函數(shù)的2 個(gè)參數(shù)用來設(shè)置TIM3的溢出時(shí)間。假設(shè)系統(tǒng)初始化 SystemInit函數(shù)里面已經(jīng)初始化APB1的時(shí)鐘為 4分頻,所以APB1的時(shí)鐘為42M,這也是timer3的最大接口時(shí)鐘,而從CKS32F4的內(nèi)部時(shí)鐘樹圖得知:當(dāng)APB1的時(shí)鐘分頻數(shù)為1的時(shí)候,TIM2~7以及TIM12~14的時(shí)鐘為APB1的時(shí)鐘,而如果APB1的時(shí)鐘分頻數(shù)不為1,那么TIM2~7以及TIM12~14的時(shí)鐘頻率將為APB1時(shí)鐘的兩倍。因此,TIM3的時(shí)鐘為84M,再根據(jù)我們設(shè)計(jì)的arr和psc的值,就可以計(jì)算中斷時(shí)間了。計(jì)算公式如下:
Tout=((arr+1)*(psc+1))/Tclk;
其中:
Tclk:TIM3的輸入時(shí)鐘頻率(單位為Mhz)。
Tout:TIM3溢出時(shí)間(單位為us)。
本節(jié)我們介紹了CKS32F4XX各定時(shí)器概況,以及如何設(shè)置最基礎(chǔ)的定時(shí)功能,包括開啟定時(shí)器的時(shí)鐘,配置定時(shí)器的時(shí)基,定時(shí)次數(shù)以及計(jì)數(shù)的方向等,此外定時(shí)器其他的功能如輸入捕獲,比較輸出和PWM輸出等功能將會在后續(xù)章節(jié)展開。
來源:中科芯MCU
審核編輯:湯梓紅
-
mcu
+關(guān)注
關(guān)注
146文章
17148瀏覽量
351185 -
中斷
+關(guān)注
關(guān)注
5文章
898瀏覽量
41495 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3248瀏覽量
114792 -
Timer
+關(guān)注
關(guān)注
1文章
64瀏覽量
12786
發(fā)布評論請先 登錄
相關(guān)推薦
評論