STM32F103輸入捕獲實驗

2021-10-18 07:39:16 字數 3814 閱讀 2759

實驗介紹:本實驗利用tim5的通道1(io為pao)來捕獲按鍵key_up(按下)輸入的高電平脈寬的時間,並且利用串列埠列印出來。

要得出高電平脈寬的時間,就要設定兩次捕獲,第一次捕獲時,先設定為上公升沿捕獲,捕當獲到了高電平觸發相關計數器開始計數,然後再設定為下降沿捕獲,捕獲到了低電平,即高電平結束的時候停止計數。如果高電平時間過長,超過了計數器的最大計數範圍,導致溢位,這個時候就要設定觸發相關中斷服務函式,計數溢位的次數,再算出總時間。

1.stm32f103

2.key_up按鍵

3.串列埠

4.定時器tim5

1.開啟tim5和gpioa的時鐘

因為tim5的通道1(ch1),它對應的管腳為pa0,io口就是gpioa了。我們知道tim5作為通用定時器是掛載在apb1匯流排下,而pclk是提供給gpio外設的時鐘,它是掛載在apb2匯流排下,於是我們的函式如下。

rcc_apb1periphclockcmd

(rcc_apb1periph_tim5, enable)

;//使能 tim5 時鐘

rcc_apb2periphclockcmd

(rcc_apb2periph_gpioa, enable)

;//使能 gpioa 時鐘

voidtim_timebaseinit

(tim_typedef*timx,tim_timebaseinittypedef* tim_timebaseinitstruct)

;typedef

struct

tim_timebaseinittypedef;

以上是包含結構體指標的函式定義部分,初始化部分如下

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)

;//根據指定的引數初始化 tim5

3.配置輸入捕獲

設定這一步的目的就是前面已經講解的,要開啟計數器在上公升沿的時候開始計數,設定上公升沿捕獲是在ti1(通道 1)配置的,所以就要把ic1 對映到 ti1(通道 1)上面,定義相關函式如下:

void

tim_icinit

(tim_typedef* timx, tim_icinittypedef* tim_icinitstruct);

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捕獲到了上公升沿或者下降沿的訊號就去執行相關指令

更新中斷,顧名思義,就是計數器溢位了,不得不重新計數,就叫做更新,產生更新中斷就會計數一次溢位的次數,使能函式如下

tim_itconfig

( tim5,tim_it_update|tim_it_cc1,enable)

;

5.中斷服務函式

接下來我們就要編寫中斷服務函式了,在此之前,不得不說明一下,中斷函式與一般函式的執行條件是不同的,一般函式一定要人工呼叫,而中斷函式只要設定的中斷條件滿足了,它會自動呼叫!

void

tim5_irqhandler

(void

)else tim5ch1_capture_sta++;}

}if(tim_getitstatus

(tim5, tim_it_cc1)

!= reset)

//捕獲 1 發生捕獲事件

else

//還未開始,第一次捕獲上公升沿}}

tim_clearitpendingbit

(tim5, tim_it_cc1|tim_it_update)

;//清除中斷標誌位

}

這個函式我就口頭說明一下,它可以拆分為兩個部分來看,前面一部分是有關捕獲中斷的,先判斷有沒有捕獲到高電平,捕獲到了高電平再判斷有沒有溢位,一旦溢位,則直接配置暫存器相關位來表示,並重新計數,如果沒有溢位,則繼續計數,直到溢位為止(這裡只討論溢位的情況

後面一部分就是有關更新中斷的了,這裡比較好理解,如果最開始捕獲到乙個下降沿,就說明第一次一定捕獲到上公升沿,標記一次,然後捕獲極性設定為下降沿捕獲,等待下降沿的到來,同理,如果開頭捕獲到乙個上公升沿…

最後,別忘了用tim_clearitpendingbit(tim5, tim_it_cc1|tim_it_update);清除中斷標誌位。

6.當然這裡還有gpio,和串列埠的使能及初始化,這裡不是重點,我就不寫了…

最後我們用tim5_cap_init這個函式來包涵進來。

#include

"sys.h"

#include

"usart.h"

#include

"timer.h"

extern u8 tim5ch1_capture_sta;

//輸入捕獲狀態

extern u16 tim5ch1_capture_val;

//輸入捕獲值

intmain

(void)}

}

開啟串列埠助手,波特率設定為115200,開啟串列埠

按下key_up按鍵之後pc接收端會顯示高電平的時間,但是是不是可以一直按下去呢,當然不是,因為我們設定了tim5ch1_capture_val=0xffff;val暫存器是16位暫存器,這裡已經設定了最大數為0xffff,換算成十進位制數就是4194303,所以我們看到輸入過長時間超過了4194303us就會強制輸出。

stm32f103外部中斷

void extix init void 外部中斷0服務程式 void exti9 5 irqhandler void 這是簡單的外部中斷的配置,pc7作為中斷輸入 上面補充io口的初始化 gpio initstructure.gpio mode gpio mode ipu pc6配置為快充指示 1...

STM32F103啟動檔案

目錄 一 概述 二 彙編指令 2.1 equ 2.2 area 2.3 space 2.4 preserve8 2.5 thumb 2.6 export 2.7 dcd 2.8 proc 2.9 ldr 2.10 blx 2.11 bx 2.12 temport 2.13 b 2.14 if,els...

STM32F103入門 10 按鍵實驗(上)

之前的點亮小燈實驗用到了gpio的輸出模式,但是對於輸入模式沒有用到,這次小r給小夥伴們介紹gpio的其中一種輸入模式 上拉輸入。按鍵出現在很多的應用場景,按鍵處理更是一門學問。因此,小r給小夥伴們介紹gpio的上拉輸入模式並簡單應用於按鍵實驗中,通過判斷按鍵的狀態來控制led燈的亮滅情況。首先,需...