首页 > 其他分享 >07. 按键输入

07. 按键输入

时间:2024-03-01 19:33:18浏览次数:30  
标签:HAL 07 PIN 消抖 按下 按键 GPIO 输入

一、按键简介

  常态下,独立按键是断开的,按下的时候才闭合。每个独立按键会单独占用一个 IO 口,通过 IO 口的高低电平判断按键的状态。但是按键在闭合和断开的时候,都存在抖动现象,即按键在闭合时不会马上就稳定的连接,断开时也不会马上断开。这是机械触点,无法避免。

  按键抖动波形图如下:

按键抖动波形图

  按下抖动和释放抖动的时间一般为 5~10ms,如果在抖动阶段采样,其不稳定状态可能出现一次按键动作被认为是多次按下的情况。为了避免抖动可能带来的误操作,我们要做的措施就是给按键消抖(即采样稳定闭合阶段)。消抖方法分为硬件消抖和软件消抖,我们常用软件的方法消抖。

  软件消抖,最简单的延时消抖。检测到按键按下后,一般进行10ms 延时,用于跳过抖动的时间段,如果消抖效果不好可以调整这个 10ms 延时,因为不同类型的按键抖动时间可能有偏差。待延时过后再检测按键状态,如果没有按下,那我们就判断这是抖动或者干扰造成的;如果还是按下,那么我们就认为这是按键真的按下了。对按键释放的判断同理。

  硬件消抖,利用 RC 电路的电容充放电特性来对抖动产生的电压毛刺进行平滑出来,从而实现消抖,但是成本会更高一点。

二、源码实现

2.1、原理图

K_UP按键

KEY_UP按键引脚接线图

按键模块

按键模块引脚接线图

  K1、K2 和 K3 设计为采样到按键另一端的低电平为有效电平,而 KEY_UP 则需要采样到高电平才为按键有效,并且按键外部没有上下拉电阻,所以需要在 STM32F407 内部设置上下拉。因此,K1、K2 和 K3 配置为 上拉输入,KEY_UP 配置为 下拉输入

2.2、程序源码

  按键初始化函数内容如下:

/**
 * @brief 按键初始化函数
 * 
 */
void Key_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOE_CLK_ENABLE();                                               // 使能GPIOE的时钟

    GPIO_InitStruct.Pin = GPIO_PIN_2;                                           // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;                                     // 输入模式
    GPIO_InitStruct.Pull = GPIO_PULLUP;                                         // 使用上拉
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);                                     // GPIO初始化

    GPIO_InitStruct.Pin = GPIO_PIN_3;                                           // GPIO引脚
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);                                     // GPIO初始化
}

  按键扫描函数内容如下:

/**
 * @brief 按键扫描函数
 * 
 * @return uint8_t 返回0代表按键没有按下,返回1代表按键按下
 */
uint8_t Key_Scan(void)
{
    if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET)                  // 读取GPIO的电平
    {
        HAL_Delay(10);                                                          // 按键消抖
        if (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET)              // 再次读取GPIO的电平
        {
            while (HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_2) == GPIO_PIN_RESET);      // 等待按键释放
            return 1;                                                           // 按键按下返回1
        }
  
    }

    return 0;                                                                   // 按键没有按下返回0 
}

  有关时钟配置函数请在 STM32 的时钟系统 篇章查看。

  有关 LED 配置函数请在 点亮 LED 篇章查看。

  main() 函数内容如下:

int main(void)
{
    HAL_Init();

    System_Clock_Init(8, 336, 2, 7);

    LED_Init();
    Key_Init();

    while (1)
    {
        if (Key_Scan())
        {
            HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);                                  // GPIO电平翻转
        } 
    }
  
    return 0;
}

标签:HAL,07,PIN,消抖,按下,按键,GPIO,输入
From: https://www.cnblogs.com/kurome/p/18047781

相关文章

  • 03按键控制LED
    上回讲到点亮一个LED    这次我们来实现用按键控制led不带中断的方式当然实例来源网络加上自己整合先熟悉流程0.添加一个自己写的驱动库文件    为什么添加笔者想的是一个项目工程希望能适应很多个应用场景需要什么直接在里面调用分装好的函数就行1.如何添加文件......
  • 洛谷题单指南-二分查找与二分答案-P3853 [TJOI2007] 路标设置
    原题链接:https://www.luogu.com.cn/problem/P3853题意解读:相邻路标的最大距离即空旷指数,空旷指数越小,用的路标越多,因此可以根据空旷指数将使用路标情况分成两类:路标数<=K,路标数>K,对空旷指数进行二分即可。解题思路:二分的判定条件为,给定空旷指数,计算需要的路标数只需遍历每两......
  • Android 13接大屏时底下显示任务栏以及虚拟按键靠右问题
    Android13大屏显示时,界面底下显示任务栏,返回、home,recent按键显示会靠右。和Android12类似,但跟以往的Android系统不一样。之前Android12上面修改过这个显示:Android12大屏时底下显示任务栏以及虚拟按键靠右问题_androidtaskbar_HH同学的博客-CSDN博客但是,Android13上面又不......
  • 【蔚来汽车】蔚来20220713第三题-旅游规划
    【蔚来汽车】蔚来20220713第三题-旅游规划牛牛对n个城市旅游情况进行了规划,已知每个城市有两种属性x和y,其中x表示去第i号城市的花费,y表示在第i号城市游玩后会得到的开心值。  现在牛牛希望从中挑选出一些城市去游玩,但挑选出的城市必须满足任意两个城市之间花费差......
  • 【C++】Mat和Pat希望邀请他们的朋友来参加派对。他们要编写一个程序完成下面的任务。
    Mat和Pat希望邀请他们的朋友来参加派对。他们要编写一个程序完成下面的任务。让Mat输入他朋友的姓名列表。姓名存储在一个容器中,然后按排列后的顺序显示出来。让Pat输入她朋友的姓名列表。姓名存储在另一个容器中,然后按排列后的顺序显示出来。创建第三个容器,将两个列表合并,删除重......
  • 假期vue学习笔记07 todo事件的本地存储
     用本地存储改写前面的todo案例 <template>    <li>      <label>        <inputtype="checkbox":checked="todo.done"@change="handleCheck(todo.id)"/>        <spanv-show="!tod......
  • 面试题 02.07. 链表相交C
    利用链表的特性,如果相交的话,后面就不可能岔开!你可以想象把他们有同一个尾巴,然后从尾巴往前看。所以只要知道两个链表的长度,就可以在同一起跑线上一起比较了。/***Definitionforsingly-linkedlist.*structListNode{*intval;*structListNode*next;......
  • P1110 [ZJOI2007] 报表统计 题解
    考察点:STL的熟练运用。记:\(l_i\)表示序列中不超过\(a_i\)的最大数,\(r_i\)表示序列中超过\(a_i\)的最小数。开一个vectorinsert[N]存储\(a_i\)后面插入的所有数字。首先,我们使用一个multisets1来存储相邻元素的差的绝对值,然后再开一个multisets2来存储当前出......
  • 2.07
    <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"......
  • 2024.02.07
    模拟器卸载安装的APP的方法在做安卓的实验时遇到了一个问题需要在模拟器卸载APP,找了网上很多资料发现没有用,于是自己摸索解决了。以Pixel2API29为例1、打开模拟器,点击更多2、点击帮助(Help)3、找到菜单的快捷命令4、退出到原始的模拟器页面,输入对应的快捷键(即,Ctrl+M)出现......