4)选定要配置为 EXTI 的 I/O 口线和 I/O 口的工作模式。
5)EXTI 中断线工作模式配置。
/*
brief configure key
param[in] keynum: specify the key to be configured
arg KEY_TAMPER: tamper key
arg KEY_WAKEUP: wakeup key
arg KEY_USER: user key
param[in] keymode: specify button mode
arg KEY_MODE_GPIO: key will be used as simple IO
arg KEY_MODE_EXTI: key will be connected to EXTI line with interrupt
param[out] none
retval none
*/
void key_init(key_typedef_enum keynum, keymode_typedef_enum keymode)
{
/* enable the key clock */
rcu_periph_clock_enable(KEY_CLK[keynum]);
rcu_periph_clock_enable(RCU_AF);
/* configure button pin as input */
gpio_init(KEY_PORT[keynum], GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, KEY_PIN[keynum]);
if (keymode == KEY_MODE_EXTI)
{
/* enable and set key EXTI interrupt to the lowest priority */
nvic_irq_enable(KEY_IRQn[keynum], 2U, 0U);
/* connect key EXTI line to key GPIO pin */
gpio_exti_source_select(KEY_PORT_SOURCE[keynum], KEY_PIN_SOURCE[keynum]);
/* configure key EXTI line */
exti_init(KEY_EXTI_LINE[keynum], EXTI_INTERRUPT, EXTI_TRIG_FALLING);
exti_interrupt_flag_clear(KEY_EXTI_LINE[keynum]);
}
}
key_init()代码中,不仅配置了NVIC ,还对按键的GPIO进行了初始化,这部分和按键轮询的设置类似。
接下来,调用 gpio_exti_source_select () 函数把 GPIOA、Pin0 与EXTI连接起来。
最后调用 exti_init() 把 EXTI 初始化,函数如下:
/*!
\brief initialize the EXTI
\param[in] linex: EXTI line number, refer to exti_line_enum
only one parameter can be selected which is shown as below:
\arg EXTI_x (x=0..19): EXTI line x
\param[in] mode: interrupt or event mode, refer to exti_mode_enum
only one parameter can be selected which is shown as below:
\arg EXTI_INTERRUPT: interrupt mode
\arg EXTI_EVENT: event mode
\param[in] trig_type: interrupt trigger type, refer to exti_trig_type_enum
only one parameter can be selected which is shown as below:
\arg EXTI_TRIG_RISING: rising edge trigger
\arg EXTI_TRIG_FALLING: falling trigger
\arg EXTI_TRIG_BOTH: rising and falling trigger
\arg EXTI_TRIG_NONE: without rising edge or falling edge trigger
\param[out] none
\retval none
*/
void exti_init(exti_line_enum linex, exti_mode_enum mode, exti_trig_type_enum trig_type)
{
/* reset the EXTI line x */
EXTI_INTEN &= ~(uint32_t)linex;
EXTI_EVEN &= ~(uint32_t)linex;
EXTI_RTEN &= ~(uint32_t)linex;
EXTI_FTEN &= ~(uint32_t)linex;
/* set the EXTI mode and enable the interrupts or events from EXTI line x */
switch(mode) {
case EXTI_INTERRUPT:
EXTI_INTEN |= (uint32_t)linex;
break;
case EXTI_EVENT:
EXTI_EVEN |= (uint32_t)linex;
break;
default:
break;
}
/* set the EXTI trigger type */
switch(trig_type) {
case EXTI_TRIG_RISING:
EXTI_RTEN |= (uint32_t)linex;
EXTI_FTEN &= ~(uint32_t)linex;
break;
case EXTI_TRIG_FALLING:
EXTI_RTEN &= ~(uint32_t)linex;
EXTI_FTEN |= (uint32_t)linex;
break;
case EXTI_TRIG_BOTH:
EXTI_RTEN |= (uint32_t)linex;
EXTI_FTEN |= (uint32_t)linex;
break;
case EXTI_TRIG_NONE:
default:
break;
}
}
AFIO 时钟
代码中调用rcu_periph_clock_enable(RCU_AF)表示开启 AFIO的时钟。
AFIO (alternate-function I/O),指 GPIO 端口的复用功能,GPIO 除了用作普通的输入输出(主功能),还可以作为片上外设的复用输入输出,如串口、ADC,这些就是复用功能。大多数 GPIO 都有一个默认复用功能,有的 GPIO 还有重映射功能。重映射功能是指把原来属于 A 引脚的默认复用功能,转移到B引脚进行使用,前提是 B 引脚具有这个重映射功能。
当把 GPIO 用作 EXTI 外部中断或使用重映射功能的时候,必须开启 AFIO 时钟,而在使用默认复用功能的时候,就不必开启 AFIO 时钟了。
编写中断服务函数
在这个 EXTI 设置中我们把 PA0 连接到内部的 EXTI0,GPIO 配置为上拉输入,工作在下降沿中断。在外围电路上我们将 PA0 接到了 key上。当按键没有按下时,PA0 始终为高,当按键按下时 PA0 变为低,从而 PA0 上产生一个下降沿跳变,EXTI0 会捕捉到这一跳变,并产生相应的中断,中断服务程序在 gd32f20x_it.c 中实现。gd32f20x_it.c 文件是专门用来存放中断服务函数的。文件中默认只有几个关于系统异常的中断服务函数,而且都是空函数,在需要的时候自行编写。那么中断服务函数名是不是可以自己定义呢?不可以。中断服务函数的名字必须要与启动文件startup_gd32f20x_cl.s 中的中断向量表定义一致。
EXTI0_IRQHandler 表示为 EXTI0 中断向量的服务函数名。于是,我们就可以在 gd32f20x_it.c文件中加入名为 EXTI0_IRQHandler() 的函数。
/*!
\brief this function handles external lines 0 interrupt request
\param[in] none
\param[out] none
\retval none
*/
void EXTI0_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_0))
{
/* turn toggle LED */
led_toggle(LED1);
led_toggle(LED2);
led_toggle(LED3);
led_toggle(LED4);
exti_interrupt_flag_clear(EXTI_0);
}
}
其内容比较容易理解,进入中断后,调用exti_interrupt_flag_get() 库函数来重新检查是否产生了 EXTI_Line 中断,接下来把 LED 取反,操作完毕后,调用 exti_interrupt_flag_clear()清除中断标志位再退出中断服务函数。
3 实验现象
编译好程序后,下载到板子上,不管是普通方式还是中断方式,当按在按键KEY1时,LED或亮或灭。
上一篇:零基础学习GD32 红外遥控器原理
下一篇:最后一页
推荐阅读最新更新时间:2024-11-07 10:17
设计资源 培训 开发板 精华推荐
- MICRF002YM 300-440 MHz Qwik-Radio ASK 接收器的典型应用
- VIPer01-使用VIPer™Plus的5V、0.85A反激式转换器
- STA516B13TR 400W 典型单 BTL 配置电路,60V,6A 四路功率半桥
- XRP6670, 3A, 300kHz - 2.5MHz 同步降压稳压器典型应用电路
- 智能风扇
- 使用基于 ZICM357SP0-1C-R Ember EM35x 收发器模块的 Mesh Connect EM35x 迷你模块的典型应用电路
- 萝丽六通接收机
- #第五届立创电子设计大赛#基于STM32和ESP8266的智能家用电器
- LTC2164 演示板,16 位 105Msps ADC,LVDS 输出,5-140MHz
- 痛PCB[转载,分享]基板少女 PCB Girl