提示:文章寫(xiě)完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
前言
本節(jié)先只講解定時(shí)器的定時(shí)中斷,內(nèi)外中斷源選擇。
一、定時(shí)器介紹
TIM(Timer)定時(shí)器
定時(shí)器可以對(duì)輸入的時(shí)鐘進(jìn)行計(jì)數(shù),并在計(jì)數(shù)值達(dá)到設(shè)定值時(shí)觸發(fā)中斷。
16位計(jì)數(shù)器、預(yù)分頻器、自動(dòng)重裝寄存器的時(shí)基單元,在72MHz計(jì)數(shù)時(shí)鐘下可以實(shí)現(xiàn)最大59.65s的定時(shí)。
不僅具備基本的定時(shí)中斷功能,而且還包含內(nèi)外時(shí)鐘源選擇、輸入捕獲、輸出比較、編碼器接口、主從觸發(fā)模式等多種功能。
根據(jù)復(fù)雜度和應(yīng)用場(chǎng)景分為了高級(jí)定時(shí)器、通用定時(shí)器、基本定時(shí)器三種類(lèi)型。
定時(shí)器類(lèi)型
注:開(kāi)啟時(shí)鐘時(shí)注意,高級(jí)定時(shí)器連接APB2總線,通用與基本定時(shí)器連接APB1總線。
基本定時(shí)器
16位計(jì)數(shù)器、預(yù)分頻器、自動(dòng)重裝寄存器構(gòu)成了最基本的計(jì)時(shí)計(jì)數(shù)電路,叫做時(shí)基單元。
基本定時(shí)器只能選擇內(nèi)部時(shí)鐘。
預(yù)分頻器:寫(xiě)0,輸入頻率=輸出頻率=72MHZ;寫(xiě)1,二分頻 ,輸出頻率=輸出頻率/2=32MHZ;
寫(xiě)n,輸出頻率=輸入頻率/(n+1)。(預(yù)分頻器是16位的,故寫(xiě)入值不得大于65535)
計(jì)數(shù)器:16位寄存器;每來(lái)一個(gè)上升沿,計(jì)數(shù)器的值加1,自增到目標(biāo)值時(shí)產(chǎn)生中斷。
自動(dòng)重裝寄存器:16位寄存器;寫(xiě)入值為固定值,是我們的目標(biāo)值,當(dāng)計(jì)數(shù)值等于自動(dòng)重裝值時(shí),產(chǎn)生中斷信號(hào),清零計(jì)數(shù)器。
上箭頭代表會(huì)產(chǎn)生中斷信號(hào)。
下箭頭代表會(huì)產(chǎn)生“更新事件”。(不會(huì)觸發(fā)中斷,但會(huì)觸發(fā)其他內(nèi)部電路的工作)。
工作流程:時(shí)鐘信號(hào)從基準(zhǔn)時(shí)鐘,到預(yù)分頻器,再到計(jì)數(shù)器。計(jì)數(shù)器計(jì)數(shù)自增,并不斷的與自動(dòng)重裝值進(jìn)行比較,相等時(shí),產(chǎn)生一個(gè)更新中斷,更新事件,CPU響應(yīng)定時(shí)中斷,完成定時(shí)中斷的任務(wù)。
主模式觸發(fā)DAC:將定時(shí)器的更新事件,映射到TRGO的位置,TRGO接到DAC的觸發(fā)引腳上,TRGO會(huì)直接去觸發(fā)DAC,實(shí)現(xiàn)了硬件自動(dòng)化。
通用定時(shí)器
擁有基本定時(shí)器的功能。
通用定時(shí)器擁有向上自增,向下自減,中央對(duì)齊。(基本定時(shí)器,只有向上模式)
內(nèi)外時(shí)鐘源選擇:基本定時(shí)器只能選擇內(nèi)部時(shí)鐘源(系統(tǒng)頻率72MHz),通用定時(shí)器還可以選擇外部時(shí)鐘,外部時(shí)鐘模式2(ETR外部時(shí)鐘),外部時(shí)鐘模式1(ERT外部時(shí)鐘、ITRx其他定時(shí)器-可定時(shí)器級(jí)聯(lián)、TIx捕獲通道)。
外部時(shí)鐘使用時(shí)注意外部時(shí)鐘的引腳,STM32最小系統(tǒng)板的TIM的外部時(shí)鐘接在PA0引腳上。(查看引腳定義表)
高級(jí)定時(shí)器
擁有通用定時(shí)器的功能。
重復(fù)次數(shù)計(jì)數(shù)器:可以實(shí)現(xiàn)每隔幾個(gè)周期才發(fā)生一次更新事件和更新中斷,相當(dāng)于對(duì)更新的輸出信號(hào)作了一次分頻。
定時(shí)中斷的基本結(jié)構(gòu)
在定時(shí)中斷中,ETR的外部中斷1與外部中斷2無(wú)區(qū)別。
中斷輸出控制:定時(shí)器中含有多種中斷(如定時(shí)中斷,輸入捕獲,輸出比較),需要中斷輸出控制進(jìn)行判斷是否需要。
時(shí)序圖介紹
我們通過(guò)時(shí)序圖,來(lái)更深入了解一下定時(shí)器定時(shí)中斷時(shí)的工作原理。
CK_PSC:預(yù)分頻器的輸入時(shí)鐘。
CNT_EN:計(jì)數(shù)器使能。
CK_CNT定時(shí)器時(shí)鐘:CK_PSC/(PSC+1)。
CNT_EN置1后,計(jì)數(shù)器使能,計(jì)數(shù)器開(kāi)始工作,預(yù)分頻器的系數(shù)為1(寫(xiě)0,系數(shù)為1;寫(xiě),系數(shù)為2),CK_CNT前半段頻率=CK_PSC(若內(nèi)部時(shí)鐘作為時(shí)鐘源的話,CK_CNT=72MHZ)。
之后,預(yù)分頻器系數(shù)為2,此時(shí)預(yù)分頻緩沖器保留之前的系數(shù),定時(shí)器時(shí)鐘CK_CNT頻率暫未改變,當(dāng)計(jì)數(shù)器值自增到目標(biāo)值時(shí),產(chǎn)生一個(gè)更新事件,并且在下一個(gè)時(shí)鐘來(lái)臨時(shí)清零計(jì)數(shù)器;當(dāng)產(chǎn)生更新事件后,預(yù)分頻緩沖器的值為1,預(yù)分頻計(jì)數(shù)器按照二分頻的工作模式工作,CK_PSC不變,CK_CNT周期,計(jì)數(shù)周期為原來(lái)的兩倍。
緩存器的作用:值的變化與計(jì)數(shù)周期同步發(fā)生,在控制寄存器的值突然改變時(shí),定時(shí)仍按原來(lái)的方式工作一個(gè)計(jì)數(shù)周期后,再改變,避免更改數(shù)值造成錯(cuò)誤。
可知 更新中斷后,需要再中斷函數(shù)內(nèi)手動(dòng)清零中斷標(biāo)志位。
二,配置定時(shí)器
第一步:配置RCC,打開(kāi)時(shí)鐘。
第二步:選擇定時(shí)器時(shí)鐘單元(不配置,默認(rèn)為內(nèi)部時(shí)鐘)。
第三步:配置時(shí)基單元。
第四步:配置輸出中斷控制,允許更新中斷到NVIC
第五步:配置NVIC,在NVIC中打開(kāi)中斷通道,配置優(yōu)先級(jí)。
最后,使能定時(shí)器,開(kāi)始運(yùn)行。
定時(shí)器庫(kù)函數(shù)(本節(jié))
void TIM_DeInit(TIM_TypeDef* TIMx);//恢復(fù)缺省配置
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//時(shí)基單元初始化;需結(jié)構(gòu)體后,作為參數(shù)傳遞。
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);//時(shí)基單元結(jié)構(gòu)體變量賦默認(rèn)值。
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);//使能計(jì)數(shù)器CNT;對(duì)應(yīng)操作上圖運(yùn)行控制位。
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);//使能中斷輸出信號(hào),ITConfing即使能外設(shè)的中斷輸出;對(duì)應(yīng)操作上圖中斷輸出控制。
//時(shí)鐘源選擇
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);//內(nèi)部時(shí)鐘
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);//選擇ITRx其他定時(shí)器的時(shí)鐘
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,
uint16_t TIM_ICPolarity, uint16_t ICFilter);//選擇TIX捕獲通道的時(shí)鐘。
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);//選擇ETR通過(guò)外部時(shí)鐘模式1,輸入的時(shí)鐘。
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,
uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);//選擇ETR通過(guò)外部時(shí)鐘模式2,輸入的時(shí)鐘
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,
uint16_t ExtTRGFilter);//單獨(dú)用來(lái)配置ETR引腳的極性,濾波器,預(yù)分頻器等參數(shù)。
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);//單獨(dú)修改預(yù)分頻值;參數(shù)1:定時(shí)器x;參數(shù)2:寫(xiě)入的預(yù)分頻器的值;參數(shù)三:預(yù)分頻器的模式(對(duì)應(yīng)上文,預(yù)分頻器的緩存器)
void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode);//修改計(jì)數(shù)器的模式
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);//修改預(yù)裝值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);//獲得計(jì)數(shù)器的值
uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);//獲得預(yù)分頻器的值
//獲取或清除標(biāo)志位(上節(jié)介紹過(guò)EXTI,類(lèi)似)
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
配置過(guò)程
第一步:配置RCC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//開(kāi)啟TIM2的時(shí)鐘,TIM2連接APB1總線
第二步:選擇定時(shí)器時(shí)鐘源
TIM_InternalClockConfig(TIM2);//內(nèi)部時(shí)鐘,不配置,默認(rèn)也是內(nèi)部時(shí)鐘
第三步:時(shí)基單元初始化
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結(jié)構(gòu)體變量
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時(shí)鐘分頻,選擇不分頻,此參數(shù)用于配置濾波器時(shí)鐘,不影響時(shí)基單元功能
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計(jì)數(shù)器模式,選擇向上計(jì)數(shù)
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //計(jì)數(shù)周期,即ARR的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //預(yù)分頻器,即PSC的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復(fù)計(jì)數(shù)器,高級(jí)定時(shí)器才會(huì)用到
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //將結(jié)構(gòu)體變量交給TIM_TimeBaseInit,配置TIM2的時(shí)基單元
定時(shí)器中濾波器工作原理:在固定的頻率f下,進(jìn)行采樣,如果n個(gè)采樣點(diǎn)都輸出相同的電平,即信號(hào)穩(wěn)定;相反,則不穩(wěn)定,這時(shí)保持上次輸出,或低電平。時(shí)鐘的濾波頻率由結(jié)構(gòu)體參數(shù)TIM_ClockDivisio配置的。
第四步:配置中斷輸出控制
TIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除定時(shí)器更新標(biāo)志位
//TIM_TimeBaseInit函數(shù)末尾,手動(dòng)產(chǎn)生了更新事件
//若不清除此標(biāo)志位,則開(kāi)啟中斷后,會(huì)立刻進(jìn)入一次中斷
//如果不介意此問(wèn)題,則不清除此標(biāo)志位也可
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //開(kāi)啟TIM2的更新中斷
配置中斷輸出控制為更新中斷。
第五步:配置NVIC
/*NVIC中斷分組*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置NVIC為分組2
//即搶占優(yōu)先級(jí)范圍:0~3,響應(yīng)優(yōu)先級(jí)范圍:0~3
//此分組配置在整個(gè)工程中僅需調(diào)用一次
//若有多個(gè)中斷,可以把此代碼放在main函數(shù)內(nèi),while循環(huán)之前
//若調(diào)用多次配置分組的代碼,則后執(zhí)行的配置會(huì)覆蓋先執(zhí)行的配置
/*NVIC配置*/
NVIC_InitTypeDef NVIC_InitStructure; //定義結(jié)構(gòu)體變量
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //選擇配置NVIC的TIM2線
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //指定NVIC線路使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //指定NVIC線路的搶占優(yōu)先級(jí)為2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定NVIC線路的響應(yīng)優(yōu)先級(jí)為1
NVIC_Init(&NVIC_InitStructure); //將結(jié)構(gòu)體變量交給NVIC_Init,配置NVIC外設(shè)
最后啟動(dòng)定時(shí)器文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-847059.html
/*TIM使能*/
TIM_Cmd(TIM2, ENABLE); //使能TIM2,定時(shí)器開(kāi)始運(yùn)行
中斷函數(shù)
在啟動(dòng)文件中查找中斷函數(shù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-847059.html
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)//檢驗(yàn)標(biāo)志位
{
//中斷函數(shù)執(zhí)行內(nèi)容
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除標(biāo)志位
}
}
到了這里,關(guān)于STM32——定時(shí)器——定時(shí)中斷的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!