stm32实现GPIO输入按键检测 您所在的位置:网站首页 readinputdatabit返回值 stm32实现GPIO输入按键检测

stm32实现GPIO输入按键检测

2023-07-28 08:59| 来源: 网络整理| 查看: 265

1、硬件设计

按键机械触点断开、闭合时,由于按键触点的弹性作用,按键开关不会马上稳定接通或一下就断开,使用按键时就会产生下图中的带纹波信号,需要软件消抖处理滤波

由于用软件消抖处理滤波不方便输入检测,所以提出了如下带有硬件消抖的电路。

从按键的原理图可知,当按键没有被按下时,GPIO引脚通过一个下拉电阻R64使引脚处于低电平状态,当按键被按下时,按键所在的电路导通,VCC通过一个限流电阻R33连接到GPIO引脚,使GPIO引脚的输入状态为高电平,只要我们检测引脚的输入电平为高电平,即可判断按键是否被按下。

同LED工程,为了使工程的移植性更高,是工程更有条理,我们把按键相关的代码独立分开存储,在工程模板上新建“bsp_key.c”及“bsp_key.h”,这些文件可由自己的喜好命名,这些文件不属于STM32标准库的内容,是根据自己的需要编写的。

bsp_keyscan.c中代码如下

#include "bsp_keyscan.h" /** * @brief 配置按键检测用到的I/O口 * @param 无 * @retval 无 */ void key_GPIO_Config(void) { GPIO_InitTypeDef GPIO_key_InitStructure; RCC_AHB1PeriphClockCmd(key1_GPIO_CLK, ENABLE); //enable AHB1 periphral clock RCC_AHB1PeriphClockCmd(key2_GPIO_CLK, ENABLE); //enable AHB1 periphral clock GPIO_key_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_key_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_key_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_key_InitStructure.GPIO_Speed = GPIO_Fast_Speed; //keyscan gpio port register configure GPIO_key_InitStructure.GPIO_Pin = key1_pin; GPIO_Init(key1_GPIO_PORT,&GPIO_key_InitStructure); //Initializes the gpio according to the specified parameters in the GPIO_key_InitStructure RCC_AHB1PeriphClockCmd(key2_GPIO_CLK, ENABLE); //enable AHB1 periphral clock GPIO_key_InitStructure.GPIO_Pin = key2_pin; GPIO_Init(key2_GPIO_PORT,&GPIO_key_InitStructure); //Initializes the gpio according to the specified parameters in the GPIO_key_InitStructure } /**按键按下标志宏 *按按键按下为高电平,设置KEY_ON = 1 , KEY_OFF = 0 *若按键按下为低电平,设置KEY_ON = 0 , KEY_OFF = 1 即可 */ /** * @brief 检测是否有按键按下 * @param GPIOx:具体的端口,x可以是(A...K) * @param GPIO_PIN:具体的端口位,可以是GPIO_PIN_x(x可以是0...15) * @retval 按键的状态 * @arg KEY_ON :按键按下 * @arg KEY_OFF :按键没按下 */ uint8_t Key_Scan(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin ) { if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON) //Detect whether the key is pressed { while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON); //Loosen the detection return KEY_ON; } else { return KEY_OFF; } }

第一个函数是按键GPIO初始化函数,初始化的流程与LED GPIO 初始化函数 类似,主 要区别是引脚的模式。函数执行流程如下: (1) 使用 GPIO_InitTypeDef 定义 GPIO 初始化结构体变量,以便下面用于存储 GPIO 配置。 (2) 调用库函数 RCC_AHB1PeriphClockCmd 来使能按键的 GPIO 端口时钟。 (3) 向 GPIO初始化结构体赋值,把引脚初始化成浮空输入模式,其中的 GPIO_Pin 使用宏“KEYx_PIN”来赋值,使函数的实现方便移植。由于引脚的默认电平受按键电路影响,所以设置成“浮空/上拉/下拉”模式均没有区别。 (4) 使用以上初始化结构体的配置,调用 GPIO_Init 函数向寄存器写入参数,完成 GPIO的初始化,这里的 GPIO 端口使用“KEYx_GPIO_PORT”宏来赋值,也是为了程序移植方便。 (5) 使用同样的初始化结构体,只修改控制的引脚和端口,初始化其它按键检测时使用的 GPIO引脚

第二个函数是按键扫描函数,在这里我们定义了一个 Key_Scan 函数用于扫描按键状态。GPIO引脚的输入电平可通 过读取 IDR 寄存器对应的数据位来感知,而 STM32 标准库提供了库函数GPIO_ReadInputDataBit 来获取位状态,该函数输入 GPIO端口及引脚号,函数返回该引脚的电平状态,高电平返回 1,低电平返回 0。Key_Scan 函数中以 GPIO_ReadInputDataBit 的返回值与自定义的宏“KEY_ON”对比,若检测到按键按下,则使用 while 循环持续检测按键状态,直到按键释放,按键释放后 Key_Scan函数返回一个“KEY_ON”值;若没有检测到按键按下,则函数直接返回“KEY_OFF”。若按键的硬件没有做消抖处理,需要在这个 Key_Scan函数中做软件滤波,防止波纹抖动引起误触发。

bsp_keyscan.h的代码如下

#ifndef _BSP_KEYSCAN_H #define _BSP_KEYSCAN_H #include "stm32f4xx.h" /*************************引脚定义***********************/ #define key1_pin GPIO_Pin_0 #define key1_GPIO_PORT GPIOA #define key1_GPIO_CLK RCC_AHB1Periph_GPIOA #define key2_pin GPIO_Pin_13 #define key2_GPIO_PORT GPIOC #define key2_GPIO_CLK RCC_AHB1Periph_GPIOC #define KEY_ON 1 #define KEY_OFF 0 void key_GPIO_Config(void); uint8_t Key_Scan(GPIO_TypeDef* GPIOx , uint16_t GPIO_Pin ); #endif

以上代码根据按键的硬件连接,把检测按键输入的 GPIO端口、GPIO引脚号以及GPIO端口时钟封装起来.

主函数代码如下

#include "stm32f4xx.h" #include "bsp_led.h" #include "bsp_keyscan.h" int main (void) { LED_Config(); key_GPIO_Config(); while(1) { if(Key_Scan(key1_GPIO_PORT,key1_pin) == KEY_ON ) { LED_R_Toggle; } if(Key_Scan(key2_GPIO_PORT,key2_pin) == KEY_ON ) { LED_B_Toggle; } } }

编译运行后,按下KEY1则红灯状态改变,按下KEY2蓝灯状态改变一次(led灯的状态改变具体参照:stm32f4固件库函数点亮LED灯)。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有