一、背景有個(gè)需求,IO口檢測(cè)上升沿,然后做相應(yīng)的動(dòng)作。在此記錄STM32F103的外部中斷結(jié)構(gòu)及配置方法,以備下次快速上手使用。有許多不太明白,又是老司機(jī)(:-D)幫忙,真的是站在別人的肩膀上會(huì)讓你看的更遠(yuǎn),走的更快,感謝老司機(jī)。二、正文STM32f103有68個(gè)可屏蔽中斷。(但是,真正能用的其實(shí)遠(yuǎn)沒有這么多,原因下面會(huì)詳述。)有16個(gè)可編程的優(yōu)先等級(jí),優(yōu)先等級(jí)的概念可詳見我的另外一篇博客《STM32之NVIC(中斷向量、優(yōu)先級(jí))簡(jiǎn)述》,鏈接:"http://www.cnblogs.com/ChYQ/p/5859974.html",接著看中斷向量表, 如下圖:
該中斷向量表從高到低按照默認(rèn)的中斷優(yōu)先級(jí)排序?qū)⑺锌捎玫闹袛嘁员淼男问搅谐鰜?。仔?xì)來看每一列代表的意義:"優(yōu)先級(jí)":無需多言,默認(rèn)的中斷優(yōu)先級(jí)次序。"優(yōu)先級(jí)類型":即表明,這個(gè)對(duì)應(yīng)的默認(rèn)優(yōu)先級(jí)是否可被配置更改,以使其優(yōu)先級(jí)升高或者降低。"名稱":外部中斷名稱簡(jiǎn)寫"說明":通過這個(gè)我們就可以清楚知道前一列的"名稱"代表的是哪個(gè)具體的外設(shè)中斷。"地址":這個(gè)地址即當(dāng)對(duì)應(yīng)的外部中斷來時(shí),若是使能了該外部中斷,則MCU會(huì)將PC指針跳轉(zhuǎn)到該地址,編譯器一般會(huì)在該地址內(nèi)保存對(duì)應(yīng)的中斷處理函數(shù)指針,進(jìn)而可進(jìn)入到相應(yīng)的中斷處理函數(shù)做相應(yīng)的處理。然后說說外部中斷事件(EXTI),外部中斷事件由20個(gè)(互聯(lián)型)/19個(gè)產(chǎn)生事件/中斷的邊沿檢測(cè)器組成,白話說,即GPIO口可檢測(cè)到對(duì)應(yīng)IO口的上升沿/下降沿/雙邊沿事件,進(jìn)而產(chǎn)生相應(yīng)中斷。 接著看外部中斷/時(shí)間框圖,如下圖:
從最右來看,輸入線連接至GPIO口,檢測(cè)外部引腳的電平信號(hào),上升沿/下降沿觸發(fā)器與軟件中斷事件觸發(fā)器,經(jīng)過"或"器件傳入下一級(jí),意味著,這兩類信號(hào)可獨(dú)立引起中斷/事件。經(jīng)過"或"后,信號(hào)出現(xiàn)了分支,信號(hào)一路進(jìn)入請(qǐng)求掛起寄存器,若是中斷屏蔽寄存器設(shè)置為允許該信號(hào),則一起"與"使能對(duì)應(yīng)的中斷。另一路則是同事件屏蔽寄存器信號(hào)相"與",通過則產(chǎn)生對(duì)應(yīng)的事件。說到這,中斷和事件又有什么不同呢?中斷既是正常理解的中斷,中斷信號(hào)通過后,會(huì)讓MCU的PC值跳轉(zhuǎn)到相應(yīng)的中斷入口,找到對(duì)應(yīng)的中斷處理函數(shù),然后進(jìn)行中斷處理。事件則用來向其他外設(shè)模塊發(fā)送脈沖事件,通知外設(shè)去做相應(yīng)的事情,就以ADC接收到脈沖事件后自動(dòng) 開始ADC轉(zhuǎn)換為例進(jìn)行說明。在ADC中,初始化ADC的結(jié)構(gòu)體如下:typedefstruct{uint32_tADC_Mode;FunctionalStateADC_ScanConvMode;FunctionalStateADC_ContinuousConvMode;uint32_tADC_ExternalTrigConv;uint32_tADC_DataAlign;uint8_tADC_NbrOfChannel;}ADC_InitTypeDef;選項(xiàng)"ADC_ExternalTrigConv",即是設(shè)置ADC的觸發(fā)啟動(dòng)方式,可配置為軟件觸發(fā)啟動(dòng),當(dāng)該值配置為"ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO"的時(shí)候,則ADC會(huì)在EXT產(chǎn)生脈沖事件的同時(shí),開始自動(dòng)觸發(fā)ADC轉(zhuǎn)換,與軟件觸發(fā)啟動(dòng)不同的是,這種方式是硬件自動(dòng)完成,不需要軟件參與。當(dāng)然,不限定只能為EXT,還可以是定時(shí)器等等。最后說說上文提及的,為什么明明有68個(gè)可屏蔽中斷,可實(shí)際卻遠(yuǎn)沒有這么多。上圖提及,GPIO口通過連接到外部中斷/事件線上來完成相應(yīng)的中斷請(qǐng)求,然后看看外部中斷通用I/O口映像,如下圖:外部中斷/事件線只有16個(gè),IO口卻有A~G(7)組,每組有16個(gè)引腳,從上圖可看出,實(shí)際上一次性可用的外部中斷/事件也只能有16個(gè),并不是IO口有多少,就能有多少個(gè)外部中斷/事件?! ∑┤缯f若是第一組PA0用了第一個(gè)中斷/事件線,那么P(x)0就不能再被用作外部中斷輸入口了。(x 為B~G)。外部中斷結(jié)構(gòu)大致就介紹到此。接下來說說,結(jié)合庫(kù)函數(shù),如何讓外部中斷配置成功并工作。一一般步驟為:-->初始化對(duì)應(yīng)IO口為輸入;-->使能對(duì)應(yīng)IO口時(shí)鐘,并設(shè)定IO口與外部中斷/事件線的聯(lián)系; 注意:由于此處用了外部中斷,所以對(duì)應(yīng)的復(fù)用時(shí)鐘要打開! RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//使能GPIO時(shí)鐘復(fù)用 //設(shè)定GPIO口與中斷/事件線聯(lián)系庫(kù)函數(shù)voidGPIO_EXTILineConfig(uint8_tGPIO_PortSource,uint8_tGPIO_PinSource);"GPIO_PortSource":選擇對(duì)應(yīng)的GPIO口。"GPIO_PinSource":選擇對(duì)應(yīng)的外部中斷/事件線。-->初始化外部中斷/事件線,并配置觸發(fā)模式(上邊沿/下邊沿/雙邊沿);voidEXTI_Init(EXTI_InitTypeDef*EXTI_InitStruct)結(jié)構(gòu)體"EXTI_InitStruct"如下:typedefstruct{//外部中斷/事件線是否被使能//"EXTI_Line0"->"EXTI_Line15"uint32_tEXTI_Line;//中斷模式/事件模式EXTIMode_TypeDefEXTI_Mode;//觸發(fā)模式(上邊沿/下邊沿/雙邊沿)EXTITrigger_TypeDefEXTI_Trigger;//"Enable"或"Disable"FunctionalStateEXTI_LineCmd;}EXTI_InitTypeDef;-->設(shè)置NVIC,并使能中斷;詳見NVIC博客,不再詳述-->寫中斷處理函數(shù)。STM32F103外部中斷函數(shù)共有6個(gè):EXTI0_IRQHandlerEXTI1_IRQHandlerEXTI2_IRQHandlerEXTI3_IRQHandlerEXTI4_IRQHandlerEXTI9_5_IRQHandlerEXTI15_10_IRQHandler外部中斷"0"->"4"有獨(dú)立的中斷處理函數(shù);外部中斷"5"->"9"共用中斷函數(shù)"EXTI9_5_IRQHandler";外部中斷"10"->"15"共用中斷函數(shù)"EXTI15_10_IRQHandler";中斷函數(shù)示例如下:voidEXTI9_5_IRQHandler(void){//獲取中斷狀態(tài)if(EXTI_GetITStatus(EXTI_IMR_MR8)!=RESET){//清除掛起位EXTI_ClearITPendingBit(EXTI_IMR_MR8);}}三、參考鏈接STM32externalinterrupthttp://www.programering.com/a/MDM4kzMwATg.html STM32外部中斷學(xué)習(xí)筆記 http://blog.csdn.net/zzwdkxx/article/details/9036679至此,記錄完畢。