EXTI簡介
EXTI是外部中斷/事件控制器,包含多個邊沿檢測器,通過檢測I/O端口的電平變化判斷是否產生中斷/事件請求。
MM32F0140的EXTI包含19個外部中斷線,其中外部中斷線EXTI0 ~ EXTI15用于I/O映射,EXTI16連接到PVD輸出,EXTI19連接到比較器1輸出,EXTI24連接到IWDG中斷。可通過軟件控制任意一個I/O端口作為EXTI的輸入源,EXTI檢測對應端口是否產生邊沿觸發,若檢測到邊沿觸發則產生中斷/事件請求,GPIO對應的16個外部中斷/事件映射關系如圖1所示。
圖1 MM32F0140 GPIO對應外部中斷/事件映射
EXTI進行邊沿檢測時包含三種觸發類型:
上升沿觸發
電平由低到高時的一瞬間稱為上升沿,由上升沿的產生觸發輸出變化就稱作上升沿觸發。
下降沿觸發
電平由高到低時的一瞬間稱為下降沿,由下降沿的產生觸發輸出變化則稱為下降沿觸發。
任意邊沿觸發
電平由上升沿或下降沿的產生而觸發輸出變化被稱作任意邊沿觸發。
中斷/事件產生過程如圖2所示,EXTI邊沿檢測引腳的外部輸入電平,若由于外部因素導致引腳電平變化并產生邊沿觸發,則邊沿檢測電路輸出有效信號。或門電路接收邊沿檢測電路輸出的信號與軟件事件中斷寄存器(EXTI_SWIER)的輸出,軟件事件中斷寄存器能夠通過軟件啟動中斷/事件線。當外部中斷線上觸發邊沿事件時,掛起寄存器(EXTI_PR)的對應位被置1,可通過讀EXTI_PR寄存器獲取當前中斷/事件狀態。或門電路的輸出與中斷屏蔽寄存器(EXTI_IMR)的輸出相與,在使能對應線中斷位且邊沿觸發有效信號時,輸出有效信號到內核的NVIC中,NVIC進行中斷處理。或門電路的輸出與事件屏蔽寄存器(EXTI_EMR)的輸出結果相與,當使能對應事件線位且邊沿觸發有效信號時,輸出有效信號1,即脈沖信號,該脈沖信號可用于其他外設,例如觸發TIM。
圖2 EXTI模塊框圖
EXTI的配置
配置中斷
配置并使能中斷線,根據圖1判斷指定I/O端口對應的外部中斷線與SYSCFG_EXTICRx寄存器中的控制位,(EXTI0~EXTI3使用SYSCFG_EXTICR1寄存器,EXTI4~EXTI7使用SYSCFG_EXTICR2寄存器,EXTI8~EXTI11使用SYSCFG_EXTICR3寄存器,EXTI12~EXTI15使用SYSCFG_EXTICR4寄存器)向SYSCFG_EXTICRx寄存器中外部中斷線的對應位賦值,若使用PA管腳則對應位賦值為0000,PB管腳對應位賦值為0001,PC管腳對應位賦值為0010,PD管腳對應位賦值為0011。
配置邊緣檢測觸發器的觸發類型,若使用上升沿觸發,則對上升沿觸發選擇寄存器(EXTI_RTSR)的外部中斷線對應位置1;若使用下降沿觸發,則對下降沿觸發選擇寄存器(EXTI_FTSR)的外部中斷線對應位置1;若使用任意邊沿觸發,則EXTI_RTSR寄存器與EXTI_FTSR寄存器的外部中斷線對應位均置1。
中斷屏蔽寄存器(EXTI_IMR)的外部中斷線對應位置1,允許中斷請求。當指定的外部中斷線檢測到配置的觸發條件時,產生一個中斷請求,掛起寄存器(EXTI_PR)的對應位置1。通過軟件對掛起寄存器中對應位寫入1,使中斷被清除。
配置軟件中斷事件寄存器(EXTI_SWIER)的外部中斷線對應位為1并置1 EXTI_IMR寄存器的外部中斷線對應位,也能產生中斷。
配置事件
配置并使能事件線,對SYSCFG_EXTICRx寄存器中外部事件線的對應位賦值;配置邊緣檢測觸發寄存器為需要的觸發類型,對EXTI_RTSR寄存器與EXTI_FTSR寄存器賦值;事件屏蔽寄存器(EXTI_EMR)的對應位置1,允許事件請求。當檢測到配置的觸發條件時,產生一個事件請求,掛起寄存器對應位置 1;通過對掛起寄存器對應位寫1清除事件。
配置軟件中斷事件寄存器(EXTI_SWIER)的外部中斷/事件線對應位為1并置1 EXTI_EMR寄存器的對應位,也能產生事件。
實驗
本實驗在靈動官方開發板MB-023上進行,通過配置EXTI下降沿觸發中斷,按下按鍵后產生邊沿觸發,進行中斷處理,LED電平轉換。配置按鍵所使用的I/O端口的對應外部中斷線,對SYSCFG_EXTICRx寄存器的EXTIx位賦值,對EXTI_RTSR寄存器和EXTI_FTSR寄存器賦值配置觸發類型,使用EXTI_IMR寄存器使能中斷,EXTI_PR寄存器對應位置1清除中斷。具體實驗內容為配置按鍵K2的對應引腳PB2與LED2對應的PB3引腳(如圖3所示),配置PB2對應的外部中斷線為下降沿觸發,若按下K2,按鍵對應的端口輸入低電平,下降沿觸發,產生中斷。實驗現象為按下按鍵K2,LED2電平反轉一次。
圖3 MCU原理圖中的EXTI引腳
初始化外設時鐘
SYSCFG在APB2線上,GPIO在AHB線上,實驗使用SYSCFG配置外部中斷,按鍵K2與LED2的引腳均為GPIOB組的引腳。因此對RCC_APB2ENR寄存器的SYSCFGEN位置1,對RCC_AHBENR寄存器的GPIOB對應位置1,從而初始化外設時鐘。
// Enable SYSCFG clock. RCC->APB2ENR |= (1u << 0u); // Enable GPIOB clock. RCC->AHB1ENR |= (1u << 18u);
初始化按鍵
實驗使用引腳為PB2的K2按鍵,按鍵原理圖如圖4所示,若K2按鍵按下則與GND導通,因此在初始化按鍵時需配置該端口的工作模式為上拉輸入。
圖4 原理圖中的按鍵
GPIOx_CRL寄存器為端口配置低寄存器,用于配置指定端口的速度與工作模式;GPIOx_BSRR寄存器用于設置/清除對應端口,該寄存器低16位的對應端口位置1會產生高電平。由圖5所示,K2所使用的端口PB2為GPIOx_CRL寄存器內第8 ~ 11位。
圖5 GPIOx_CRL寄存器
// Clear the configuration bit of port 2. GPIOB->CRL = ~(0xf << 8u); // Configure pull-up input mode. GPIOB->CRL |= (0x8 << 8u); // Configure PB2 pin to high level. GPIOB->BSRR |= (1u << 2u);
初始化LED
實驗使用PB3引腳,使用GPIOx_CRL寄存器對LED進行初始化配置,如圖5所示,端口3為GPIOx_CRL寄存器內第12 ~ 15位。
// Clear the configuration bit of port 3. GPIOB->CRL = ~(0xf << 12u); // Configure push-pull output mode. GPIOB->CRL |= (0x1 << 12u);
配置中斷線
由圖1可知,PB2使用的外部中斷線為EXTI2,配置SYSCFG_EXTICR1寄存器的EXTI2對應位為0001,如圖6所示,EXTI2處于SYSCFG_EXTICR1寄存器的8~ 11位。
圖6 GPIOx_EXTICR1
// Clear EXTI2 and assign value, the corresponding value of PB is 0001. SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 ~(0xf << 8u) ) | (0x1 << 8u) );
配置觸發類型
在按鍵初始化中配置按鍵未按下時處于高電平,因此,對上升沿觸發選擇寄存器(EXTI_RTSR)與下降沿觸發選擇寄存器(EXTI_FTSR)賦值時配置觸發類型為下降沿觸發。
// Clear the corresponding bit of EXTI2 triggered by rising edge. EXTI->RTSR = ~ (1u << 2u); // Configure falling edge trigger. EXTI->FTSR |= (1u << 2u);
使能中斷
配置EXTI_IMR寄存器的EXTI2對應位,使能中斷。
// Enable EXTI interrupt. EXTI->IMR |= (1u << 2u);
配置NVIC
EXTI控制中斷,NVIC處理中斷,使用Cortex-M0 core_cm0.h頭文件中的NVIC_EnableIRQ使能中斷線,EXTI2對應中斷為EXTI2_3_IRQn。
// Setup NVIC. NVIC_EnableIRQ (EXTI2_3_IRQn);
編寫中斷服務程序
中斷使能中使用EXTI2_3_IRQn,中斷處理函數要與其匹配,因此使用EXTI2_3_IRQHandler,設置變量app_exti_event_on作為中斷狀態標志,該變量初始時為false,中斷請求產生時中斷狀態標志轉換為true,將EXRI_PR寄存器的對應位寫入1來清除中斷。
void EXTI2_3_IRQHandler(void) { uint32_t flags = EXTI->PR; if ( 0u != ( flags (1u << 2u) ) ) { app_exti_event_on = true; } EXTI->PR |= (1u << 2u); // Clear interrupt. }
main()函數
主程序中初始化變量app_exti_event_times為0,設置該變量從0開始計數,當中斷狀態標志app_exti_event_on為true,即產生中斷請求時,計數值加1,由于LED2初始化后顯示為亮,計算計數值取余2,若余數不等于0則LED2滅,若余數為0則LED2亮。實驗效果如圖7所示。
int main(void) { // Enable SYSCFG and GPIOB clock. RCC->APB2ENR |= (1u << 0u); RCC->AHB1ENR |= (1u << 18u); // Setup K2. GPIOB->CRL = ~(0xf << 8u); GPIOB->CRL |= (0x8 << 8u); GPIOB->BSRR |= (1u << 2u); // Setup LED2. GPIOB->CRL = ~(0xf << 12u); GPIOB->CRL |= (0x1 << 12u); // Setup SYSCFG EXTI2. SYSCFG->EXTICR1 = ( ( SYSCFG->EXTICR1 ~(0xf << 8u) ) | (0x1 << 8u) ); // Setup EXTI. EXTI->RTSR = ~ (1u << 2u); EXTI->FTSR |= (1u << 2u); // Enable EXTI interrupt. EXTI->IMR |= (1u << 2u); // Setup NVIC. NVIC_EnableIRQ (EXTI2_3_IRQn); while (1) { while ( !app_exti_event_on ) { } app_exti_event_on = false; app_exti_event_times++; if ( (app_exti_event_times % 2u) != 0u ) { GPIOB->BSRR = (1u << 3u);// LED2(PB3 pin) off. } else { GPIOB->BRR = (1u << 3u);// LED2(PB3 pin) on. } } }
圖7 實驗現象
審核編輯:彭菁
-
控制器
+關注
關注
112文章
16445瀏覽量
179446 -
比較器
+關注
關注
14文章
1658瀏覽量
107428 -
電平
+關注
關注
5文章
361瀏覽量
40006 -
端口
+關注
關注
4文章
990瀏覽量
32206
發布評論請先 登錄
相關推薦
評論