09. 按键输入

发布时间 2023-07-31 19:33:30作者: 夏冰翎

一、按键简介

  按键是一种电子开关,使用时轻轻按开关按钮就可使开关接通,当松开手时,开关断开。

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

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

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

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

二、原理图

img

img

img

三、程序设计

  按键初始化程序:

void Key_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
  
    __HAL_RCC_GPIOE_CLK_ENABLE();                   // 使能GPIOE的时钟

    GPIO_InitStruct.Pin = GPIO_PIN_2;               // 选择GPIOE的引脚
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;         // 设置为输入模式
    GPIO_InitStruct.Pull = GPIO_PULLUP;             // 使用上拉
    HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);         // GPIO初始化函数
}

如果要使用 KEY_UP,则需要将 GPIO 的模式设置 下拉输入(GPIO_PULLDOWN);

如果使用 K1、K2 和 K3,则需要将 GPIO 的模式设置为 上拉输入(GPIO_PULLUP);

  按键扫描函数:

uint8_t Key_Scanner()
{
    if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == GPIO_PIN_RESET)               // 读取按键接口的电平
    {  
        HAL_Delay(10);                                                      // 延迟消抖
        if (HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == GPIO_PIN_RESET)           // 再次读取按键接口的电平
        {  
            while(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) == GPIO_PIN_RESET);    // 等待按键释放
            return 1;                                                       // 返回1代表按键按下
        }
    }
    return 0;                                                               // 返回0代表按键没有按下
}

如果要使用 KEY_UP,需要将 KEY_UP 所连接的引脚读取的电平与 GPIO_PIN_SET(高电平)作比较;

如果使用 K1、K2 和 K3,则需要将 K1、K2 和 K3 所连接的引脚读取的电平与 GPIO_PIN_RESET(低电平)作比较;

  LED 初始化函数 请在 点亮 LED 篇章查看;

  main() 函数:

int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  Key_Init();
  
  while (1)
  {
    if(Key_Scanner() == 1)
    {
      HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);
    }
  }
}