STM32(二):按键 (标准库函数)

这篇具有很好参考价值的文章主要介绍了STM32(二):按键 (标准库函数)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

上一篇文章已经介绍了如何实现流水灯,实现了点灯的第一步。这一篇则介绍按键控制点灯的实现过程。

一、实验原理

1.GPIO输操作说明

按键的初始化与LED灯初始化不同,LED是推挽输出,而按键则是输入。而输入也分两种:上拉输入和下拉输入。若是按键为共阴极,则按键按下时,IO口输入为低电平,需要在IO口接上拉电阻,则使用上拉输入模式;若是按键为共阳极,则按键按下时,IO口输入为高电平,需要在IO口接下拉电阻,则使用下拉输入模式。

其余根据板子的实际情况选择定时器,选择IO口即可。

二、实验步骤

1.按键消抖

因为按键是机械开关,在按下的时候会产生电平的抖动。可以采用延时消抖的方法,通过延时一小段时间,消除抖动。当然除了软件消抖还有硬件消抖的方法,可以看下下面这个链接【单片机】按键消抖及原理(硬件和软件方法详解)-CSDN博客

按键s1、s2 的gpio初始化配置函数 key_init();,STM32,stm32,嵌入式硬件,单片机

if(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
{
  /* 延时一小段时间,消除抖动 */
  Delay(10);
  /* 延时时间后再来判断按键状态,如果还是按下状态说明按键确实被按下 */
  if(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
  {
    /* 等待按键弹开才退出按键扫描函数 */
    while(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL){ }
      /* 按键扫描完毕,返回按键被按下状态 */
        return KEY_DOWN;
   }
}
  /* 按键没被按下,返回没被按下状态 */
  return KEY_UP;

2.长短按

为了检测按下时间的长短,可以采取延时计数的方法。通过引入时间计数的KeyTimeCount,在按键扫描的时候以延时多少时间,增大KeyTimeCount。最后自定义判断时间长短。

值得注意的是,要是想检测按下的时间更为精确,需要调整延时函数,且针对不同单片机的定时器有不同的频率,需要根据实际情况自行调整。

uint16_t KeyTimeCount = 0;

/* 等待按键弹开才退出按键扫描函数 */
while(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
{
    /* 时间计数 */
	Delay(10);
    KeyTimeCount = KeyTimeCount + 1;  
}

   /* 按键扫描完毕,返回按键被按下状态 */
if (KeyTimeCount <= 99)   // 小于等于1s
{
	/* 计数清零 */
	KeyTimeCount = 0;  
	return KEY_DOWN;   // 短按状态
}
else if (KeyTimeCount >= 199)   // 大于等于2s
{
	/* 计数清零 */
	KeyTimeCount = 0; 
	return KEY_DOWN_LONG;   // 长按状态
}

3.联合点灯

按键部署完后,就是一个联合点灯的过程,将bsp_led.h引入到bsp_key.c便可以通过按键实现点灯了!(其实是灭灯)

void KEY_LED(void)
{
	/* 读取按键状态 */
	int key1State = KEYx_Choice(1);
	
   /* 短按按键1 */
	if (key1State == 1)
	{
		LED1_OFF;
	}
}

三、实操代码

程序分为3个文件:bsp_key.c、bsp_key.h、main.c

1.bsp_key.c

/* 包含头文件 ----------------------------------------------------------------*/
#include "bsp/key/bsp_key.h"

void KEY_GPIO_Init(void)
{
   /* 定义IO硬件初始化结构体变量 */
  GPIO_InitTypeDef GPIO_InitStructure;
        
   /* 使能(开启)KEY引脚对应IO端口时钟 */   
  RCC_APB2PeriphClockCmd(KEY1_RCC_CLOCKGPIO|KEY2_RCC_CLOCKGPIO|KEY3_RCC_CLOCKGPIO, ENABLE);
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  /* 设定KEY对应引脚IO编号 */
  GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN |KEY2_GPIO_PIN | KEY3_GPIO_PIN;
  /* 配置KEY GPIO:输入上拉模式 */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(KEY3_GPIO, &GPIO_InitStructure);
  GPIO_Init(KEY1_GPIO, &GPIO_InitStructure);
  GPIO_Init(KEY2_GPIO, &GPIO_InitStructure);

}

/**
  * 函数功能: 读取按键KEYx的状态
  * 输入参数:无
  * 返 回 值: KEY_UP  :按键没被按下;
  *           KEY_DOWN:按键被按下;
  *           KEY_DOWN_LONG  :按键被长按下
  * 说    明:无。
  */
	
KEYState_TypeDef KEYx_StateSet(GPIO_TypeDef* KEYx_GPIO, uint16_t KEYx_GPIO_PIN, uint8_t KEYx_DOWN_LEVEL)
{	
  uint16_t KeyTimeCount = 0;  
  if(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
  {
    /* 延时一小段时间,消除抖动 */
    Delay(10);
    /* 延时时间后再来判断按键状态,如果还是按下状态说明按键确实被按下 */
    if(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
    {
      /* 等待按键弹开才退出按键扫描函数 */
      while(GPIO_ReadInputDataBit(KEYx_GPIO, KEYx_GPIO_PIN)==KEYx_DOWN_LEVEL)
	  {
		  /* 时间计数 */
		  Delay(10);
		  KeyTimeCount = KeyTimeCount + 1;  
	  }
	 }
       /* 按键扫描完毕,返回按键被按下状态 */
		if (KeyTimeCount <= 99)   // 小于等于1s
		{
			 /* 计数清零 */
			KeyTimeCount = 0;  
			return KEY_DOWN;   // 短按状态
		}
		else if (KeyTimeCount >= 199)   // 大于等于2s
		{
			 /* 计数清零 */
			KeyTimeCount = 0; 
			return KEY_DOWN_LONG;   // 长按状态
		}
    
  }
  /* 按键没被按下,返回没被按下状态 */
  return KEY_UP;
}

/**
  * 函数功能: 选取按键KEYx
  * 输入参数:1 :按键1;
  *          2 :按键2;
  *          3 :按键3
  * 返 回 值: KEYx_StateSet(KEYx_GPIO, KEYx_GPIO_PIN, KEYx_DOWN_LEVEL)
  * 说    明:无。
  */
KEYState_TypeDef KEYx_Choice(int KEYIndex)
{
    switch(KEYIndex)
    {
        case 1:
            return KEYx_StateSet(KEY1_GPIO, KEY1_GPIO_PIN, KEY1_DOWN_LEVEL);
        case 2:
            return KEYx_StateSet(KEY2_GPIO, KEY2_GPIO_PIN, KEY2_DOWN_LEVEL);
		  case 3:
            return KEYx_StateSet(KEY3_GPIO, KEY3_GPIO_PIN, KEY3_DOWN_LEVEL);
        default:
            return KEY_UP; 
    }
}

/**
  * 函数功能: 按键KEYx控制LED
  * 输入参数:无
  * 返 回 值:LED1_OFF:1灯灭;
  *          LED2_OFF:2灯灭;
  *          LED3_OFF:3灯灭
  * 说    明:无。
  */
void KEY_LED(void)
{
	/* 读取按键状态 */
	int key1State = KEYx_Choice(1);
	int key2State = KEYx_Choice(2);
	int key3State = KEYx_Choice(3);
	
   /* 短按按键1 */
	if (key1State == 1)
	{
		LED1_OFF;
	}
	 /* 长按按键1 */
	else if (key1State == 2)
	{
		LED3_OFF;
	}

	else if (key2State == 1)
	{
		LED2_OFF;
	}
	else if (key2State == 2)
	{
		LED3_OFF;
	}

	else if (key3State == 1)
	{
		LED3_OFF;
	}
	else
	{
		LED1_ON;
		LED2_ON;
		LED3_ON;
	}
}

2.bsp_key.h

#ifndef __BSP_KEY_H__
#define __BSP_KEY_H__

/* 包含头文件 ----------------------------------------------------------------*/
#include <stm32f10x.h>
#include "bsp/delay/delay.h"
#include "bsp/led/bsp_led.h"

/* 类型定义 --------------------------------------------------------------*/
typedef enum
{
  KEY_UP   = 0,
  KEY_DOWN = 1,
  KEY_DOWN_LONG   = 2,
}KEYState_TypeDef;

/* 宏定义 --------------------------------------------------------------------*/
#define KEY1                          (uint8_t)0x01
#define KEY2                          (uint8_t)0x02
#define KEY3                          (uint8_t)0x04
#define IS_KEY_TYPEDEF(KEY)           (((KEY) == KEY1) || ((KEY) == KEY2) || ((KEY) == KEY3))

/* 宏定义 --------------------------------------------------------------------*/
#define KEY1_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY1_GPIO_PIN                 GPIO_Pin_7
#define KEY1_GPIO                     GPIOE
#define KEY1_DOWN_LEVEL               0  /* 根据原理图设计,KEY1按下时引脚为低电平,所以这里设置为0 */


#define KEY2_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY2_GPIO_PIN                 GPIO_Pin_8
#define KEY2_GPIO                     GPIOE
#define KEY2_DOWN_LEVEL               0  /* 根据原理图设计,KEY2按下时引脚为低电平,所以这里设置为0 */


#define KEY3_RCC_CLOCKGPIO            RCC_APB2Periph_GPIOE
#define KEY3_GPIO_PIN                 GPIO_Pin_9
#define KEY3_GPIO                     GPIOE
#define KEY3_DOWN_LEVEL               0  /* 根据原理图设计,KEY3按下时引脚为低电平,所以这里设置为0 */

/* 扩展变量 ------------------------------------------------------------------*/
/* 函数声明 ------------------------------------------------------------------*/
void KEY_GPIO_Init(void);
KEYState_TypeDef KEYx_StateSet(GPIO_TypeDef* KEYx_GPIO, uint16_t KEYx_GPIO_PIN, uint8_t KEYx_DOWN_LEVEL);
KEYState_TypeDef KEYx_Choice(int KEYIndex);
void KEY_LED(void);

#endif  // __BSP_KEY_H__

3.main.c

这边值得注意的是延时函数需要配置文件,也可以将上一篇的延时函数直接放入main.c和bsp_key.c中

STM32(一):流水灯 (标准库函数)-CSDN博客

/* 包含头文件 ----------------------------------------------------------------*/
#include "stm32f10x.h"
#include "bsp/led/bsp_led.h"
#include "bsp/key/bsp_key.h"
#include "bsp/delay/delay.h"


/* 函数体 --------------------------------------------------------------------*/

/**
  * 函数功能: 主函数.
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 无
  */
int main(void)
{

    /* 初始化 */
	LED_GPIO_Init();
	KEY_GPIO_Init();
  while (1)
  {
//	/* 流水灯 */
//   LED_Turn();
//   Delay(100);
	  
	/* 按键控制LED */
	KEY_LED();
	Delay(100);

  }
}

四、实验效果

按键点灯

结束语

本文以STM32VET6为例讲解了一种按键长按和短按点灯的实现方法,当然,这只是其中一种方法,实现的方式其实还是很多。
如果还有什么问题,欢迎评论区留言,谢谢!文章来源地址https://www.toymoban.com/news/detail-861655.html

到了这里,关于STM32(二):按键 (标准库函数)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【物联网】详解STM32的GPIO八种输入输出模式,GPIO各种输入输出的区别、初始化的步骤详解,看这文章就行了(超详细)

    在STM32微控制器中,常见的输入输出(GPIO)模式有八种,分别是推挽输出、开漏输出、复用推挽输出、复用开漏输出、浮空输入、上拉输入、下拉输入和模拟输入。下面我将为你解释每种模式的特点和区别,并提供相应的示例代码。 推挽输出(Push-Pull Output):推挽输出模式是最常

    2024年02月14日
    浏览(40)
  • 【开篇】STM32F103C8T6 含义、命名规则、GPIO原理以及初始化(参考男神江科协,学习交流用)

    目录 目录 一,STM系列命名规则 二.引脚功能 三.电路以及寄存器 1.产品系列:         STM32代表意法半导体的Cortex-Mx系列内核(ARM)32位的MCU 2.产品类型: F-通用型,S-简单型,L-低功耗,H-高性能,AL-汽车应用低功耗型,AF-汽车应用通用型。 3.产品子系列: 103:ARM Cortex-M3内核

    2024年01月17日
    浏览(71)
  • STM32 hal库 NVIC初始化函数梳理

    使用的是stm32f407vg,代码来源stm32cubemx。 已经配置了中断的是GPIOD_pin6和TIM2。  这个是STM32CubeMX里面NVIC的控制面板;其中最上面priority grope是优先级组,我设置的是4位抢占优先级,0位响应优先级,就和以前刚学中断时中断嵌套那样。 下面是有哪些中断源,勾上之后,在最下面

    2024年01月18日
    浏览(41)
  • STM32(二):按键 (标准库函数)

    前言 上一篇文章已经介绍了如何实现流水灯,实现了点灯的第一步。这一篇则介绍按键控制点灯的实现过程。 按键的初始化与LED灯初始化不同,LED是推挽输出,而按键则是输入。而输入也分两种:上拉输入和下拉输入。若是按键为共阴极,则按键按下时,IO口输入为低电平,

    2024年04月29日
    浏览(17)
  • stm32 hal库 RCC初始化函数SystemClock_Config()梳理分析、初步细致学习(一)

    目录 一、PLL主时钟初始化 1.1 时钟使能  1.2 配置好主时钟配置结构体 1.3 将配置好的值写入到对应的寄存器、初始化PLL主时钟; 1.3.1 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct-HSEState)分析:  1.3.2 给PLL相关寄存器赋值: 二、外设时钟初始化 2.1等待周期的验证和写入; 2.2 HCLK配置 2.3 SYSC

    2024年02月15日
    浏览(33)
  • STM32 GPIO输入检测——按键

    在嵌入式系统开发中,对GPIO输入进行检测是一项常见且关键的任务。STM32微控制器作为一款功能强大的处理器,具有丰富的GPIO功能,可以轻松实现对外部信号的检测和处理。在本文中,我们将深入探讨如何在STM32微控制器上进行GPIO输入检测,并介绍两种常见的方法:轮询检测

    2024年04月10日
    浏览(29)
  • STM32 cubemx CAN STM32 CAN初始化详解

    接收用到的结构体如下: CAN概念:         全称Controller Area Network,是一种半双工,异步通讯。 物理层:         闭环:允许总线最长40m,最高速1Mbps,规定总线两端各有一个120Ω电阻,闭环        开环:最大传输距离1Km,最高速125Kbps,规定每根线串联一个2.2kΩ的电阻,

    2024年02月13日
    浏览(42)
  • STM32各外设初始化步骤

            1、使能GPIO时钟         2、初始化GPIO的输入/输出模式         3、设置GPIO的输出值或获取GPIO的输入值         1、使能EXTI线所在的GPIO时钟和AFIO复用时钟         2、初始化EXTI线所在的GPIO的输入输出模式         3、将GPIO脚映射到对应的EXTI线上         4、设置

    2024年03月25日
    浏览(46)
  • GPIO(STM32)点亮LED灯、按键KEY

    GPIO(general porpose intputoutput):通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能。 在STM32F4xx芯片上的GPIO口被分成各个组,一共有7组IO口,以A、B、C、D、E、F、G等命名(不同

    2024年04月14日
    浏览(29)
  • STM32CubeMX教程3 GPIO输入 - 按键响应

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 使用STM32CubeMX软件配置STM32F407开发板的按键作为输入,利用按键输入使LED灯产生响应 对于所有的GPIO来说都是既可以作为输出引脚也可以作为输入引脚使用,本开发板上有一个用户按键,

    2024年02月03日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包