第九章 按键中断实验
本章实验将介绍如何使用SDK编程让Kendryte K210通过中断的方式获取板载按键的状态。通过本章的学习,读者将学习到SDK编程技术使用Kendryte K210的GPIO输入中断功能。 本章分为如下几个小节: 9.1 GPIO介绍 9.2 硬件设计 9.3 程序设计 9.4 运行验证
9.1 GPIO介绍 有关GPIOHS外设的介绍,请见第8.1小节《GPIOHS介绍》。
9.2 硬件设计 9.2.1 例程功能 1. 当KEY0按键被按下后,双色LED的红灯切换一次亮灭状态
9.2.2 硬件资源 1. 双色LED LEDR - IO24 2. 独立按键 KEY0按键 - IO18
9.2.3 原理图 本章实验内容,需要通过KEY0按键按下是产生的下降沿触发GPIO的中断,正点原子DNK210开发板上KEY0按键的连接原理图,如下图所示: 9.2.3.1 KEY0按键连接原理图 通过以上原理图可以看出,KEY0按键对应的IO编号为IO18,当KEY0按键被按下后,其对应IO的电平将变为低电平。
9.3 程序设计 9.3.1 按键中断驱动代码 按键中断属于外部中断的一种,驱动源码包括两个文件:exti.c和exti.h,我们先介绍exti.h。 /* 硬件IO口,与原理图对应 */ #define PIN_KEY_EXTI (18) /*****************************SOFTWARE-GPIO********************************/ /* 软件GPIO口,与程序对应 */ #define EXTI_GPIONUM (3) /*****************************FUNC-GPIO************************************/ /* GPIO口的功能,绑定到硬件IO口 */ #define FUNC_KEY0_EXTI (FUNC_GPIOHS0 + EXTI_GPIONUM) /******************************************************************************************/ KEY0对应的硬件引脚IO为IO_18,这部分不变,为了区分上个按键实验,我们使用GPIOHS3,完成引脚功能绑定,exti.h内容比较少,我们直接看对应的源文件。 void exti_init(void) { /* 初始化中断,使能全局中断*/ plic_init(); sysctl_enable_irq(); fpioa_set_function(PIN_KEY_EXTI, FUNC_KEY0_EXTI); gpiohs_set_drive_mode(EXTI_GPIONUM, GPIO_DM_INPUT_PULL_UP); /*输入上拉*/ gpiohs_set_pin_edge(EXTI_GPIONUM, GPIO_PE_FALLING); /* 设置为下降沿触发 */ gpiohs_irq_register(EXTI_GPIONUM, 4, gpiohs_key0_exti_cb, NULL); /* 注册中断,绑定按键 */ } 这个是中断初始化代码,因为开启了中断功能,所以首先我们需要先初始化中断并使能,然后绑定KEY0的按键功能,独立按键KEY0在没有按下时是浮空状态,所以我们需要设置为输入上拉,然后通过gpiohs_set_pin_edge函数设置引脚中断为下降沿触发(引脚默认配置为上拉,按下后接入低电平,出现 1->0 即下降沿),接着是注册中断,设置中断服务函数等。 int gpiohs_key0_exti_cb(void *ctx) { LEDR(1); /* 红灯灭 */ LEDB(0); /* 蓝灯亮 */ sleep(1); /* 延时1秒 */ LEDR(0); /* 红灯亮 */ LEDB(1); /* 蓝灯灭 */ sleep(1); /* 延时1秒 */ return 0; } 当发生中断时,就会进入中断服务函数gpiohs_key0_exti_cb,执行中断程序,这里我们只是简单的红蓝灯亮灭一次,这里需要提一下的是,我们中断函数使用了延时函数,但是不建议读者在实际的应用中在中断服务函数中添加延时,因为中断服务函数的执行应该要尽可能的快,如果需要在中断中执行比较耗时的事务,建议将该事务分为上下文进行执行,从而减少中断服务函数执行的时间。
9.3.2 main.c代码 main.c中的代码如下所示: #include <stdio.h> #include <unistd.h> #include <sleep.h> #include "./BSP/EXTI/exti.h" #include "./BSP/LED/led.h" int main(void) { led_init(); /* LED初始化 */ exti_init(); /* 外部中断初始化 */ while (1) { msleep(10); } } main函数十分简单,仅仅是对外部中断和LED实现初始化后,就进入死循环执行延时,不做其他任何处理。
9.4 运行验证 将DNK210开发板连接到电脑主机,通过VSCode将固件烧录到开发板中,此时,若按下板载的KEY0按键,则能看到双色LED的红色LED切换了亮灭状态,这与理论推断的结果一致。
|