stm32实现GPIO输入按键检测

发布者:Dingsir1902最新更新时间:2019-02-18 来源: eefocus关键字:stm32  GPIO  输入按键检测 手机看文章 扫描二维码
随时随地手机看文章

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蓝灯状态改变一次

关键字:stm32  GPIO  输入按键检测 引用地址:stm32实现GPIO输入按键检测

上一篇:STM32 的位带操作
下一篇:stm32f4固件库函数点亮LED灯

推荐阅读最新更新时间:2024-03-16 16:24

(一)stm32之CMSIS标准、库目录、GPIO
一、CMSIS标准   ST公司的stm32采用的是cortex-m3内核,内核是整个微处理器的CPU。该内核是ARM公司设计的一种处理器体系架构。内核与外设的关系就像PC上的CPU与硬盘、主板、内存等的关系一样。 基于cortex系列的处理器内核都是一样的,区别在于除内核以外的外设的差异,由于这些差异,导致不同处理器移植起来比较麻烦,所以ARM与芯片厂商建立了CMSIS标准,CMSIS架构如下所示:   CMSIS标准中最主要的是CMSIS核心层;内核函数层中的内核函数寄存器以及地址主要由ARM公司提供;设备外设访问层核外外设和中断寄存器地址由芯片生产厂商定义。 二、库目录和文件简介 1、core_cm3.c文件   在Co
[单片机]
(一)<font color='red'>stm32</font>之CMSIS标准、库目录、<font color='red'>GPIO</font>
STM32系统学习——USART(串口通信)
串口通信是一种设备间非常常用的串行通行方式,其简单便捷,大部分电子设备都支持。 一、物理层 常用RS-232标准,主要规定了信号的用途、通信接口以及信号的电平标准。 “DB9接口”之间通过串口信号线建立起连接,串口信号线使用”RS-232标准“传输数据信号,这些信号通过记过电平转换芯片转换成控制器能识别的TLL标准的电平信号,才能实现通信。 1.电平标准 可分为TTL标准以及RS-232标准。 常见的电子电路中常见TTL的电平标准,理想状态使用5V表示二进制逻辑1,0V表示逻辑0;而为了增加串口通信的远距离传输以及抗干扰能力,RS-232使用-15V表示逻辑1,+15V表示逻辑0。 因为控制器一般使用TTL电平标准
[单片机]
<font color='red'>STM32</font>系统学习——USART(串口通信)
基于stm32做的遥控器源程序(按键和摇杆均有)
按键的话非常简单,定义一个函数,然后可以直接在主函数里实现,要确认好自己的蓝牙就可以,波特率也要一致才行。 int main(void) { delay_init(); LED_Init(); Key_Init(); uart_init(9600); while(1) { keys(); } } 摇杆的话,需要用到ADC算法,下面会分享一个ADC搜集数据的程序然后将搜集的数据加以利用就好了。 如下: void chuli(void ) { u16 x; u16 y; x = Get_Adc_Average(ADC_Channel_1 , 10);
[单片机]
基于STM32单片机的紫外线消毒系统设计
一.系统设计 通过STM32单片机进行主控,通过设置消毒时间来控制消毒,超声波测距模块和光电开关主要起到人体检测作用,当检测达不到人体时才能进行消毒,检测到人即使在上位机端启动消毒,也不会执行消毒。 图1 系统框图 二.硬件设计 本设计所采用的STM32F103C8T6是以Cortex-3为核心的单片机,单片机上普通GPIO即可与HC-SR04超声波模块进行数据收发端进行通信,另外使用DS1302进行消毒定时,通过UART串口实现单片机和ESP8266-01S的通信。 图2 硬件电路 三.软件设计 系统在完成系统初始化后就开始通过传感器进行数据检测,检测到的数据有距离和光电识别信息,上位机端设置距离阈值,当到达消毒时间
[单片机]
基于<font color='red'>STM32</font>单片机的紫外线消毒系统设计
STM32单片机中使用SPI通信的方法
  在本教程中,我们将使用 STM32F103C8 的 Blue Pill 板替换一个 Arduino 板,并将使用 SPI 总线与 Arduino 板进行通信。在这个STM32 SPI 示例中,我们将使用Arduino UNO作为 Slave,STM32F103C8 作为 Master,两个16X2 LCD 显示器分别连接在一起。两个电位器还与STM32(PA0)和Arduino(A0)相连,通过改变电位器来确定主机到从机和从机到主机的发送值(0到255)。   STM32F103C8中的SPI   比较 Arduino 和 STM32F103C8 Blue Pill 板中的 SPI 总线,STM32 有2 条 SPI 总线
[单片机]
在<font color='red'>STM32</font>单片机中使用SPI通信的方法
MSP430FR4133练习(一):GPIO输入电平状态判断
硬件环境:MSP430FR4133 LANCHPAD开发板 软件环境:IARV7.10 For 430 源代码: 1 #include driverlib.h 2 3 void main(void) 4 { 5 //Stop WDT 6 WDT_A_hold(WDT_A_BASE); 7 while(1) 8 { 9 //设置P1.0为输出,接LED 10 GPIO_setAsOutputPin( GPIO_PORT_P1,GPIO_PIN0 ); 11 //设置P4.0为输出,接LED 12 GPIO_setAsOutputPin( GPIO_PORT_P4,GPIO_PI
[单片机]
基于stm32通用定时器设置的学习心得
stm32 单片机的定时器资源相当丰富,它的定时器分为高级控制定时器、通用定时器和基本定时器,具体这些定时器资源在哪个系列的片子有就得看不同的片子的手册了。他们具体有什么区别,我也是刚接触这个,看他的数据手册介绍也是茫然,主要是刚开始摸,那些功能都没用到,反正用做定时作用的话哪种定时器都行。在这我就把我自己配置通用定时器的方法及心得简短做个总结,以防以后忘记了。我配置的是定时器2(TIM2)。 通用 定时器 的时钟可来自于外部或内部,选用默认即是采用内部的。通用定时器的时钟来源为APB1总线,所以首先,得将APB1外设时钟打开。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENAB
[单片机]
基于<font color='red'>stm32</font>通用定时器设置的学习心得
STM32系列里RTC的亚秒特性及功能(下)
我们回到前面提到的需求,每隔50±20ms做唤醒,即30ms~70ms范围内实现唤醒都可以接受。如果说使用ALARM中断,相信很多人自然会想到,先设定一个ALARM点,等唤醒后再修改新的ALARM值,就这样延续下去。 这样操作也是可以的,即每次在ALARM中断里修改新的ALARM时间点。下图是对ALARM值进行编程的流程【设置时先要关闭ALARM,修改ALARM值后再手动开启ALARM单元】: 不过,结合眼前的应用需求,我们可以不使用上面的做法,而是巧妙地使用RTC亚秒特性来实现周期性的ALARM以满足需求。怎么个巧法呢?一起来看看。 先假定RTCCLK为32768Hz,RTC同步分频系数和异步分频系数分别为如下参数:
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved