【单片机/嵌入式】【梁山派】学习日志09:按键

一、独立按键

1.1独立按键基础知识

1.1.1独立按键结构组成

独立按键实际上是一个非自锁的轻触开关,有左右两个触点当按下时左右两个触点闭合,当松开时左右两个触点断开

1.1.2独立按键原理

单片机通过检测按键按下前后的高低电平变化,来判断按键是否按下。通过程序的控制,就可以实现不同的功能与设置。机械式按键在按下或者释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。抖动时间长短与开关的机械特性有关,一般为5-10ms。在触点抖动期间检测按键的按下与否,可能会导致判断错误,为了克服机械抖动所产生的影响,必须采取消抖措施,可分为硬件消抖软件消抖

1.1.3消抖措施

硬件消抖:硬件消抖一般会在按键两端并联电容,通过电容的充放电作用将按键按下时的高频振荡吸收掉。

软件消抖:软件消抖一般是通过延时。当检测到按键按下时,不会立即去检测电平,而是经过短暂的延时之后,再去检测当前引脚的电平。

1.1.4独立按键驱动原理

独立按键直接接到单片机的一个IO上,通过检测单片机的IO为高低电平判断按键是否按下。

1.2独立按键原理图

开发板上一共有三个按键,一个复位、一个BOOT0和一个KEY_UP,复位和BOOT0作为单片机的特殊功能,不可以作为按键使用,故只有KEY_UP可以作为按键使用。开发板关于独立按键的原理图如图所示。

 

1.3独立按键驱动流程

通过上面的原理图可以了解到,KEY_UP引脚接到了单片机的PA0引脚上。按键的一端接到了3.3V,另一端通过一个10K的电阻接到了地。通过检测PA0引脚的电平状态,判断按键是否按下。当按键松开的时候,PA0检测到的电平为低电平当按键按下的时候,PA0检测到的电平为高电平。在程序里使能PA0引脚,配置为输入模式,然后以一定时间去获取PA0引脚的状态,判断按键是否按下,如果按键按下,就执行对应的功能。

二、按键点灯

2.1配置流程

一般使用GPIO的端口输入功能,都需要有以下几个步骤。

(1)开启GPIO的端口时钟

(2)配置GPIO的模式

开发板的按键使用的是KEY_UP,接到了单片机的PA0引脚上,因此需要配置PA0引脚的状态。

2.1.1开启GPIO的端口时钟

按键接到了单片机的PA0引脚上,首先要使能GPIOA端口的时钟。还是用rcu_periph_clock_enable函数,只需要将GPIOA时钟当做参数传入。为了移植方便,可以将按键的时钟和引脚进行宏定义。

/* 定义key的引脚 */

#define BSP_KEY_RCU      RCU_GPIOA

#define BSP_KEY_PORT    GPIOA

#define BSP_KEY_PIN      GPIO_PIN_0

使能GPIOA的端口可以写为:

/* 开启时钟 */

rcu_periph_clock_enable(BSP_KEY_RCU);

2.1.2配置GPIO模式

通过前面章节的按键检测原理知道需要检测按键引脚的电平状态来判断按键是否按下,要检测电平引脚的状态,就需要将按键配置为输入模式。开发板上的按键默认接的是低电平,即按键松开的状态需要是低电平,在默认状态下需要将按键的状态保持为低电平。开发板上已经做了下拉处理(10kΩ电阻接地),代码中可以配置为无上下拉(浮空)也可以配置为下拉

使能按键的引脚为输入模式和下拉模式,转换为代码为:

/* 配置为输出模式 下拉模式 */   

gpio_mode_set(BSP_KEY_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, BSP_KEY_PIN); 

// 按键默认状态是低电平,所以配置为下拉

2.2获取按键的状态

配置好GPIO之后,就可以检测按键引脚的状态了。

首先还是到gd32f4xx_gpio.h中去查找对应的获取引脚状态的库函数。

FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin);

这个函数可以获取引脚电平状态,有两个参数,第一个参数就是要获取引脚的端口,第二个参数就是要获取的引脚,还有一个返回值,返回值是获取到的引脚的状态,如果为高电平就为1,如果为低电平就为0。

 

获取PA0引脚的电平状态转换为代码就是:

gpio_input_bit_get(BSP_KEY_PORT,BSP_KEY_PIN);

判断按键是否按下只需要判断检测的引脚电平是高电平即可。

转化为代码为:

/* 先读取按键引脚的电平 如果高电平,按键按下 */   

if(gpio_input_bit_get(BSP_KEY_PORT,BSP_KEY_PIN) == SET) // 按键按下   

{

}

前面说过,机械按键按下之后会发生抖动,有硬件消抖和软件消抖两种,开发板上没有做硬件消抖处理,这里用软件来实现

可以在第一次检测到按键按下之后延迟一定的时间,按键稳定之后再次检测按键按下,即可判断按键是按下状态。在按键按下之后就可以执行功能,比如点灯。在按键按下之后可以通过检测按键的引脚的状态变为低电平判断按键是否松开,这里用串口打印按键按下和松开的状态,最终编写代码为:

void key_scan(void){   

    /* 先读取按键引脚的电平 如果高电平,按键按下 */   

    if(gpio_input_bit_get(BSP_KEY_PORT,BSP_KEY_PIN) == SET) // 按键按下   

    {

        /* 延迟消抖 */       

        delay_1ms(20);        

        if(gpio_input_bit_get(BSP_KEY_PORT,BSP_KEY_PIN) == SET) // 再次检测按键是否按下        

        {           

            /* 执行功能 */           

            gpio_bit_toggle(BSP_LED2_PORT,BSP_LED2_PIN); // led电平状态翻转           

            printf("key press!\r\n");           

            while(gpio_input_bit_get(BSP_KEY_PORT,BSP_KEY_PIN) == SET); // 等待按键松开           

            printf("key release!\r\n");       

        }   

    }

}

上面实现的效果就是按一次按键,led开启,再按一次按键,led关闭,每次按键按下和松开都会在串口打印key press和key release。

这里led的实现用了一个新的库函数。

void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin);

这个函数可以使引脚电平状态翻转,有两个参数,第一个参数是要翻转的引脚的端口,第二个参数是要翻转的引脚。

2.3实验

按键按下后,向串口发送客户编号,小灯亮起;按键松开后,向串口发送数字,小灯闪烁。

 

期间解决了如下两个问题:

Undefined symbol ...【标识符未定义】https://www.cnblogs.com/steven913/p/16867891.html

function ... declared implicitly【函数隐式声明】https://www.cnblogs.com/steven913/p/16867834.html

posted @ 2022-11-08 09:07  U羊U  阅读(522)  评论(0编辑  收藏  举报