3.1實(shí)驗內(nèi)容
通過本實(shí)驗主要學(xué)習(xí)以下內(nèi)容:
3.2實(shí)驗原理
3.2.1NVIC中斷向量控制器
介紹EXTI之前,首先為各位讀者介紹NVIC中斷向量控制器,NVIC為M7內(nèi)核組件,用于實(shí)現(xiàn)高效的異常和中斷處理。NVIC可以支持搶占以及咬尾中斷,具有多達(dá)217種外設(shè)中斷以及4位中斷優(yōu)先等級配置(最多支持16個中斷有限等級),當(dāng)中斷或異常產(chǎn)生時,系統(tǒng)自動將當(dāng)前處理器工作狀態(tài)壓棧,在執(zhí)行完中斷服務(wù)子程序(ISR) 后自動將其出棧。
有關(guān)NVIC中斷相關(guān)配置函數(shù)可參考gd32h7xx_misc.c,其中主要有以下幾個函數(shù),其功能簡介如下表所示。
3.2.2EXTI中斷原理
EXTI為外部中斷/事件控制器,GD32H7系列MCU EXTI可以最多支持38個相互獨(dú)立的邊沿檢測電路并且能夠向處理器內(nèi)核產(chǎn)生中斷請求或喚醒事件。EXTI有三種觸發(fā)類型:上升沿觸發(fā)、下降沿觸發(fā)和任意沿觸發(fā)。EXTI中的每一個邊沿檢測電路都可以獨(dú)立配置和屏蔽。
EXTI框圖如下圖所示,極性控制用于控制邊沿檢測,可實(shí)現(xiàn)對外部EXTI信號線進(jìn)行檢測判斷,當(dāng)符合相關(guān)極性配置的EXTI信號出現(xiàn)后,將會發(fā)出EXTI請求,硬件EXTI請求與內(nèi)部軟件觸發(fā)信號相或,然后輸出給NVIC中斷向量控制器產(chǎn)生中斷以及輸出至喚醒單元進(jìn)行喚醒,也即是內(nèi)部軟件也可以觸發(fā)相關(guān)請求。
EXTI相關(guān)觸發(fā)源如下表所示,所有的GPIO均可以觸發(fā)EXTI,另外LVD、RTC鬧鐘、USB喚醒以及以太網(wǎng)喚醒也可以觸發(fā)EXTI中斷或事件,EXTI可用于喚醒深度睡眠模式下的MCU。
注意:相同編號的引腳共用中斷入口,比如PA0、PB0、PC0均使用EXTI0中斷線,讀者在使用時需注意不同的EXTI中斷需要使用不同編號的GPIO引腳。
?軟件觸發(fā)EXTI中斷請求可通過設(shè)置EXTI_SWIEV軟件中斷事件寄存器實(shí)現(xiàn),如下圖所示,設(shè)置相應(yīng)控制位為1,即可實(shí)現(xiàn)軟件觸發(fā)EXTI中斷請求。
3.3硬件設(shè)計
本例程所使用的電路也為按鍵電路,具體可參考2.4章節(jié)描述。
3.4代碼解析
3.4.1主函數(shù)代碼解析
主函數(shù)代碼如下所示,主要包括驅(qū)動初始化、LED初始化、key按鍵結(jié)構(gòu)體初始化(此處將用戶按鍵配置為中斷模式,并將中斷回調(diào)函數(shù)注冊為USER_KEY_IRQHandler)、串口初始化以及NVIC配置,用戶按鍵使用的是PA1引腳,因而使能EXTI1_IRQn中斷號,延遲1S后,打印Example of key interrupt detection,之后進(jìn)入主循環(huán),在主循環(huán)中查詢USER_KEY.press_timerms標(biāo)志位,當(dāng)USER_KEY被按鍵觸發(fā)中斷后,該標(biāo)志將會被設(shè)置為PRESS_DOWN,然后被主循環(huán)檢測到后,將會打印USER_KEY is pressed to trigger an interrupt。
C
int main(void)
{
driver_init();
bsp_led_group_init();
bsp_led_on(&LED2);
bsp_led_off(&LED1);
/* 配置按鍵為中斷模式,并注冊按鍵回調(diào)函數(shù) */
USER_KEY.key_gpio->gpio_mode = INT_LOW;
USER_KEY.key_gpio->int_callback = USER_KEY_IRQHandler;
bsp_key_init(&USER_KEY);
nvic_irq_enable(EXTI1_IRQn,0,0);
bsp_uart_init(&BOARD_UART);
delay_ms(1000);
printf_log("Example of key interrupt detection.\r\n");
while (1)
{
if(USER_KEY.press_timerms == PRESS_DOWN)
{
/* 檢測到按鍵被按下 */
USER_KEY.press_timerms = PRESS_NONE;
printf_log("USER_KEY is pressed to trigger an interrupt.\r\n");
}
}
}
3.4.2按鍵中斷回調(diào)函數(shù)
按鍵中斷回調(diào)函數(shù)如下所示,該函數(shù)在dvire_gpio_exti_handle中被調(diào)用,dvire_gpio_exti_handle在EXTI1_IRQHandler中被調(diào)用,其中EXTI2_IRQHandler為EXTI2的中斷服務(wù)程序入口。
C
void USER_KEY_IRQHandler(typdef_gpio_general *KEYx_IO)
{
if(SET==bsp_key_state_get(&USER_KEY))
{
USER_KEY.press_timerms=PRESS_DOWN;
bsp_led_toggle(&LED2);
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 EXTI1_IRQHandler(void)
{
dvire_gpio_exti_handle(USER_KEY.key_gpio);
}
3.5實(shí)驗結(jié)果
將本例程燒錄到海棠派開發(fā)板中,在液晶上首先將會打印Example of key interrupt detection.,之后按下USER_KEY按鍵后,將會打印:USER_KEYis pressed to trigger an interrupt.。
本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)
-
單片機(jī)
+關(guān)注
關(guān)注
6035文章
44554瀏覽量
634635 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5032瀏覽量
97372 -
GD32
+關(guān)注
關(guān)注
7文章
403瀏覽量
24328 -
EXTI
+關(guān)注
關(guān)注
0文章
27瀏覽量
3686
發(fā)布評論請先 登錄
相關(guān)推薦
評論