STM32(9) 通用定時器作為輸入捕捉

2022-05-17 20:55:55 字數 3848 閱讀 9673

通用定時器作為輸入捕獲的使用。我們將用 tim5 的通道 1 (pa0)來做輸入捕獲,捕獲 pa0 上高電平的脈寬(用 wk_up 按鍵輸入高電平),通過串列埠列印高電平脈寬時間

輸入捕獲模式可以用來測量脈衝寬度或者測量頻率。 stm32 的定時器,除了 tim6 和 tim7,其他定時器都有輸入捕獲功能。stm32 的輸入捕獲,簡單的說就是通過檢測 timx_chx 上的邊沿訊號,在邊沿訊號發生跳變(比如上公升沿/下降沿)的時候,將當前定時器的值(timx_cnt)存放到對應的通道的捕獲/比較暫存器(timx_ccrx)裡面,完成一次捕獲。同時還可以配置捕獲時是否觸發中斷/dma 等。

我們用到 tim5_ch1 來捕獲高電平脈寬,也就是要先設定輸入捕獲為上公升沿檢測,記錄發生上公升沿的時候 tim5_cnt 的值。然後配置捕獲訊號為下降沿捕獲,當下降沿到來時,發生捕獲,並記錄此時的 tim5_cnt 值。這樣,前後兩次 tim5_cnt 之差,就是高電平的脈寬,同時 tim5 的計數頻率我們是知道的,從而可以計算出高電平脈寬的準確時間。

1.開啟 tim5 時鐘和 gpioa 時鐘,配置 p a0 為下拉輸入

要使用 tim5,我們必須先開啟 tim5 的時鐘。這裡我們還要配置 p a0 為下拉輸入,因為我們要捕獲 tim5_ch1 上面的高電平脈寬,而 tim5_ch1 是連線在 pa0 上面的。

rcc_apb1periphclockcmd(rcc_apb1periph_tim5, enable);    //使能 tim5 時鐘

rcc_apb2periphclockcmd(rcc_apb2periph_gpioa, enable); //使能 gpioa 時鐘

2.初始化 tim5,設定 tim5 的 arr 和 psc

在開啟了 tim5 的時鐘之後,我們要設定 arr 和 psc 兩個暫存器的值來設定輸入捕獲的自動重裝載值和計數頻率。 這在庫函式中是通過tim_timebaseinit 函式實現的

tim_timebaseinittypedef tim_timebasestructure;

tim_timebasestructure.tim_period = arr; //設定計數器自動重灌值

tim_timebasestructure.tim_prescaler =psc; //設定預分頻值

tim_timebasestructure.tim_clockdivision = tim_ckd_div1; // tdts = tck_tim

tim_timebasestructure.tim_countermode = tim_countermode_up; //tim 向上計數模式

tim_timebaseinit(tim5, &tim_timebasestructure);

3.設定 tim5 的輸入比較引數,開啟輸入捕獲  

輸入比較引數的設定包括對映關係,濾波,分頻以及捕獲方式等。這裡我們需要設定通道 1為輸入模式,且 ic1 對映到 ti1(通道 1)上面,並且不使用濾波(提高響應速度)器,上公升沿捕獲。庫函式是通過tim_icinit 函式來初始化輸入比較引數的:

void tim_icinit(tim_typedef* timx, tim_icinittypedef* tim_icinitstruct);

同樣,我們來看看引數設定結構體 tim_icinittypedef 的定義:

typedef struct

tim_icinittypedef;

配置**是:

tim_icinittypedef tim5_icinitstructure; 

tim5_icinitstructure.tim_channel = tim_channel_1; //選擇輸入端 ic1 對映到 ti1 上

tim5_icinitstructure.tim_icpolarity = tim_icpolarity_rising; //上公升沿捕獲

tim5_icinitstructure.tim_icselection = tim_icselection_directti; //對映到 ti1 上

tim5_icinitstructure.tim_icprescaler = tim_icpsc_div1; //配置輸入分頻,不分頻

tim5_icinitstructure.tim_icfilter = 0x00;//ic1f=0000 配置輸入濾波器 不濾波

tim_icinit(tim5, &tim5_icinitstructure);

4.使能捕獲和更新中斷(設定 tim5 的 dier 暫存器)  

因為我們要捕獲的是高電平訊號的脈寬,所以,第一次捕獲是上公升沿,第二次捕獲時下降沿,必須在捕獲上公升沿之後,設定捕獲邊沿為下降沿,同時,如果脈寬比較長,那麼定時器就會溢位,對溢位必須做處理,否則結果就不准了。這兩件事,我們都在中斷裡面做,所以必須開啟捕獲中斷和更新中斷。 

這裡我們使用定時器的開中斷函式 tim_itconfig 即可使能捕獲和更新中斷:

tim_itconfig( tim5,tim_it_update|tim_it_cc1,enable);//允許更新中斷和捕獲中斷

5.設定中斷分組,編寫中斷服務函式  

設定中斷分組主要是通過函式 nvic_init()來完成。分組完成後,我們還需要在中斷函式裡面完成資料處理和捕獲設定等關鍵操作,從而實現高電平脈寬統計。在中斷服務函式裡面,跟以前的外部中斷和定時器中斷實驗中一樣,我們在中斷開始的時候要進行中斷型別判斷,在中斷結束的時候要清除中斷標誌位。使用到的函式分別為 tim_getitstatus()函式和 tim_clearitpendingbit()函式。

if (tim_getitstatus(tim5, tim_it_update) != reset){}//判斷是否為更新中斷

if (tim_getitstatus(tim5, tim_it_cc1) != reset){} //判斷是否發生捕獲事件

tim_clearitpendingbit(tim5, tim_it_cc1|tim_it_update);//清除中斷和捕獲標誌位

6.使能定時器(設定 tim5 的 cr1 暫存器)  

最後,必須開啟定時器的計數器開關,  啟動 tim5 的計數器,開始輸入捕獲。

tim_cmd(tim5,enable );    //使能定時器 5

例程:

#include "timer.h"

#include "led.h"

#include "usart.h"

/** * 定時器5通道1輸入捕獲配置

*/ void tim5_cap_init(u16 arr,u16 psc)

u8 tim5ch1_capture_sta=0; //輸入捕獲狀態

u16 tim5ch1_capture_val; //輸入捕獲值

/** * 定時器5中斷服務程式

*/void tim5_irqhandler(void)

else tim5ch1_capture_sta++;}}

if(tim_getitstatus(tim5,tim_it_cc1) !=reset)

else}}

tim_clearitpendingbit(tim5,tim_it_cc1|tim_it_update); /*清除中斷標誌位*/

}

extern u8 tim5ch1_capture_sta;        //輸入捕獲狀態                         

extern u16 tim5ch1_capture_val; //輸入捕獲值

int main(void)

}}

**:

stm32通用定時器

stm32的定時器是個強大的模組,定時器使用的頻率也是很高的,定時器可以做一些基本的定時,還可以做pwm輸出或者輸入捕獲功能。時鐘源問題 名為timx的有八個,其中tim1和tim8掛在apb2匯流排上,而tim2 tim7則掛在 apb1匯流排上。其中tim1 tim8稱為高階控制定時器 adva...

STM32通用定時器配置

stm32通用定時器配置 一 stm32 通用定時器原理 stm32 系列的cpu 有多達8 個定時器,其中tim1 和tim8 是能夠產生三對pwm 互補輸出的高階定時器,常用於三相電機的驅動,它們的時鐘由apb2 的輸出產生。其它6 個為普通定時器,時鐘由apb1 的輸出產生。下圖是stm32參...

STM32 通用定時器基本定時功能

1.stm32的timer簡介 stm32中一共有11個定時器,其中2個高階控制定時器,4個普通定時器和2個基本定時器,以及2個看門狗定時器和1個系統嘀嗒定時器。其中系統嘀嗒定時器是前文中所描述的systick,看門狗定時器以後再詳細研究。今天主要是研究剩下的8個定時器。定時器計數器解析度 計數器型...