首先初厚,要理清楚,什么是中斷孙技。
中斷的意思是产禾,比如CPU是主角,他正在工作牵啦,忽然間GPIO口跟他講亚情,這件事需要他來(lái)做。CPU就只能停止自己手頭的工作哈雏,去辦GPIO口分配的事情楞件。辦完了衫生,再去做自己的事情。等到GPIO口又有事了土浸,CPU再停下工作罪针,來(lái)完成GPIO口送來(lái)的事情。
每一次CPU停止工作的時(shí)候都叫做中斷黄伊,GPIO口叫他做的事情叫做中斷源泪酱。
這次外部中斷實(shí)驗(yàn)的目的是:
使開發(fā)板上的三個(gè)按鈕能控制開發(fā)板上燈泡的亮滅。按KEY0鍵还最,LED0亮墓阀,按KEY1鍵,LED1亮拓轻,按WK_UP鍵斯撮,LED0和LED1的狀態(tài)就翻轉(zhuǎn)一次。
就是我們要拿GPIO口做外部中斷輸入扶叉。就是我們按下按鍵的時(shí)候吮成,就會(huì)產(chǎn)生一個(gè)中斷,本來(lái)主函數(shù)里面運(yùn)行得好好的辜梳,一產(chǎn)生中斷粱甫,主函數(shù)就跳到子函數(shù)里面執(zhí)行讓燈亮的程序。然后就一直在中斷函數(shù)里面不出來(lái)了作瞄,所以燈會(huì)一直亮著茶宵。再按下按鍵的時(shí)候,應(yīng)該就是結(jié)束中斷宗挥,回到主函數(shù)里面乌庶。(個(gè)人理解)
這個(gè)跟按鍵輸入實(shí)驗(yàn)的結(jié)果一模一樣。原理有什么不同呢契耿?
按鍵輸入實(shí)驗(yàn)
目的:
通過(guò)按鍵來(lái)控制燈泡的亮滅瞒大。 這個(gè)實(shí)驗(yàn)有頭文件,按鍵源文件搪桂,燈源文件還有main函數(shù)透敌。
頭文件:
用位帶操作,給控制燈泡的GPIO口起了一個(gè)別名踢械,比如LED0酗电,LED1等等。給將要控制燈泡亮滅的按鍵起了一個(gè)別名内列,比如KEYO撵术,KEY1等等。讀取燈泡和按鍵的GPIO口的狀態(tài)话瞧,我們可以用到一個(gè)讀取函數(shù)GPIO_ReadInputDataBit()讀取它嫩与。然后再各個(gè)按鍵按下的時(shí)候取個(gè)別名寝姿。比如:
除了這個(gè),頭文件里面還要有一個(gè)按鍵掃描函數(shù)和一個(gè)配置按鍵參數(shù)的函數(shù)划滋。
接著是KEY的配置函數(shù)方面会油,就是,開啟GPIO口所對(duì)應(yīng)的時(shí)鐘古毛,然后配備GPIO口的模式翻翩,速度以及端口號(hào)。如下圖
這個(gè)函數(shù)用于禁用JTAG稻薇,使用SWD嫂冻,因?yàn)槲覀円玫降囊粋€(gè)GPIO口PA15占用了JTAG的一個(gè)IO,所以要禁止JTAG塞椎,使PA15作為普通的IO輸入桨仿。
除了一個(gè)函數(shù),KEY文件里還有一個(gè)按鍵掃描函數(shù)案狠。如下圖服傍。
這個(gè)意思應(yīng)該是,以KEY0為例骂铁,讀取KEY0時(shí)返回0吹零,則表示按鍵就是按下了,所以返回按鍵按下的標(biāo)志KEY_PRES拉庵。
接下來(lái)就是主函數(shù)灿椅。首先初始化延時(shí)函數(shù),燈函數(shù)钞支,KEY函數(shù)茫蛹,然后進(jìn)入switch循環(huán)。當(dāng)是KEY0按下的標(biāo)志時(shí)烁挟,就是LED0=!LED0婴洼,從而實(shí)現(xiàn)按鍵控制燈的亮滅的功能。
然后撼嗓,外部中斷也是實(shí)現(xiàn)了這個(gè)功能柬采。
STM32的每一個(gè)GPIO口都可以作為中斷輸入口。然后静稻,中斷控制器支持19條中斷/控制請(qǐng)求警没。分別是:
0-15:分別對(duì)應(yīng)響應(yīng)的GPIO口匈辱;
16:對(duì)應(yīng)PVD輸出
17:對(duì)應(yīng)RTC鬧鐘事件
18:對(duì)應(yīng)USB喚醒事件
因?yàn)镾TM32供GPIO口使用的中斷線只有16條振湾,而GPIO口不止16個(gè)。所以亡脸,用GPIOX.0-GPIOX.15(X=ABCDEFG)分別對(duì)應(yīng)中斷線的15-0押搪。下圖就是GPIO口跟中斷線的映射關(guān)系圖树酪。如果我們要哪個(gè)GPIO口對(duì)應(yīng)到中斷線上,我們就需要配備大州。
配置GPIO與中斷線的映射關(guān)系的函數(shù)是
使用方法如下圖
這樣子就把GPIOE和中斷線2聯(lián)系起來(lái)了续语。但是這個(gè)IO口的中斷是通過(guò)什么方式觸發(fā)的,還不知道厦画,因?yàn)檫@個(gè)需要我們?nèi)コ跏蓟袛嗟囊恍﹨?shù)疮茄。初始化中斷的函數(shù)名如下。
例如我們可以這樣配備這個(gè)函數(shù)
這個(gè)初始化函數(shù)有幾個(gè)變量根暑,首先我們要配置他是在哪一條線上力试。(選擇范圍有EXTI_Line0-EXTI_Line15。)接著配置他的模式排嫌,有兩種模式:中斷(EXTI_Mode_Interrupt)和事件(EXTI_Mode_Event)既然是中斷實(shí)驗(yàn)我們肯定選擇中斷模式的畸裳。然后我們?cè)賮?lái)配備他的觸發(fā)方式,有三種模式淳地,一種是上升沿觸發(fā)怖糊,一種是下降沿觸發(fā),或者是任意電平(上升沿和下降沿觸發(fā))颇象。最后就使能中斷伍伤。
關(guān)于上升沿下降沿的說(shuō)法,如下圖
因?yàn)槭峭獠恐袛嗲睬跃鸵O(shè)置中斷優(yōu)先級(jí)嚷缭。因?yàn)檩斎氲耐獠恐袛嗄敲炊啵偟酶嬖V單片機(jī)哪一個(gè)先哪一個(gè)后吧耍贾。不然擠在一起阅爽,誰(shuí)也沒(méi)本事中斷他。設(shè)置中斷優(yōu)先級(jí)的函數(shù)是NVIC_Init()荐开。這個(gè)函數(shù)有幾個(gè)變量付翁,我們可以設(shè)置如下圖。
配置完中斷優(yōu)先級(jí)后晃听,指定了條中斷線先之后百侧,就該確定這中斷線是要走去哪里的了。也就是我們應(yīng)該編寫中斷服務(wù)函數(shù)能扒。中斷服務(wù)函數(shù)名在MDK里面已經(jīng)有事先定義了佣渴。一共有六個(gè)。
分別對(duì)應(yīng)中斷線0,1,2,3,4,5-9,10-15初斑。
但在編寫中斷服務(wù)函數(shù)之前辛润,我們還應(yīng)該確定一下,中斷線上是否產(chǎn)生了中斷见秤。(標(biāo)志是否置位)判斷中斷線上的狀態(tài)的函數(shù)是
這個(gè)函數(shù)中還要用到一個(gè)中斷標(biāo)志位清除函數(shù)砂竖。如下
另外真椿,有兩個(gè)函數(shù):EXTI_GetFlagStatus()和EXTI_ClearStatus()兩個(gè)函數(shù)跟上面兩個(gè)函數(shù)的作用是差不多的。但是EXTI_GetFlagStatus()要先判斷這個(gè)中斷是否已經(jīng)使能乎澄,再去判斷他的中斷標(biāo)志位是否置位突硝。而EXTI_ClearStatus()是直接判斷他的狀態(tài)標(biāo)志位。
使能中斷=允許產(chǎn)生中斷置济。
這兩個(gè)中斷的使用方法如下圖:
所以解恰,外部中斷總共有五步。
1.將所有的GPIO口都配置為輸入
2.開啟GPIO口復(fù)用時(shí)鐘浙于,然后將GPIO口和中斷線的映射關(guān)系安排好
3.初始化外部中斷修噪,設(shè)置觸發(fā)條件
4.設(shè)置中斷分組(NVIC),中斷事件那么多路媚,總得先排好隊(duì)才好提高打斷效率黄琼。
5.編寫中斷服務(wù)函數(shù)。
這個(gè)和按鍵輸入實(shí)驗(yàn)不一樣的一點(diǎn)就是整慎,按鍵輸入實(shí)驗(yàn)是用按鍵掃描函數(shù)檢測(cè)按鍵的狀態(tài)(是否按下)脏款,這個(gè)是靠中斷實(shí)驗(yàn)檢測(cè)按鍵是否已經(jīng)按下。
中斷的代碼是:首先是各種頭文件裤园,寫了一大堆撤师,比如,exti.h拧揽,delay.h等等剃盾。然后,就是開始EXTIX_Init()的編寫了淤袜。
說(shuō)簡(jiǎn)單其實(shí)也特別簡(jiǎn)單因?yàn)槔锩婢椭挥袔讉€(gè)個(gè)小函數(shù)痒谴,第一個(gè)是配置中端線的函數(shù)EXTI_Init(),分別初始化出三條中斷通道來(lái)铡羡,但是總得先知道中斷通道是哪個(gè)吧积蔚。所以就用到了一個(gè)函數(shù):GPIO_EXTILineConfig()來(lái)給GPIO口牽中斷線。
因?yàn)槿齻€(gè)按鍵分別對(duì)應(yīng)三個(gè)通道烦周,分別是
EXTI0_IRQHandler()和EXTI9_5IRQHandler()和EXTI15_10IRQHandler()
然后分別給這三個(gè)通道設(shè)置中斷優(yōu)先級(jí)尽爆,所以,控制器NVIC读慎。將每個(gè)通道分組后漱贱,這個(gè)大函數(shù)就成立了。
然后另辟函數(shù)夭委,名字叫做中斷服務(wù)函數(shù)幅狮,給每個(gè)中斷通道都分一個(gè)。然后是這樣的,先延時(shí)10ms彪笼,防抖钻注。
單片機(jī):亮燈蚂且,請(qǐng)給我10ms的時(shí)間配猫。
然后就判斷了,如果按下了哪個(gè)鍵杏死,就哪個(gè)燈亮泵肄,到最后,還一定要清除中斷標(biāo)志位淑翼。不然的話腐巢,這個(gè),按鍵就控制不了等玄括,他就要屹立不倒冯丙,常亮不衰了。
具體代碼如下圖
然后再調(diào)用一個(gè)主函數(shù)遭京。就可以了胃惜。