一. 按键中断实验工作
本篇文章接上一篇文章的实验。上一篇文章如下:
IMX6ULL裸机篇--向GPIO驱动添加中断处理函数_凌雪舞的博客-CSDN博客
上一篇文章已经写好了GPIO设置中断所要做的工作。这一节编写按键中断代码并运行。
按键中断实验大体工作如下:
1. 首先设置 GPIO的中断触发方式。
在这之前也是需要做一些工作的,其中包括设置GPIO复用功能,设置电气特性等。
对于设置按键中断实验,根据原理图可知,我们设置 KEY0,也就是 UART1_CTS 这个 IO 为下降沿触发。
2. 使能 GIC控制器(GIC控制器是中断控制器)。
3. 注册中断函数。
注册到相应 GPIO的中断函数,当然也是需要实现的。实现好中断服务函数后,将该中断函数注册到指定的IO。
4. 设置中断使能。
这里是中断的使能,不同于 GIC控制器使能。两个是不同的使能。
二. 按键中断实验
基于之前几篇文章的介绍铺垫,现在可以编写按键 KEY0的中断实验代码,调用之前实现的通用中断相关接口。
在工程 /bsp目录下,新建名为 "exit" 目录。再在 bsp/exit/ 目录下,创建 bsp_exit.h 和 bsp_exit.c 两个文件。
注意:在中断服务函数中,切记要"快进快出",禁止在中断服务函数中调用延时函数
这里是按键中断函数中,为了按键消抖,才加了延时的操作。实际开发中,是禁止加延时操作的。
bsp_exit.c文件中,按键中断代码实现如下:
#include "bsp_exter_int.h"
#include "bsp_gpio.h"
#include "bsp_delay.h"
#include "bsp_beep.h"
#include "bsp_int.h"
/*初始化外部中断,KEY0即 GPIO1_IO18 */
void exter_inter_init(void)
{
gpio_pin_config_t key_config;
//复用为GPIO功能
IOMUXC_SetPinMux(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0);
//配置电气特性
IOMUXC_SetPinConfig(IOMUXC_UART1_CTS_B_GPIO1_IO18, 0X1070);
key_config.direction = kGPIO_DigitalInput; //GPIO1_IO18设置为输入
key_config.interruptMode = kGPIO_IntFallingEdge; //下降沿触发
gpio_init(GPIO1, 18, &key_config);
//使能GIC控制器
GIC_EnableIRQ(GPIO1_Combined_16_31_IRQn);
//注册按键中断函数
system_register_irqhandler(GPIO1_Combined_16_31_IRQn, key_interrupt, NULL);
//设置中断使能(不同于上面的GIC控制器使能)
gpio_interrupt_enable(GPIO1, 18);
}
/* 按键中断服务函数 */
void key_interrupt(unsigned int gicciar, void* param)
{
static unsigned char beep_status = 0;
delay(10); //这里加延时为了按键消抖
//在实际开发中,中断函数中要“快尽快出”,禁止在中断服务函数中调用延时函数
if(0 == gpio_pin_read(GPIO1, 18))
{
beep_status = !beep_status;
beep_switch(beep_status);
}
//清除中断标志位
gpio_clearintflags(GPIO1, 18);
}
可以看出,中断处理结束之后,需要清除中断标志位。
main.c 文件代码实现如下:
#include "imx6ull.h"
#include "bsp_clk.h"
#include "bsp_delay.h"
#include "bsp_led.h"
#include "bsp_beep.h"
#include "bsp_key.h"
#include "bsp_int.h"
#include "bsp_exter_int.h"
int main(void)
{
unsigned int led_status = OFF;
int_init(); //中断初始化
imux6ull_clk_init(); //初始化系统时钟
clk_enable(); //使能外设时钟
led_init(); //Led初始化
beep_init(); //蜂鸣器初始化
key_init(); //key按键初始化
exter_inter_init(); //Key0中断初始化
while(1)
{
//LED灯每隔
led_status = !led_status;
led_switch(LED0, led_status);
delay(500);
}
return 0;
}
经过开发板运行测试,按键按下后,蜂鸣器会响或者关闭。说明按键中断函数实现,本次实验完成。