一、背景
有個需求,IO口檢測上升沿,然后做相應的動作。在此記錄STM32F103的外部中斷結構及配置方法,
以備下次快速上手使用。
有許多不太明白,又是老司機(:-D)幫忙,真的是站在別人的肩膀上會讓你看的更遠,走的更快,
感謝老司機。
二、正文
STM32f103有68個可屏蔽中斷。(但是,真正能用的其實遠沒有這么多,原因下面會詳述。)
有16個可編程的優先等級,優先等級的概念可詳見我的另外一篇博客《STM32 之 NVIC(中斷向量、
優先級)簡述》,鏈接:"http://www.cnblogs.com/ChYQ/p/5859974.html",接着看中斷向量表,
如下圖:

該中斷向量表從高到低按照默認的中斷優先級排序將所有可用的中斷以表的形式列出來。仔細來看
每一列代表的意義:
"優先級":無需多言,默認的中斷優先級次序。
"優先級類型":即表明,這個對應的默認優先級是否可被配置更改,以使其優先級升高或者降低。
"名稱":外部中斷名稱簡寫
"說明":通過這個我們就可以清楚知道前一列的"名稱"代表的是哪個具體的外設中斷。
"地址":這個地址即當對應的外部中斷來時,若是使能了該外部中斷,則MCU會將PC指針跳轉到該
地址,編譯器一般會在該地址內保存對應的中斷處理函數指針,進而可進入到相應的中斷
處理函數做相應的處理。
然后說說外部中斷事件(EXTI),外部中斷事件由20個(互聯型)/19個產生事件/中斷的邊沿檢測器組
成,白話說,即GPIO口可檢測到對應IO口的上升沿/下降沿/雙邊沿事件,進而產生相應中斷。
接着看外部中斷/時間框圖,如下圖:

從最右來看,輸入線連接至GPIO口,檢測外部引腳的電平信號,上升沿/下降沿觸發器與軟件中斷
事件觸發器,經過"或"器件傳入下一級,意味着,這兩類信號可獨立引起中斷/事件。經過"或"后,信
號出現了分支,信號一路進入請求掛起寄存器,若是中斷屏蔽寄存器設置為允許該信號,則一起"與"使
能對應的中斷。另一路則是同事件屏蔽寄存器信號相"與",通過則產生對應的事件。
說到這,中斷和事件又有什么不同呢?
中斷既是正常理解的中斷,中斷信號通過后,會讓MCU的PC值跳轉到相應的中斷入口,找到對應的
中斷處理函數,然后進行中斷處理。
事件則用來向其他外設模塊發送脈沖事件,通知外設去做相應的事情,就以ADC接收到脈沖事件后自動
開始ADC轉換為例進行說明。
在ADC中,初始化ADC的結構體如下:
typedef struct
{
uint32_t ADC_Mode;
FunctionalState ADC_ScanConvMode;
FunctionalState ADC_ContinuousConvMode;
uint32_t ADC_ExternalTrigConv;
uint32_t ADC_DataAlign;
uint8_t ADC_NbrOfChannel;
}ADC_InitTypeDef;
選項"ADC_ExternalTrigConv",即是設置ADC的觸發啟動方式,可配置為軟件觸發啟動,當該值配置為
"ADC_ExternalTrigConv_Ext_IT11_TIM8_TRGO"的時候,則ADC會在EXT產生脈沖事件的同時,開始自動
觸發ADC轉換,與軟件觸發啟動不同的是,這種方式是硬件自動完成,不需要軟件參與。當然,不限定
只能為EXT,還可以是定時器等等。
最后說說上文提及的,為什么明明有68個可屏蔽中斷,可實際卻遠沒有這么多。
上圖提及,GPIO口通過連接到外部中斷/事件線上來完成相應的中斷請求,然后看看外部中斷通用
I/O口映像,如下圖:

外部中斷/事件線只有16個,IO口卻有A~G(7)組,每組有16個引腳,從上圖可看出,實際上一次性
可用的外部中斷/事件也只能有16個,並不是IO口有多少,就能有多少個外部中斷/事件。
譬如說若是第一組PA0用了第一個中斷/事件線,那么P(x)0就不能再被用作外部中斷輸入口了。(x
為B~G)。
外部中斷結構大致就介紹到此。接下來說說,結合庫函數,如何讓外部中斷配置成功並工作。一
一般步驟為:
--> 初始化對應IO口為輸入;
--> 使能對應IO口時鍾,並設定IO口與外部中斷/事件線的聯系;
注意:由於此處用了外部中斷,所以對應的復用時鍾要打開!
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 使能GPIO時鍾復用
// 設定GPIO口與中斷/事件線聯系庫函數
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
"GPIO_PortSource":選擇對應的GPIO口。
"GPIO_PinSource" :選擇對應的外部中斷/事件線。
--> 初始化外部中斷/事件線,並配置觸發模式(上邊沿/下邊沿/雙邊沿);
void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)
結構體"EXTI_InitStruct"如下:
typedef struct
{
// 外部中斷/事件線是否被使能
// "EXTI_Line0"->"EXTI_Line15"
uint32_t EXTI_Line;
// 中斷模式/事件模式
EXTIMode_TypeDef EXTI_Mode;
// 觸發模式(上邊沿/下邊沿/雙邊沿)
EXTITrigger_TypeDef EXTI_Trigger;
// "Enable"或"Disable"
FunctionalState EXTI_LineCmd;
}EXTI_InitTypeDef;
--> 設置NVIC,並使能中斷;
詳見NVIC博客,不再詳述
--> 寫中斷處理函數。
STM32F103外部中斷函數共有6個:
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler
外部中斷"0"->"4"有獨立的中斷處理函數;
外部中斷"5"->"9"共用中斷函數"EXTI9_5_IRQHandler";
外部中斷"10"->"15"共用中斷函數"EXTI15_10_IRQHandler";
中斷函數示例如下:
void EXTI9_5_IRQHandler(void)
{
// 獲取中斷狀態
if(EXTI_GetITStatus(EXTI_IMR_MR8) != RESET)
{
// 清除掛起位
EXTI_ClearITPendingBit(EXTI_IMR_MR8);
}
}
三、參考鏈接
STM32 external interrupt
http://www.programering.com/a/MDM4kzMwATg.html
STM32 外部中斷學習筆記
http://blog.csdn.net/zzwdkxx/article/details/9036679
至此,記錄完畢。
記錄時間:2016-12-2
記錄地點:深圳WZ