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