使用查询方式检测按键
- 实验目的
本节实验目的为获取按键状态。这一节计划采取查询的方式来检测按键状态,按键每按下一次,翻转一下LED的状态,以此来表示检测到按键按下的动作,所使用的LED为上一节提到的红色LED。
- 实验准备
1)、带按键和发光二极管(LED)的K210开发板一块,用于实践并查看实验现象;
2)、官方裸机编程指导手册:kendryte_standalone_programming_guide,用于查阅SDK中接口说明。
- 实验原理
如下图硬件设计,当微动开关(按键)按下时,会将IO电平拉低,松开时,IO电平拉高,所以,如果采用查询方式来判断按键状态的话,只需获取IO电平状态,即可知道按键的状态。
- 硬件设计
硬件电路图如下:
- 软件设计
软件流程图如下:
- 软件实现
根据硬件设计和软件设计可知,本节应用实现步骤如下:
1)、设置引脚复用功能:由硬件原理图可知:我们需要将IO12和IO16设置为GPIOHS功能,如下图:
2)、LED初始化,如下图:
3)、按键初始化,如下图:
4)、检测按键状态,并根据按键状态,对LED进行控制,如下图:
根据上述实现步骤,最终代码如下:
#include <fpioa.h>
#include <gpiohs.h>
#include <sleep.h>
#define LED_R_PIN (12)
#define LED_R_GPIOHSNUM (0)
#define LED_R_FUNC (FUNC_GPIOHS0+LED_R_GPIOHSNUM)
#define KEY_BT1_PIN (16)
#define KEY_BT1_GPIOHSNUM (1)
#define KEY_BT1_FUNC (FUNC_GPIOHS0+KEY_BT1_GPIOHSNUM)
/*********************************
* 管脚功能初始化
********************************/
void init_hardware(void)
{
// 将红色LED管脚设置复用为GPIOHS
fpioa_set_function(LED_R_PIN, LED_R_FUNC);
// 将按键管脚设置复用为GPIOHS
fpioa_set_function(KEY_BT1_PIN, KEY_BT1_FUNC);
}
/*********************************
* LED初始化
********************************/
void init_led(gpio_pin_value_t value)
{
// 设置输出
gpiohs_set_drive_mode(LED_R_GPIOHSNUM, GPIO_DM_OUTPUT);
// 设置初始电平状态
gpiohs_set_pin(LED_R_GPIOHSNUM, value);
}
/*********************************
* 控制LED亮灭
********************************/
void ctl_led(gpio_pin_value_t value)
{
gpiohs_set_pin(LED_R_GPIOHSNUM, value);
}
/*********************************
* 按键初始化
********************************/
void init_key(void)
{
// 设置输入
gpiohs_set_drive_mode(KEY_BT1_GPIOHSNUM, GPIO_DM_INPUT);
}
/*********************************
* 获取按键状态
********************************/
gpio_pin_value_t get_key_statue(void)
{
return gpiohs_get_pin(KEY_BT1_GPIOHSNUM);
}
int main()
{
gpio_pin_value_t led_r_value = GPIO_PV_HIGH; // LED初始电平
unsigned char key_release_flag = 0; // 按键松手标志
init_hardware(); // 设置管脚复用功能
init_led(led_r_value); // led初始化
init_key(); // 按键初始化
while(1)
{
if(get_key_statue() == 0 && key_release_flag == 0) // 按键按下
{
led_r_value = !led_r_value;
ctl_led(led_r_value);
key_release_flag = 1;
}
else if(get_key_statue() == 1 && key_release_flag == 1) // 按键松开
{
key_release_flag = 0;
}
else
{
key_release_flag = key_release_flag;
}
}
return 0;
}
- 编译
1)、同上一节类似,在SDK中创建key_find文件夹,在新建的文件夹中创建一个main.c文件,然后将本节代码输入到main.c文件中,如下图:
2)、同上一节的编译方式类似,打开vscode终端,在终端中进入上一节创建的build文件夹,然后输入:cmake ../ -DPROJ=key_find -G "MinGW Makefiles" ,生成makefile文件,如下图:
3)、生成makefile文件后,输入:make ,开始编译,如下图:
4)、编译完成后,会在build目录下生成烧录文件:key_find.bin,如下图:
- 烧录
同上一节的烧录方式类似,注意:Firmware那一项选择我们刚编译出的key_find.bin文件。
- 实验现象
每按一次按键,LED状态反转一次,例如:初始LED灭,按下一次按键,LED亮,再按一下按键,LED灭,以此循环。
- 实验总结
1)、微动开关是依靠内部拨片的接触来实现物理导通的,而内部拨片有一定弹性,所以,当我们按下或者松开按键时,可能会有一定的抖动,在抖动期间内,开关处于频繁通断的状态,导致电平跳动。这个时候,就需要我们去给按键做消抖处理,消抖处理可以从硬件上做消抖,也可以从软件上做消抖,用户在使用按键时,需查看硬件原理图是否有消抖处理,如果没有的话,就需要我们使用软件来消抖。