利用STM32的外部中斷和定時器測量頻率

2021-10-12 20:05:51 字數 3141 閱讀 8567

摘要:利用定時器產生pwm波。然後利用32的外部中斷和定時器來測量32輸出的波形 硬體:stm32f103c8t6核心板、示波器、串列埠除錯助手 所用到的的引腳為pa8和pa0。

測量方案:在第一次外部中斷(上公升沿觸發)到之時,開啟定時器,同時計數器清零。然後等待第二次中斷到來,在第二次外部中斷(上公升沿觸發)到之時,獲取計數器的計數值,同時關閉計數器。因為知道了計數器計數乙個數的時間,所以在第二次外部中斷(上公升沿觸發)到之時,獲取計數器的計數值,通過這個值就知道乙個脈衝的時間週期。時間週期的倒數就是外部訊號的頻率。

pwm.c

#include "pwm.h"void tim1_pwm_init(u16 arr,u16 psc)pwm.h

#ifndef __pwm_h#define __pwm_h#include "sys.h"void tim1_pwm_init(u16 arr,u16 psc);#endifmain.c

#include "delay.h"#include "sys.h"#include "pwm.h"int main(void)}定時器1的通道1對應的是pa8引腳,連線示波器可以測出波形

這裡利用pa8輸出的pwm波形讓pa0外部中斷引腳測量。

我們知道在配置定時器時最重要的就是配置定時器的預分頻係數和重裝載值。

定時器的本質就是乙個計數器,計數到我們設定的值後就會溢位,也就是重新從0開始開始計數。設定預分頻係數就是設定計數器的頻率,假設為71,f1的系統時鐘為72m,經過72分頻,給計數器的時鐘頻率就是1m,週期就是1/1m=1us。也是就1us計乙個數。那麼計幾個數呢?這就要看重裝載值arr,這裡我們設定為0xffff,也就是計數65536個數,就是計滿整個暫存器的值。為什麼要分頻係數為72,重裝載值為0xffff?這裡給出詳細的分析過程。

f1的系統時鐘為72m,f1的系統時鐘為72m,如果不分頻的話,提供給定時器的時鐘就直接是72mhz。72mhz是個什麼概念?72mhz它對應的週期就是(1/72000000)秒,也就是計數器從0計數到最大值65535,只需要花費(65535/72000000)秒≈1ms。這句話的意思就是如果你不分頻,計數器最大只能定時1ms。那麼你的定時器每隔1ms就會溢位一次。如果經過72分頻,給計數器的時鐘頻率就是1m,週期就是1/1m=1us,也是就1us計乙個數。換句話就是可以取樣的波形頻率為1m,提高了取樣頻率。另一方面也是容易計算,計乙個數1us,計count個數就是count個us,頻率就是1000 000/count(hz)。

最大取樣間隔是跟定時器的中斷間隔相關的,定時器產生溢位中斷後計數值cnt會自動清0,定時器的中斷間隔由分頻係數prescaler和自動重裝載暫存器period決定,分頻係數前面已經確定,那最大取樣間隔只需要考慮自動重裝載暫存器period的設定,比如頻分析係數72-1,自動重灌暫存器值65535,則中斷間隔=65536/72000000/72=65.536ms,即最大取樣間隔65.536ms,如果65.536ms內沒有檢測到乙個脈衝,則這麼設定間隔是不合理的,必須想辦法犧牲最小的取樣時間1us(擴大分頻係數)或者擴大自動重灌暫存器值(16位,<65535)來增加定時器中斷間隔,也可以編寫自己的應用函式來計算溢位的定時時間。

一般來說我們使用外部中斷是不需要用到定時器的,大家看原子和野火的外部中斷實驗也沒有用到外部中斷。但是我們現在不是利用外部中斷簡單的處理一件事,而是利用外部中斷測量頻率,而測頻率就涉及到時間,而只要涉及到時間,就需要用到定時器了。測量外部訊號的頻率,就是測量pwm波對吧!如果我們測量到乙個週期的時間,那麼不就知道了訊號的頻率了嗎?

測量方案:在第一次外部中斷(上公升沿觸發)到之時,開啟定時器,同時計數器清零。然後等待第二次中斷到來,在第二次外部中斷(上公升沿觸發)到之時,獲取計數器的計數值,關閉計數器。因為我們知道了計數器計數乙個數的時間,所以我們到在第二次外部中斷(上公升沿觸發)到之時,獲取計數器的計數值,通過這個值就知道乙個脈衝的時間週期。時間週期的倒數就是外部訊號的頻率。

具體**如下:

void exti0_irqhandler(void)else if(capturenumber==1)//第2次上公升沿觸發}}int main(void)}當然你可能覺得這只是測量訊號的乙個週期脈衝不夠準確,那麼也可以測量100次脈衝的時間再除以100,就是乙個脈衝的時間,然後再取倒數就可以算出頻率,這種方法也是可以的。具體**如此:

void exti0_irqhandler(void)else if(capturenumber>0&& capturenumber<100)else if(capturenumber==100)//第100次上公升沿觸發}}int main(void)}程式流程圖:

串列埠列印結果:

當然測量訊號頻率的方法我們直接利用tim的輸入捕獲的方法就可以實現。用外部中斷只是另外乙個測量方案,具體用哪一種還要看具體情況。

STM32外部中斷

一 基本概念 arm coetex m3核心共支援256個中斷,其中16個內部中斷,240個外部中斷和可程式設計的256級中斷優先順序的設定。stm32目前支援的中斷共84個 16個內部 68個外部 還有16級可程式設計的中斷優先順序的設定,僅使用中斷優先順序設定8bit中的高4位。stm32可支援...

stm32外部中斷

外部中斷程式配置流程 rcc 時鐘配置 void rcc configuration void 時鐘配置 開啟各路時鐘 rcc apb2periphclockcmd rcc apb2periph usart1 rcc apb2periph gpioa rcc apb2periph afio,enab...

stm32外部中斷

好久沒玩微控制器了,最近閒著沒事想拿出來玩玩,沒想到乙個stm32的外部中斷讓我花費了兩天時間,好的的挫折啊!終於下午除錯成功,下面來說一下我的除錯之路吧!硬體就是兩個按鍵,四個led,led事共陽極接法,按鍵一端接地一端接gpio口,通過按鍵中斷控制led。程式寫好以後發現始終無法進入中斷,開始查...