4.1實驗內容
通過本實驗主要學習以下內容:
4.2實驗原理
4.2.1NVIC中斷向量控制器
介紹EXTI之前,首先為各位讀者介紹NVIC中斷向量控制器,NVIC為M4內核組件,用于實現高效的異常和中斷處理。NVIC可以支持搶占以及咬尾中斷,具有多達68種外設中斷以及4位中斷優先等級配置(最多支持16個中斷有限等級),當中斷或異常產生時,系統自動將當前處理器工作狀態壓棧,在執行完中斷服務子程序(ISR) 后自動將其出棧。
GD32F303系列MCU的中斷向量表如下表所示(包含異常中斷)。
有關NVIC中斷相關配置函數可參考gd32f30x_misc.c,其中主要有以下幾個函數,其功能簡介如下表所示。
4.2.2EXTI中斷原理
EXTI為外部中斷/事件控制器,GD32F303系列MCU EXTI可以最多支持20個相互獨立的邊沿檢測電路并且能夠向處理器內核產生中斷請求或喚醒事件。EXTI有三種觸發類型:上升沿觸發、下降沿觸發和任意沿觸發。EXTI中的每一個邊沿檢測電路都可以獨立配置和屏蔽。
EXTI框圖如下圖所示,極性控制用于控制邊沿檢測,可實現對外部EXTI信號線進行檢測判斷,當符合相關極性配置的EXTI信號出現后,將會發出EXTI請求,硬件EXTI請求與內部軟件觸發信號相或,然后輸出給NVIC中斷向量控制器產生中斷以及輸出至喚醒單元進行喚醒,也即是內部軟件也可以觸發相關請求。
EXTI相關觸發源如下表所示,所有的GPIO均可以觸發EXTI,另外LVD、RTC鬧鐘、USB喚醒以及以太網喚醒也可以觸發EXTI中斷或事件,EXTI可用于喚醒深度睡眠模式下的MCU。
|
?軟件觸發EXTI中斷請求可通過設置EXTI_SWIEV軟件中斷事件寄存器實現,如下圖所示,設置相應控制位為1,即可實現軟件觸發EXTI中斷請求。
4.3硬件設計
本例程所使用的電路也為按鍵電路,具體可參考3.3章節描述。
4.4代碼解析
4.4.1主函數代碼解析
主函數代碼如下所示,主要包括延遲初始化、LED初始化、key按鍵結構體初始化(此處將KEY0按鍵配置為中斷模式,并將中斷回調函數注冊為ROCKER_KEY_IRQHandler)、串口初始化以及NVIC配置,KEY0使用的是PE2引腳,因而使能EXTI2_IRQn中斷號,延遲1S后,打印Example of key interrupt detection,之后進入主循環,在主循環中查詢ROCKER_KEY.press_timerms標志位,當ROCKER_KEY被按鍵觸發中斷后,該標志將會被設置為PRESS_DOWN,然后被主循環檢測到后,將會打印ROCKER_KEY is pressed to trigger an interrupt。
C int main(void) { driver_init(); bsp_led_group_init(); bsp_led_on(&LED0); bsp_led_off(&LED1); /* 配置按鍵為中斷模式,并注冊按鍵回調函數 */ ROCKER_KEY.key_gpio->gpio_mode = INT_LOW; ROCKER_KEY.key_gpio->int_callback = ROCKER_KEY_IRQHandler; bsp_key_init(&ROCKER_KEY); nvic_irq_enable(EXTI2_IRQn,0,0); bsp_uart_init(&BOARD_UART); delay_ms(1000); printf_log("Example of key interrupt detection.\r\n"); while (1) { if(ROCKER_KEY.press_timerms == PRESS_DOWN) { /* 檢測到按鍵被按下 */ ROCKER_KEY.press_timerms = PRESS_NONE; printf_log("ROCKER_KEY is pressed to trigger an interrupt.\r\n"); } } } |
4.4.2按鍵中斷回調函數
按鍵中斷回調函數如下所示,該函數在dvire_gpio_exti_handle中被調用,dvire_gpio_exti_handle在EXTI2_IRQHandler中被調用,其中EXTI2_IRQHandler為EXTI2的中斷服務程序入口。
C void ROCKER_KEY_IRQHandler(typdef_gpio_general *KEYx_IO) { if(SET==bsp_key_state_get(&ROCKER_KEY)) { ROCKER_KEY.press_timerms=PRESS_DOWN; bsp_led_toggle(&LED0); bsp_led_toggle(&LED1); } } void dvire_gpio_exti_handle(typdef_gpio_general *gpio) { bit_status int_input_bit=RESET; if(exti_flag_get(gpio->extix)==SET) { exti_flag_clear(gpio->extix); int_input_bit=dvire_gpio_pin_filter_get(gpio); if( (gpio->gpio_mode==INT_LOW && int_input_bit==RESET) || (gpio->gpio_mode==INT_HIGH && int_input_bit==SET) ) { if(gpio->int_callback!=NULL) { gpio->int_callback((typdef_gpio_general *)gpio); } } } } void EXTI2_IRQHandler(void) { dvire_gpio_exti_handle(ROCKER_KEY.key_gpio); } |
4.5實驗結果
將本例程燒錄到紅楓派開發板中,通過Type C數據線連接USB串口和PC,打開串口調試助手,上電復位后,首先將會打印Example of key interrupt detection.,之后按下ROCKER_KEY按鍵后,將會打印:ROCKER_KEYis pressed to trigger an interrupt.。
-
單片機
+關注
關注
6037文章
44558瀏覽量
635233 -
mcu
+關注
關注
146文章
17148瀏覽量
351186 -
開發板
+關注
關注
25文章
5050瀏覽量
97456 -
GD32
+關注
關注
7文章
403瀏覽量
24351 -
EXTI
+關注
關注
0文章
27瀏覽量
3690
發布評論請先 登錄
相關推薦
評論