STM32 定時器詳解
吃了一個猛虧,自己理解花了大半天時間,結(jié)果一看代碼發(fā)現(xiàn)巨簡單
算了,把自己理解的放上來吧
目錄
STM32 定時器詳解
前言
一、定時器種類和區(qū)分
二、時鐘源
三、計數(shù)過程
3.1 計數(shù)器時鐘CK_CNT
3.2 計數(shù)器有關(guān)的三個寄存器
3.3 其他的寄存器
3.4 定時器計算時間
總結(jié)
前言
前面說過看門狗以及簡單的延時功能,實際上STm32還有專門用于定時器的配置。定時器配套的功能有很多,比如定時發(fā)送 USART 數(shù)據(jù)、定時采集 AD數(shù)據(jù)等等。如果把定時器與 GPIO 結(jié)合起來使用的話可以實現(xiàn)非常豐富的功能,可以測量輸入信號的脈沖寬度,可以生產(chǎn)輸出波形。定時器生產(chǎn) PWM 控制電機(jī)狀態(tài)是工業(yè)控制普遍方法(STM32第六章-TIM定時器詳解 - 知乎)
為什么要用計時器? 答:延時過程中,CPU時間被占用,無法進(jìn)行其他任務(wù),導(dǎo)致系統(tǒng)效率降低。延時時間越長,該 缺點便越明顯,因此軟件延時只適用于短暫延時,或簡單項目。
這一塊比較復(fù)雜:參考了很多博客( 【STM32】通用定時器的基本原理(實例:定時器中斷)_stm32定時器中斷設(shè)置中斷變量_Yngz_Miao的博客-CSDN博客),最后整理總結(jié)如下:
一、定時器種類和區(qū)分
高級定時器(TIM1、TIM8);通用定時器(TIM2、TIM3、TIM4、TIM5);基本定時器(TIM6、TIM7)。
?
即:高級定時器具有捕獲/比較通道和互補(bǔ)輸出,通用定時器只有捕獲/比較通道,基本定時器沒有以上兩者。
使用最多的是高級定時器和通用定時器
主要的區(qū)別見下:
?
二、時鐘源
2.1 需要一個時鐘源
定時器要實現(xiàn)計數(shù)必須有個時鐘源,因為他需要一個計時的基礎(chǔ)(很矛盾吧,但是內(nèi)部能夠提供一個最基本的RCC時鐘可以基于此設(shè)計,也可以用外部的)。
基本定時器時鐘只能來自內(nèi)部時鐘,高級控制定時器和通用定時器還可以選擇外部時鐘源或者直接來自其他定時器等待模式。
我們可以通過 RCC 專用時鐘配置寄存器(RCC_DCKCFGR)的 TIMPRE位設(shè)置所有定時器的時鐘頻率,我們一般設(shè)置該位為默認(rèn)值 0,使得表中可選的(通用定時器的時鐘頻率是由APB1的分頻系數(shù)決定,如果APB1的預(yù)分頻系數(shù)是1,則通用定時器的時鐘頻率等于APB1的時鐘頻率(不理解這句話可以看下面的RCC時鐘部分))。
基本定時器只能使用內(nèi)部時鐘,當(dāng) TIM6 和 TIM7 控制寄存器 1(TIMx_CR1)的 CEN 位置 1時,啟動基本定時器,并且預(yù)分頻器的時鐘來源就是 CK_INT(下面還有很多不同的說法)。?
對于高級控制定時器和通用定時器的時鐘源需要找控制器外部時鐘、其他定時器等等模式,較為復(fù)雜,定時器來源:
1.系統(tǒng)RCC內(nèi)部(RCC的CK_INT,這個可以由系統(tǒng)內(nèi)部時鐘IMx_CLK直接提供)
2.系統(tǒng)內(nèi)外部的定時器(TIMX)
其中外部時鐘有關(guān)的時鐘源為
1.外部觸發(fā)輸入(也叫外部引腳輸出TIMx_ETR)
2.內(nèi)部觸發(fā)輸入(ITRx)
3.外部輸入腳(TIx)
?
2.2 最常用的時鐘源(默認(rèn)設(shè)定)
關(guān)于來自系統(tǒng)(RCC)的時鐘這里還需要在仔細(xì)說明一下(也即是 CK_INT來源再說明一下):在RCC(系統(tǒng)時鐘)過程有這樣的流程:
也就是說:由AHB時鐘經(jīng)過APB1預(yù)分頻系數(shù)轉(zhuǎn)至APB1時鐘,再通過某個規(guī)定轉(zhuǎn)至TIMxCLK時鐘(TIMxCLK就是上面說的內(nèi)部時鐘CK_INT)。值得注意的是TIMxCLK時鐘頻率一定是APB1時鐘頻率(圖中說了二分了就又會乘以二)
【APB1(RCCx系統(tǒng)中的時鐘)->CK_CNT時鐘】的過程
CK_PSC最終經(jīng)過PSC預(yù)分頻系數(shù)轉(zhuǎn)至CK_CNT(就是下面這個計數(shù)器)。
原文鏈接:【STM32】通用定時器的基本原理(實例:定時器中斷)_stm32定時器中斷設(shè)置中斷變量_Yngz_Miao的博客-CSDN博客
感謝大佬。
三、計數(shù)過程
3.1 計數(shù)器時鐘CK_CNT
TIMxCLK經(jīng)過PSC預(yù)分頻器之后為CK_INT,作為CNT計數(shù)器的計數(shù)時鐘。PSC可以對定時器時鐘TIMxCLK(也就是CK_PSC)進(jìn)行1~65535之間任何一個數(shù)進(jìn)行分頻,CK_CNT = TIMxCLK / (PSC + 1)。PSC的值設(shè)置于TIMx_PSC寄存器。
?
定時器的本質(zhì)是計數(shù)器,即對一定周期(頻率)的脈沖進(jìn)行計數(shù)。(定時器的本質(zhì)是計數(shù)器,即對一定周期(頻率)的脈沖進(jìn)行計數(shù)。_定時器為什么就是計數(shù)器_TYINY的博客-CSDN博客)
3.2 計數(shù)器有關(guān)的三個寄存器
要知道定時器的本質(zhì)是計數(shù)器和三個寄存器有關(guān)就行了
定時器計數(shù)過程主要涉及三個寄存器( STM32-定時器詳解_stm32定時器_KevinFlyn的博客-CSDN博客)
計數(shù)器寄存器(TIMx_CNT):向上計數(shù)、向下計數(shù)或者中心對齊計數(shù);
預(yù)分頻寄存器(TIMx_PSC):可將時鐘頻率按1到65535之間的任意值進(jìn)行分頻,可在運行時改變其設(shè)置值;
自動裝載寄存器(TIMx_ARR):如果TIMx_CR1寄存器中的ARPE位為0,ARR寄存器的內(nèi)容將直接寫入影子寄存器;如果ARPE為1,ARR寄存器的那日同將在每次的更新時間UEV發(fā)生時,傳送到影子寄存器;如果TIM1_CR1中的UDIS位為0,當(dāng)計數(shù)器產(chǎn)生溢出條件時,產(chǎn)生更新事件。:【STM32】通用定時器的基本原理(實例:定時器中斷)_stm32定時器中斷設(shè)置中斷變量_Yngz_Miao的博客-CSDN博客
3.3 其他的寄存器
當(dāng)然,還有幾個相關(guān)的寄存器需要記住
1.控制寄存器(TIMx_CR1)
作用:對計數(shù)器的計數(shù)方式、使能位等進(jìn)行設(shè)置。
這里有ARPE位:自動重裝載預(yù)裝載允許位。ARPE=0時,TIMx_ARR寄存器沒有緩沖;ARPE=1時,TIMx_ARR寄存器被裝入緩沖器。
2.DMA/中斷使能寄存器(TIMx_DIER)
DMA是一個臨時的寄存器,定時器能夠與DMA進(jìn)行通信
該寄存器能夠?qū)MA/中斷使能進(jìn)行配置。
3.4 定時器計算時間
通用定時器超時時間
超出(溢出)時間計算:Tout=(ARR+1)(PSC+1)/TIMxCLK。其中:Tout的單位為us,TIMxCLK的單位為MHz。
這里需要注意的是:PSC預(yù)分頻系數(shù)需要加1,同時自動重加載值也需要加1。
為什么自動重加載值需要加1,因為從ARR到0之間的數(shù)字是ARR+1個;
為什么預(yù)分頻系數(shù)需要加1,因為為了避免預(yù)分頻系數(shù)不設(shè)置的時候取0的情況,使之從1開始。
這里需要和之前的預(yù)分頻進(jìn)行區(qū)分:由于通用定時器的預(yù)分頻系數(shù)為1~65535之間的任意數(shù)值,為了從1開始,所以當(dāng)預(yù)分頻系數(shù)寄存器為0的時候,代表的預(yù)分頻系數(shù)為1。而之前的那些預(yù)分頻系數(shù)都是固定的幾個值,比如1、4、8、16、32、64等等,而且可能0x000代表1,0x001代表4,0x010代表8等等。也就是說,一邊是隨意的定義(要從1開始),另一邊是宏定義了某些值(只有特定的一些值)。
比如,想要設(shè)置超出時間為500ms,并配置中斷,TIMxCLK按照系統(tǒng)默認(rèn)初始化來(即72MHz),PSC取7199,由此可以計算出ARR為4999。
也就是說,在內(nèi)部時鐘TIMxCLK為72MHz,預(yù)分頻系數(shù)為7199的時候,從4999遞減至0的計數(shù)事件是500ms倒計時。
3.5 代碼
代碼:
概念很多,但是代碼很少:
1.使能定時器時鐘。
RCC_APB1PeriphClockCmd();
2. 初始化定時器,配置ARR,PSC。
TIM_TimeBaseInit();
3.開啟定時器中斷,配置NVIC。
void TIM_ITConfig();
NVIC_Init();
4.使能定時器。
TIM_Cmd();
5.編寫中斷服務(wù)函數(shù)。
TIMx_IRQHandler();
還有獲取狀態(tài)位的函數(shù)(這部分區(qū)別可以查看:STM32學(xué)習(xí)筆記---TIM_GetFlagStatus和TIM_GetITStatus兩個固件庫函數(shù)的區(qū)別_小重拌豆腐的博客-CSDN博客)
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);文章來源:http://www.zghlxwxcb.cn/news/detail-464065.html
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);文章來源地址http://www.zghlxwxcb.cn/news/detail-464065.html
到了這里,關(guān)于STM32 定時器詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!