實驗介紹:本實驗利用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燈的亮滅情況。首先,需...