STM32學(xué)習(xí)筆記一時(shí)鐘和定時(shí)器
STM32的時(shí)鐘系統(tǒng)相當(dāng)?shù)膹?fù)雜,包含了5個(gè)時(shí)鐘源,分別是HSI HSE LSI LSE PLL,HSI是高速內(nèi)部時(shí)鐘、RC振蕩器,頻率為8M,HSE是高速外部時(shí)鐘,即晶振,我的核心板上晶振為8M。LSI為低速內(nèi)部時(shí)鐘、RC振蕩器,頻率40k,LSE為低速外部時(shí)鐘,接32.768kHz晶振,作為RTC時(shí)鐘源。PLL為鎖相環(huán)倍頻輸出,最大不超過72M。
本文引用地址:http://m.butianyuan.cn/article/201611/318495.htm我在學(xué)習(xí)定時(shí)器時(shí)先看的是TIM3,它掛載在APB1分頻器上,APB1上面掛載的是低速外設(shè),APB2上掛載高速外設(shè)。
在system_stm32f10x.c文件下,有默認(rèn)定義SYSCLK_FREQ_72MHz,同時(shí)在SystemInit()函數(shù)下調(diào)用了SetSysClock(),根據(jù)宏定義將時(shí)鐘設(shè)為72M。
讀取SystemCoreClock變量即可獲得系統(tǒng)時(shí)鐘頻率。
在默認(rèn)情況下,系統(tǒng)的各個(gè)時(shí)鐘頻率如下:
SYSCLK:72M
AHB:72M
APB1(PCLK1):36M
APB2(PCLK2):72M
PLL:72M
詳細(xì)的定時(shí)器設(shè)定如下:
①首先要搞清楚定時(shí)器的計(jì)數(shù)時(shí)鐘頻率,在預(yù)分頻系數(shù)≠1的時(shí)候,TIM2~7的時(shí)鐘頻率為APB1的2倍,即72MHz,預(yù)分頻系數(shù)的默認(rèn)值不是1,但我并未查到該如何設(shè)置該值。
②定時(shí)器的設(shè)置主要包括定時(shí)器的初始化和中斷的初始化。
2.1 定時(shí)器初始化:
首先定義TIM_TimeBaseInitTypeDef類型的結(jié)構(gòu)體,它包含了如下的內(nèi)容:
typedef struct{uint16_t TIM_Prescaler; uint16_t TIM_CounterMode; uint16_t TIM_Period; uint16_t TIM_ClockDivision; uint8_t TIM_RepetitionCounter; } TIM_TimeBaseInitTypeDef;
第一項(xiàng)TIM_Prescaler是預(yù)分頻值,它與TIM_Period(重載周期值)的乘積即為計(jì)數(shù)的總值。
第二項(xiàng)TIM_CounterMode為計(jì)數(shù)模式,它的內(nèi)容如下:
#define TIM_CounterMode_Up ((uint16_t)0x0000)#define TIM_CounterMode_Down ((uint16_t)0x0010)#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020)#define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040)#define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060)
后面三項(xiàng)為中心對(duì)齊模式,指的是計(jì)數(shù)到一定的值,產(chǎn)生溢出事件,再向下計(jì)數(shù)到0。常用的為向上計(jì)數(shù)模式,即TIM_CounterMode_Up
第四項(xiàng)TIM_ClockDivision為時(shí)鐘分割,對(duì)于時(shí)鐘分割沒有查到太多的描述,一般設(shè)定為TIM_CKD_DIV1,或者直接填入0x0000。
第五項(xiàng)TIM_RepetitionCounter為PWM模式的一些設(shè)定,一般的定時(shí)器不用設(shè)置。
除此之外還要設(shè)置中斷的類型,一般的定時(shí)器為更新中斷,即由溢出事件產(chǎn)生的中斷,設(shè)置的方式為:TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE),其中第一項(xiàng)是定時(shí)器代號(hào),第二項(xiàng)為類型,這里設(shè)定為更新方式,第三項(xiàng)為使能。
根據(jù)上述內(nèi)容我們知道,初始化的過程如下:
3
TIM_TimeBaseInitTypeDef TIM_STR;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//TIM3掛載在APB1上//由于預(yù)分頻系數(shù)默認(rèn)不是1,所以TIM3的時(shí)鐘為2*APB1=72MTIM_STR.TIM_Period=arr;TIM_STR.TIM_Prescaler=psc;//(arr+1)*(psc+1)/TIM時(shí)鐘=定時(shí)器溢出中斷觸發(fā)周期TIM_STR.TIM_ClockDivision=TIM_CKD_DIV1;TIM_STR.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3,&TIM_STR);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
2.2 中斷初始化:
中斷初始化為操作NVIC(嵌套向量中斷控制器)函數(shù)。 設(shè)置方式如下:
NVIC_STR.NVIC_IRQChannel=TIM3_IRQn;//設(shè)定為TIM3中斷NVIC_STR.NVIC_IRQChannelPreemptionPriority=0;//先占優(yōu)先級(jí)0級(jí)NVIC_STR.NVIC_IRQChannelSubPriority=3;//從優(yōu)先級(jí)3級(jí)NVIC_STR.NVIC_IRQChannelCmd=ENABLE;//IRQ通道時(shí)能NVIC_Init(&NVIC_STR);//中斷初始化TIM_Cmd(TIM3,ENABLE);//TIM3定時(shí)器使能
2.3 把這些都封裝成一個(gè)函數(shù),既可作為TIM3的初始化函數(shù)。如下:
void TIM3_Init(u16 arr,u16 psc){//定時(shí)時(shí)間=(arr+1)*(psc+1)/72 單位為usTIM_TimeBaseInitTypeDef TIM_STR;NVIC_InitTypeDef NVIC_STR;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//初始化定時(shí)器TIM_STR.TIM_Period=arr;TIM_STR.TIM_Prescaler=psc;TIM_STR.TIM_ClockDivision=TIM_CKD_DIV1;TIM_STR.TIM_CounterMode=TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3,&TIM_STR);TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//初始化中斷NVIC_STR.NVIC_IRQChannel=TIM3_IRQn;NVIC_STR.NVIC_IRQChannelPreemptionPriority=0;NVIC_STR.NVIC_IRQChannelSubPriority=3;NVIC_STR.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_STR);//使能定時(shí)器TIM_Cmd(TIM3,ENABLE);}
③中斷服務(wù)函數(shù):
中斷函數(shù)的名字,TIM3的為TIM3_IRQHandler
中斷服務(wù)函數(shù)內(nèi)包含了:判斷是否發(fā)生中斷、中斷發(fā)生后執(zhí)行的內(nèi)容、清除標(biāo)志位三部分。
首先是判斷是否發(fā)生了更新中斷,利用庫函數(shù)TIM_GetITStatus(P1,P2),它的參數(shù)P1為代號(hào),這里是TIM3,P2為中斷類型,這里為更新中斷TIM_IT_Update,當(dāng)它為1時(shí)即發(fā)生了更新中斷,這里為了增強(qiáng)可讀性,采用一個(gè)RESET代表0,當(dāng)函數(shù)返回值不是RESET的時(shí)候,即發(fā)生了置位(中斷)。
清除標(biāo)志位采用的是庫函數(shù)TIM_ClearITPendingBit(P1,P2),參數(shù)與判斷的函數(shù)一樣。
具體函數(shù)如下:
void TIM3_IRQHandler(void){if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET){TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//在這里執(zhí)行中斷內(nèi)容}}
④完成調(diào)用
只要在main函數(shù)里調(diào)用TIM3_Init()函數(shù),并填入適當(dāng)?shù)膮?shù),即可實(shí)現(xiàn)精確的定時(shí)中斷,例如獲得一秒,即72M個(gè)數(shù)字中斷一次,可分解為10000*7200,配置如下:
TIM3_Init(9999,7199);
評(píng)論