STM32 外部中斷詳解(原理+配置代碼)

本文介紹了STM32基於標準外設庫的外部中斷配置,以及基於參考手冊如何更加寄存器配置外部中斷

前言

打算寫一下中斷,又忍不住想說一下中斷的概念,去書上翻一翻,或者自己在搜索引擎上搜一下,都可以找到一大堆,包括本文寫的這個外部中斷也不例外。如果要寫光是中斷就可以單獨寫一篇了,所以本文直入主題,對於STM32的外部中斷進行詳細的剖析。

STM32的外部中斷

下圖來自《STM32參考手冊》,從整個架構圖可以知道,外部中斷的功能可以配置六個寄存器;

  • 中斷屏蔽寄存器(EXTI_IMR)
  • 事件屏蔽寄存器(EXTI_EMR)
  • 上升沿觸發選擇寄存器(EXTI_RTSR)
  • 下降沿觸發選擇寄存器(EXTI_FTSR)
  • 軟件中斷事件寄存器(EXTI_SWIER)
  • 掛起寄存器(EXTI_PR)
    在這裏插入圖片描述
    EXTI支持配置20箇中斷和事件屏蔽位;
  • GPIO端口以下圖的方式連接到16個外部中斷/事件線上;EXTI_Line0EXTI_Line15
  • EXTI_Line16 連接到PVD輸出 ;
  • EXTI_Line17連接到RTC鬧鐘事件;
  • EXTI_Line18連接到USB喚醒事件;
  • EXTI_Line19連接到以太網喚醒事件(只適用於互聯型產品);

GPIO的映射關係圖如下所示;
在這裏插入圖片描述

中斷服務函數的映射關係

GPIO IRQn IRQHandler
GPIO_Pin0 EXTI0_IRQn EXTI0_IRQHandler
GPIO_Pin1 EXTI1_IRQn EXTI1_IRQHandler
GPIO_Pin2 EXTI2_IRQn EXTI2_IRQHandler
GPIO_Pin3 EXTI3_IRQn EXTI3_IRQHandler
GPIO_Pin4 EXTI4_IRQn EXTI4_IRQHandler
GPIO_Pin5 — GPIO_Pin9 EXTI9_5_IRQn EXTI9_5_IRQHandler
GPIO_Pin10 — GPIO_Pin15 EXTI15_10_IRQn EXTI15_10_IRQHandler

外部中斷的配置

宏定義,抽象一下接口,方便後面修改;

#define Z_GPIO_PIN    GPIO_Pin_5
#define Z_GPIO_PORT   GPIOE
#define Z_PortSource  GPIO_PortSourceGPIOE
#define Z_PinSource   GPIO_PinSource5
#define Z_Line        EXTI_Line5
#define Z_IRQ         EXTI9_5_IRQn

GPIO的配置;這裏GPIO的輸入模式可以配置爲浮空輸入(GPIO_Mode_IN_FLOATING),上拉輸入(GPIO_Mode_IPU)或者下拉輸入(GPIO_Mode_IPD),具體如下圖所示;
在這裏插入圖片描述GPIO的配置代碼如下;

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Z_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(Z_GPIO_PORT, &GPIO_InitStructure);

不要忘記外設總線時鐘的配置;

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
 		RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF |
    	RCC_APB2Periph_GPIOG, ENABLE);

EXTI的配置,EXTI_Trigger這裏支持三種模式;

  • EXTI_Trigger_Rising 上升沿觸發;
  • EXTI_Trigger_Falling 下降沿觸發;
  • EXTI_Trigger_Rising_Falling 上升沿和下降沿都可以觸發;
GPIO_EXTILineConfig(Z_PortSource, Z_PinSource);

EXTI_InitStructure.EXTI_Line = Z_Line; 
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; 	//下降沿
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);

NVIC的配置

 NVIC_InitStructure.NVIC_IRQChannel = Z_IRQ;
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);

中斷服務函數

void EXTI9_5_IRQHandler(void)
{
     //中斷服務函數
}

以上就完成了檢測下降沿信號的GPIOE5的外部中斷;
也參考官方DEMO
STM32F10x_StdPeriph_Lib_V3.5.0\Project\STM32F10x_StdPeriph_Examples\EXTI\EXTI_Config

寄存器的操作

以下摘自《STM32參考手冊》
產生產生中斷的步驟,必須先配置好並使能中斷線。根據需要的邊沿檢測設置2個觸發寄存器,同時在**中斷屏蔽寄存器(EXTI_IMR)的相應位寫1允許中斷請求。當外部中斷線上發生了期待的邊沿時,將產生一箇中斷請求,對應的掛起位也隨之被置1。在掛起寄存器(EXTI_PR)的對應位寫1,將清除該中斷請求。
產生事件的步驟:必須先配置好並使能事件線。根據需要的邊沿檢測通過設置2個觸發寄存器,同時在
中斷屏蔽寄存器(EXTI_IMR)**的相應位寫1允許事件請求。當事件線上發生了需要的邊沿時,將產生一個事件請求脈衝,對應的掛起位不被置1。通過在軟件中斷/事件寄存器寫1,也可以通過軟件產生中斷/事件請求。

  • 中斷屏蔽寄存器(EXTI_IMR)
  • 事件屏蔽寄存器(EXTI_EMR)
  • 上升沿觸發選擇寄存器(EXTI_RTSR)
  • 下降沿觸發選擇寄存器(EXTI_FTSR)
  • 軟件中斷事件寄存器(EXTI_SWIER)
  • 掛起寄存器(EXTI_PR)

IMR如下圖所示,其他幾個類似;
在這裏插入圖片描述

硬件中斷選擇

通過下面的過程來配置20個線路做爲中斷源:

  • 配置20箇中斷線的屏蔽位(EXTI_IMR)
  • 配置所選中斷線的觸發選擇位(EXTI_RTSR和EXTI_FTSR);
  • 配置對應到外部中斷控制器(EXTI)的NVIC中斷通道的使能和屏蔽位,使得20箇中斷線中的請求可以被正確地響應。

硬件事件選擇

通過下面的過程,可以配置20個線路爲事件源

  • 配置20個事件線的屏蔽位(EXTI_EMR)
  • 配置事件線的觸發選擇位(EXTI_RTSR和EXTI_FTSR)

軟件中斷/事件的選擇

20個線路可以被配置成軟件中斷/事件線。下面是產生軟件中斷的過程:

  • 配置20箇中斷/事件線屏蔽位(EXTI_IMR, EXTI_EMR)
  • 設置軟件中斷寄存器的請求位(EXTI_SWIER)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章