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浏览量
635195 -
mcu
+关注
关注
146文章
17148浏览量
351176 -
开发板
+关注
关注
25文章
5050浏览量
97451 -
GD32
+关注
关注
7文章
403浏览量
24347 -
EXTI
+关注
关注
0文章
27浏览量
3690
发布评论请先 登录
相关推荐
评论