多个按键识别出短按、双击、长按的一种简单方案

本文分享了一种在嵌入式系统中使用有限的按键实现多种功能的策略,包括短按、双击和长按的识别。通过分析客户需求,作者面临将14个按键功能压缩到3个按键上的挑战。通过借鉴网上的按键识别程序,成功实现了按键状态的高效利用,简化了硬件设计。文章详细介绍了如何初始化按键、检测按键状态以及在定时器中断中处理按键事件。
摘要由CSDN通过智能技术生成

        几个普通按键实现复杂的功能在现在的嵌入式系统中应用非常常见,一方面是为了考虑到硬件平台的大小,毕竟现在的东西越来越小巧(功能相同的情况下越小越显得高逼格);另一方面是按键太多会影响平台的美观性和适用性,毕竟要是一个平台上面有一大堆按键会加大工作人员学习难度,在这种情况下很容易发生误操作。

        最近在忙一个网上接的小项目,做着做着客户提了许多新功能,但麻烦的事当初画板子的时候没有考虑到这些(是我的原因,在画板之前没有考虑周全)。项目原来只需要控制继电器按照设定的时间通断,然后提示本次是否有错误,想着挺简单的就接了。结果做着做着客户居然还要能保存和读取测量错误的数据,顿时给我懵逼了。

        数据存储的话就需要用到存储器,还好芯片有自带的EEPROM,可以把数据存在这里面。麻烦的是如何控制把存进去的错误数据读出来。按照最初的要求我只设置了两个拨码开关负责通道的通断,普通按键只有三个负责修改时间和循环次数。普通按键三个分别实现:当前位选数值+1、当前位选数值-1、当前位选向左移位。至于调整的那个通道就看拨码开关哪个是打开的状态(这里双通道都打开不能识别反而不执行任何动作)。

        把更新后的要求仔细分析了一下发现如果一个按键一个功能的话需要用到14个普通按键(具体功能如下):

按键一 通道一时间参数修改;
按键二 通道一循环次数参数修改;
按键三 读取通道一当前次数存储的的错误数据;
按键四 读取通道一所有存储的的错误数据;
按键五 清除通道一存储的数据;
按键六 通道二时间参数修改;
按键七 通道二循环次数参数修改;
按键八 读取通道二当前次数存储的的错误数据;
按键九 读取通道二所有存储的的错误数据;
按键十 清除通道二存储的数据;
按键十一 数码管位选移位;
按键十二 数码管位选数值+1;
按键十三 数码管位选数值-1;
按键十四 已修改的参数保存;

 很明显不可能用这么多的按键,14个按键看着都头晕,只得另寻他法。在网上看了一篇如何实现按键单击、双击、长按的帖子上面还有详细的程序和注释(链接如下:单片机按键识别篇---单击---双击----长按 - 一切都会好 - 博客园)。顿时发现我的这14个功能都不是是个事,一个按键三个状态,三个按键就可以组合成27个状态,这对于我这点需求不是轻而易举。

        至于如何实现单按键识别三种状态网上有很多,基本都是差不多的原理,我这里

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现按键按和短按功能可以通过软件延时和计时器实现。下面是一个示例代码,演示如何实现按键按和短按功能: ```C++ const int buttonPin = 2; // 按钮接口 int buttonState = HIGH; // 按钮状态 int lastButtonState = HIGH; // 上一次按钮状态 unsigned long lastDebounceTime = 0; // 上一次抖动时间 const int debounceDelay = 50; // 抖动延时 const int longPressDelay = 1000; // 按延时 bool longPress = false; // 是否按 unsigned long pressStartTime; // 按下按键开始计时 unsigned long pressEndTime; // 释放按键结束计时 void setup() { pinMode(buttonPin, INPUT_PULLUP); // 初始化按键接口 Serial.begin(9600); // 初始化串口通信 } void loop() { int reading = digitalRead(buttonPin); // 读取按钮状态 if (reading != lastButtonState) { // 抖动检测 lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { // 按钮状态改变 buttonState = reading; if (buttonState == LOW) { // 按钮按下 pressStartTime = millis(); } else { // 按钮释放 pressEndTime = millis(); longPress = false; if ((pressEndTime - pressStartTime) > longPressDelay) { // 按 longPress = true; Serial.println("Long press!"); } else { // 短按 Serial.println("Short press!"); } } } } lastButtonState = reading; } ``` 这个代码使用 `digitalRead()` 函数读取按钮状态,并使用 `millis()` 函数计时。在按钮按下时,记录下按键开始计时的时间,当按钮释放时,记录下按键结束计时的时间,并计算按键持续时间,如果持续时间超过设定的按延时,则判断为按。如果持续时间小于按延时,则判断为短按
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值