GPIO输入——按键检测

当按下一个按键时,系统是如何检测到的呢?

我们通过LED灯的亮灭状态来间接完成按键检测。当按下按键时,LED灯亮,再次按下时,LED灯灭。

要完成这个实验,我们就会用到GPIO外设的基本输入功能。

查阅开发板的按键原理图,如图3-1。

图3-1

图中的K1、K2即为按键。以K1为例,当未按下按键时,其PA0引脚处于接地状态,即低电平,按下按键时,引脚接到电源,输入状态为高电平。所以只要我们检测按键对应引脚(这里是PA0)的输入电平状态,即可判断按键是否被按下。这便是按键的检测原理了。

有一点需要知道,由于机械按键的弹性作用,按下按键时并不会马上稳定接通或断开,即存在按键抖动。一般情况下我们需要通过软件或硬件的方式消抖才能得到理想的实验效果。软件消抖如通过定时器延时等方式,忽略前后的抖动;而硬件消抖,如可以利用电容的充放电延时等方式。本文默认已经进行过消抖处理了。

直接开始编程环节的分析。

首先得使能GPIO端口的时钟,然后初始化按键和LED灯的引脚,最后通过读取引脚不同电平状态控制LED灯的状态切换。这便是这个实验的大致步骤了。

使能GPIO端口时钟

所有的GPIO外设都挂载在APB2总线上,所以其使能寄存器为RCC_APB2ENR,查阅固件库手册可得其固件函数为RCC_APB2PeriphClockCmd(该固件函数功能即为对RCC_APB2ENR寄存器操作的封装)。我们需要使能的是GPIOA时钟,所以可调用如下API实现使能时钟:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

初始化按键和LED灯

在使能GPIOA时钟后,便开始初始化按键和LED灯了。我们需要用到GPIO_Init固件函数(该函数实现对配置引脚模式的封装),将引脚配置为浮空输入模式。这一步我们可以写一个函数将其封装起来。如下代码:

/**
  * @brief  初始化按键
  * @param  无
  * @retval 无
  */
void Key_GPIO_Config(void){

    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;         // 选择按键引脚PA0
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;     // 设置引脚模式为浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);            // 初始化按键

}

注:IO口为输入模式时,不用设置输出速率。

同样的,由于我们需要通过LED灯来间接完成按键检测(这里我们使用的是RGB灯,使用G色的引脚PB0),所以以上步骤也需要对LED灯的PB0引脚重复一遍,其流程与按键初始化流程类似,这里就不再赘述了,读者可参考按键流程完成。

检测按键状态

接下来就需要通过检测按键引脚的电平状态来判断按键是否按下了。那么我们怎么获取引脚的电平状态呢,查阅参考手册可知,我们可以通过读取IDR寄存器的值来获取。而这个操作同样被STM32固件库封装了,其函数名为GPIO_ReadInputDataBit。查看源码,其正是对IDR寄存器操作的封装,如下图3-2所示。

图3-2

其最终会返回引脚的电平状态,即返回1(高电平),返回0(低电平)。代码里“Bit_RESET”和“Bit_SET”已经通过枚举方式定义了,Bit_RESET=0(低电平),Bit_SET=1(高电平)。最后我们通过判断函数返回值完成按键检测。若按键按下,则引脚输出高电平。我们将该检测过程也封装为一个函数Key_DETECTOR,具体如下:

/**
  * @brief  检测按键状态
  * @param  GPIOx:x可以是A, B, C, D, E
  *         GPIO_Pin:对应引脚序号
  * @retval 1(高电平,即按下按键)、0(低电平,即没有按下按键)
  */
uint8_t Key_DETECTOR(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin){

    uint16_t keyState = GPIO_ReadInputDataBit(GPIOx, GPIO_Pin);

    /* 检测是否按下按键 */
    if(keyState){
	return 1;
    }else{
        return 0;
    }

}

万事俱备,只欠东风,我们终于可以开始写main函数了。main函数里,需要逐步调用以上所述的API,完成实验功能。直接上代码:

// 定义控制LED的引脚
#define LED_TOGGLE		          LED_Control(GPIOB, GPIO_Pin_0)
// 使用带参宏输出LED灯的另一种状态
#define LED_Control(GPIOx, GPIO_Pin)      {GPIOx->ODR ^= GPIO_Pin;}

int main(void){

    uint8_t SaveStatus = 0;
    uint8_t State;

    LED_GPIO_Config();
    Key_GPIO_Config();	

    while(1)
    {
        State = Key_DETECTOR(GPIOA, GPIO_Pin_0);
	if(SaveStatus != State)
	{
	    if(State == 1)
	    {
	        LED_TOGGLE;
	    }
	    SaveStatus = State;
	}
    }

}

至此,我们的按键检测实验也分析完成了。

转自知乎。

原文地址:https://www.cnblogs.com/fire909090/p/8874335.html

时间: 2024-10-13 11:55:55

GPIO输入——按键检测的相关文章

第12章 GPIO输入-按键检测—零死角玩转STM32-F429系列

第12章 ????GPIO输入-按键检测 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ? 本章参考资料:<STM32F4xx参考手册>.库帮助文档<stm32f4xx_dsp_stdperiph_lib_um.chm>. 按键检测使用到GPIO外设的基本输入功能,本章中不再赘述GPIO外设的概念,如您忘记了,可重读前面"GPIO框图剖析"小

第12章 GPIO输入—按键检测

第12章     GPIO输入-按键检测 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料:<STM32F4xx参考手册>.库帮助文档<stm32f4xx_dsp_stdperiph_lib_um.chm>. 按键检测使用到GPIO外设的基本输入功能,本章中不再赘述GPIO外设的概念,如您忘记了,可重读前面"GPIO框图剖析"小节,

第13章 GPIO输入—按键检测

本章参考资料:<STM32F76xxx参考手册>.库帮助文档<STM32F779xx_User_Manual.chm>. 按键检测使用到GPIO外设的基本输入功能,本章中不再赘述GPIO外设的概念,如您忘记了,可重读前面"GPIO框图剖析"小节,STM32 HAL库中GPIO初始化结构体GPIO_TypeDef的定义与"定义引脚模式的枚举类型"小节中讲解的相同. 13.1  硬件设计 按键机械触点断开.闭合时,由于触点的弹性作用,按键开关不会

GPIO 输入—按键检测

这里要用到一定的模电知识.电容两端电压不能突变,电感两端电流不能突变.这里利用了电容的放电延时实现硬件消抖.按键按下会有抖动,波形有毛刺,使得高低电平显现不明显,而按键按下时,电容放电一下,马上又被充电,此时电容两端的电压不会突然变化,这个延时时间恰好可以达到消抖作用. 这里需要使用一个固件库函数: /** * @brief Reads the specified input port pin. * @param GPIOx: where x can be (A..K) to select th

nRF51822外设应用[2]:GPIOTE的应用-按键检测

版权声明:本文为博主原创文章,转载请注明作者和出处.    作者:强光手电[艾克姆科技-无线事业部] 1. nRF51822寄存器类型 nRF51822的寄存器和一般的单片机有所差别,nRF51822的寄存器分为下面的三种类型. Task :任务寄存器,可以由程序或事件触发. Event:事件寄存器,事件可以产生中断或触发任务. Register:普通寄存器,和一般单片机的寄存器一样. Task和event使得操作片上外设十分方便简洁,只需进行少量的配置,即可轻松运用各种外设.同时,Task和e

ESP8266 LUA脚本语言开发: 外设篇-GPIO输入检测

咱使用 GPIO0 https://nodemcu.readthedocs.io/en/master/modules/gpio/#gpioread 第一种 GPIO设置为输出的状态下读取引脚状态 gpio.mode(3, gpio.OUTPUT) gpio.write(3, gpio.HIGH) if gpio.read(3) == 1 then print("GPIO0 is HIGH") end 可以检测继电器输出的状态,自行扩展! 第二种 GPIO设置为输入的状态下.检测GPIO

【iCore3 双核心板_FPGA】例程三:GPIO输入实验——识别按键输入

实验指导书及代码包下载: http://pan.baidu.com/s/1dEaDr37 iCore3 购买链接: https://item.taobao.com/item.htm?id=524229438677

beaglebone_black_学习笔记——(8)GPIO输入之KEY

今天笔者在LED灯的基础上写了一个GPIO作为输入端口的例子.实验中笔者采用一个按键作为IO输入设备,然后用bb_black去采集当前的信息. 第一步:硬件介绍 1.按键介绍 轻触按键的结构如下图所示,按键的1,2脚,3,4脚是分别连在一起的,当按下按键是也就是将1,3(或者2,4)引脚短接,松开时两脚间开路. 2.硬件原理 注: (1)为了防止误操作时,3.3V将IO口烧掉笔者在按键与3.3V之间连接了一个限流电阻(10k): (2)本实验笔者使用了P8排座的14引脚,也就是GPIO_26引脚

单片机第6课:独立按键检测原理

将JP5的8号引脚连接到单片机的P1^0,然后P1^0和发光二极管的接正引脚相连接(加高电平,发光二极管就会亮,由于单片机上电的时候各IO口默认为高电平,所以导线接好之后,发光二极管就点亮了).当我们按下K1的时候,发光二极管熄灭,松开按键,发光二极管再次点亮.因为当你按下按键的时候,TTL电路只有两种电平的时候,呈现"线与"的关系,再次检测P1^0引脚的电平,你会发现已经是低电平了.因为高电平与上低电平等于低电平.