前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一种你值得学习的按键扫描方式

一种你值得学习的按键扫描方式

作者头像
用户8913398
发布2021-08-16 12:25:21
4350
发布2021-08-16 12:25:21
举报
文章被收录于专栏:嵌入式实验基地

  最近在群里跟小伙伴聊到按键键值的获取方式,提到一种使用状态机的方式,小伙伴有点疑问,小飞哥马上放下饭碗,停止干饭,撸他一个,大神自动飘过...不想飘过的,欢迎批评指导~

实验目标

  • 学会HAL库定时器的配置及使用
  • 状态机法获取键值

软件环境

  • cubemx
  • keil5

硬件环境

  • 能“点灯”的板子
  • 按键4个(我用的是正点原子系列的,4个按键)
  • TFT LCD(可选)

一、cubemx配置

 鉴于本次实验难度不高,也不宜多吹牛x,所以直接干就完事了!

Q&A 什么是状态机?

来源:https://blog.csdn.net/xinghuanmeiying/article/details/81586954

大家可以前去查看该博主,或者百度哈~

1.1 按键配置:

  这是我的硬件连接,小伙伴们根据自己的配置进行,

1.2 定时器3配置

  配置比较简单,就不啰嗦了,不懂的话,欢迎加群,轰炸我~

二、软件代码编写

2.1 定时器相关函数

代码语言:javascript
复制
void TIM3_Init(void)
{
  HAL_TIM_Base_Start_IT(&htim3); //开启定时器中断3,10ms中断周期
}
/* 
定时器中断回调函数
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM3) //定时器中断3发生中断事件
  {
    if (Key_Scan_TimCallBack())
    {
      key_value = Key_Scan_TimCallBack();
    }
  }
}

2.2 按键相关函数

代码语言:javascript
复制

//下面的方式是通过直接操作HAL库函数方式读取IO
#define KEY0 HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin)  //KEY0按键PE4
#define KEY1 HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin)  //KEY1按键PE3
#define KEY2 HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin)  //KEY2按键PE2
#define WK_UP HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) //WKUP按键PA0

#define KEY0_PRES 1
#define KEY1_PRES 2
#define KEY2_PRES 3
#define WKUP_PRES 4



typedef enum 
{
    key_no_Press,   //按键尚未按下
    key_Press,      //按键按下
    key_PressCheck, //按键是否松开
    key_Release     //按键松开
    
}key_status;

/*----------------------------------------------------------------
按键IO状态查询函数
----------------------------------------------------------------*/
uint8_t KEY_Scan(void)
{
    if ((KEY0 == 0 || KEY1 == 0 || KEY2 == 0 || WK_UP == 1))
    {
        if (KEY0 == 0)
            return KEY0_PRES;
        else if (KEY1 == 0)
            return KEY1_PRES;
        else if (KEY2 == 0)
            return KEY2_PRES;
        else if (WK_UP == 1)
            return WKUP_PRES;
    }
    else if (KEY0 == 1 && KEY1 == 1 && KEY2 == 1 && WK_UP == 0)
    return 0; //无按键按下
}

/*----------------------------------------------------------------
定时器中断中调用此函数
----------------------------------------------------------------*/
uint8_t Key_Scan_TimCallBack(void)
{
    static key_status Press_status;
    uint8_t key = 0;
    switch (Press_status)
    {
    case key_no_Press:
        if (KEY_Scan()) //有按键按下
        {
            Press_status++;
            key = 0;
        }
        else
        {
            Press_status = key_no_Press;
            key = 0;
        }
        break;
    case key_Press:
        if (KEY_Scan()) //有按键按下,第一次消抖,仍有按键按下,认为按键有效
        {
            Press_status++;
            key = KEY_Scan();
        }
        break;
    case key_PressCheck:
        if (KEY_Scan()) //有按键按下,仍有按键按下,可做长按键判断,目前仍按照短按键键值处理,可修改
        {
            Press_status++;
            key = KEY_Scan();
        }
        break;
    case key_Release:
        if (KEY_Scan())  //有按键按下,仍有按键按下,可做长按键判断,目前仍按照短按键键值处理,可修改
        {
            Press_status = key_no_Press;
            key = 0;
        }
        break;
    default:
        Press_status = key_no_Press;
        key = 0;
    }
    if (key)
    {
        key_debug_printf("key value is %d\r\n", key);
    }
    return key;
}

2.3 LCD显示相关

本次的介绍就到这里啦,后面有更精彩的内容,欢迎大家持续关注嵌入式实验基地,来这里还可以学习HAL库+cubemx的更多精彩内容哦!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小飞哥玩嵌入式 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实验目标
  • 软件环境
  • 硬件环境
  • 一、cubemx配置
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档