STM32F10x 學習筆記之基本定時器

2021-06-19 22:54:48 字數 2508 閱讀 6248

大容量的stm32f101xx、stm32f103xx系列和互聯型產品中包含了兩個基本定時器,tim6和tim7。這兩個定時器功能非常簡單,基本上和systick 定時器相當。

但是我在使用的時候確是費了一番周折才除錯通過,所以還是應該將這兩個定時器的使用方法好好的寫一寫。

基本定時器tim6和tim7各包含乙個16位自動裝載計數器,由各自的可程式設計預分頻器驅動。簡單的說兩個定時器是從0計數到n(由自動裝載計數器來確定n的具體值),然後復位回0 重新計數。每次復位到0 的時候可以產生對應的中斷訊號,或者產生dma 請求,還可以觸發dac 同步電路。不過這次筆記不討論觸發dac 的問題,等寫到dac 的使用時在講解如何用這兩定時器驅動dac。

基本定時器tim6和tim7掛載在apb1匯流排上,在使用之前需要先使能對應的時鐘訊號。對應的語句如下:

[cpp] view plaincopy

rcc_apb1periphclockcmd(rcc_apb1periph_tim6, enable);   

rcc_apb1periphclockcmd(rcc_apb1periph_tim7, enable);   

apb1 匯流排上的時鐘訊號在進入定時器之後第一件事情是被預分頻器timx_psc分頻。程式中隨時都可以更改timx_psc的值,但是timx_psc是有緩衝的,只有發生了更新事件時新的預分頻值才會生效。

另外有一點必須要特別注意:如果我們想對 ck_psc 時鐘訊號n 分頻的話,timx_psc 中應該寫入 m - 1,而不是 m。

對應的語句如下:

[cpp] view plaincopy

timx->psc = m - 1;  

如果我們希望立刻更新預分頻器也是有辦法的,那就是軟體觸發一次更新事件。tim6和tim7有個事件產生暫存器(timx_egr) 就是起這個作用的。timx_egr 只有最低位有用,稱之為 ug 位,向這一位寫入 1 則產生更新事件,定時器的計數器被歸零。

對應的語句如下:

[cpp] view plaincopy

timx->egr = 0x0001;  

自動重裝載暫存器timx_arr決定了cnt 計數器最高記到多少就會歸零。自動重裝載暫存器也是帶快取的。如果timx_cr1暫存器中的自動重裝載預載入使能位(arpe)為0,則寫入自動重裝載暫存器的值立即起作用。如果arpe = 1,則要等到發生了更新事件後才會起作用。舉例來說,當前自動重裝載暫存器的值為20000,cnt 計數器的值為1000,arpe = 1,這時我們向自動重裝載暫存器寫個 5000,cnt 計數器記到 5000 時並不會歸零,它還要繼續直到記到20000然後歸零,在歸零的同時產生計數器溢位事件,計數器溢位事件可以產生更新事件,之後自動重裝載暫存器的值才真的變為5000了。

這裡出現了兩個事件:計數器溢位事件和更新事件。這兩個實際是不同的。每次當計數器溢位時都會產生計數器溢位事件,但是不一定產生更新事件。

tim6和tim7控制暫存器1(timx_cr1) 有一位udis:禁止更新 (update disable)位。

如果這位被設定為1,則計數器溢位事件不會產生更新事件。不產生更新事件則預分頻器的係數不能被更新,自動重裝載暫存器的值也可能不能更新(arpe = 1)。

只是產生更新事件是沒有用的,我們最終需要的是產生中斷或dma請求。這裡先說中斷的產生。

tim6和tim7 dma/中斷使能暫存器(timx_dier) 有一位為uie。只有這一位為1時才能產生更新中斷。

對應的語句如下:

[cpp] view plaincopy

timx->dier |= 0x0001;  

tim6和tim7狀態暫存器(timx_sr) 中也只有一位是有用的,位於這個暫存器的最低位,稱之為uif位。這一位為1 標誌著產生了更新中斷。什麼時候這一位才能為1呢?簡單的說就是產生更新事件這一位會被置位為1,不過也有特殊情況,我們知道有兩種情況會產生更新事件:計數器溢位事件和 ug=1。如果timx_cr1的urs位被設為了1,則ug=1 產生的更新事件不會將uif位置位1。

一般來說我們都不希望ug=1時產生中斷,所以多數時間我們會設定urs位為1。

對應的語句如下:

[cpp] view plaincopy

timx->cr1 |= 0x0004;  

下面是乙個例子程式,使用tim6,產生乙個5hz的定時中斷。時鐘頻率為72mhz。

[cpp] view plaincopy

void tim6_init(void)  

void tim6_irqhandler(void)  

還可以完全用stm32f10x standard peripherals firmware library 來寫這個程式。下面用tim7 實現類似的功能。

[cpp] view plaincopy

void tim7_init(void)  

void tim7_irqhandler(void)  

}  程式寫完了,這裡說幾點注意事項。

(1)在對timx 進行設定之前一定要開啟apb1匯流排上對應的時鐘,否則所有的設定都不起作用。

(2)一定要設定nvic,因為預設情況下這些外設的中斷都是被禁用的。

STM32F10x系列 中斷

概念問題 中斷與事件有什麼聯絡與區別?stm32之中斷與事件 中斷與事件的區別 簡單概括下。中斷 cpu單執行緒情況下只能處理單一任務,在有零時任務需要處理時,可以暫時放下當前任務,優先處理零時任務,再回過來處理之前的任務。多個中斷可以進行巢狀,比如產生了多個零時任務,那麼就可以按照優先順序處理這多...

STM32F10X入門 流水燈

2019 3 16 2019 3 19 core cm32.c stdin.h中定義了字元型 stm32f10x.h stm32f10x conf.h中定義了引用的外設標頭檔案 庫檔案之間的依賴呼叫關係 pngstm32f10x.h檢視位址對映 比如define gpioa base apb2per...

STM32F10X 位帶操作

在stm32微控制器的學習中,有乙個最大的特點就是你所編寫的stm32的程式操作,基本上都是匯流排的操作,比如gpiob odr 0x0001 或者直接等於1 這樣的操作必須要考慮整個暫存器的資料,但其實如果學過51微控制器的人都知道,我們除了對於匯流排操作外,我們還是經常會對單獨的位進行操作,比如...