找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3593|回复: 15
收起左侧

请教关于MCU单个按键实现不同次数的点击对应不同功能的处理思想

[复制链接]
ID:258164 发表于 2018-11-29 10:37 | 显示全部楼层 |阅读模式
现在我有一个按键(通过MCU IO口判断电平的),有长按和短按两种方式,现在长短按功能实现了,但是现在我遇到一个新的问题:我这个按键可能需要按1次到多次,然后不同的次数对应不同的功能。因为我现在的短按时间设定的是50ms-2s,在多次检查按键连续短按的时候,请问我该怎么处理,才能保证我可以识别具体按键的次数呢?

具体的实例可以参考现实生活中的电磁炉,菜单键按一次到多次,切换到不同的功能。

希望做过类似功能逻辑的坛友提供点思路,谢谢!
回复

使用道具 举报

ID:94031 发表于 2018-11-29 11:34 | 显示全部楼层
设一个变量存放在一定时间内点击次数,根据这个变量决定程序走向。
回复

使用道具 举报

ID:410399 发表于 2018-11-29 14:20 | 显示全部楼层
设置一个标志号,长按一次加一,标志=1对应一个功能,=2对应一个功能等等,再设置另外一个标志,短按一次加一,同理
回复

使用道具 举报

ID:435739 发表于 2018-11-29 14:48 | 显示全部楼层
设定每次按键间隔时间,统计按键的次数,超时后重新计数
回复

使用道具 举报

ID:424598 发表于 2018-11-29 15:24 来自手机 | 显示全部楼层
如需要实现一个按键5种功能,那就初始变量为0,按一次就+1,然后判断变量的值是多少就执行指定的程序。当累加超过5时,将变量重置为0
回复

使用道具 举报

ID:435828 发表于 2018-11-29 16:06 | 显示全部楼层
呃  如需要实现一个按键5种功能,那就初始变量为0,按一次就+1,然后判断变量的值是多少就执行指定的程序。当累加超过5时,将变量重置为0
回复

使用道具 举报

ID:435826 发表于 2018-11-29 16:29 | 显示全部楼层
短按只需设置防抖时间,程序要做成识别下降沿及上升沿,一个下降沿+一个上升沿为一个按键事件的触发,需不需要设置全局变量记录触发的次数,看你的目的需求是以按下次数表示功能的切换,还是按一次功能响应切换一次,个人建议后者
回复

使用道具 举报

ID:258164 发表于 2018-11-29 16:33 | 显示全部楼层
xuyaqi 发表于 2018-11-29 11:34
设一个变量存放在一定时间内点击次数,根据这个变量决定程序走向。

我的问题不在这,我想问的是:我怎么保证我的第一次短按和第二次 第三次 ...第n次都检测到,因为我的程序还有别的很多功能。
回复

使用道具 举报

ID:258164 发表于 2018-11-29 16:34 | 显示全部楼层
ssk7793 发表于 2018-11-29 15:24
如需要实现一个按键5种功能,那就初始变量为0,按一次就+1,然后判断变量的值是多少就执行指定的程序。当累 ...

这个我知道,但是我的问题不是这个。请看看我对一楼的回复,我的问题所在
回复

使用道具 举报

ID:213173 发表于 2018-11-29 20:48 | 显示全部楼层
给你写一个单键长短按实现多任务的示例程序

#include <REG51.H>
#define uint unsigned int                         //宏定义数据类型uint
#define uchar unsigned char                 //宏定义数据类型uchar
#define key_S 10                                                //宏定义短按(10ms)
#define key_L key_S*100                                //宏定义长按(1s)

sbit key1=P3^7;
//sbit key2=P3^6;
sbit LED1=P1^0;
sbit LED2=P1^2;
sbit LED3=P1^4;
sbit LED4=P1^6;
uchar KeySec=0;
uchar num=0;
void Timer0Init()//1毫秒@12.000MHz
{
        TMOD= 0x01;                //设置定时器模式
        TL0 = 0x18;                //设置定时初值
        TH0 = 0xFC;                //设置定时初值
        TF0 = 0;                        //清除TF0标志
        TR0 = 1;                        //定时器0开始计时
        EA=1;                                //开总中断
        ET0=1;                        //开定时器0中断
}

void keyscan()                                                        //按键扫描
{
        static uint count1=0;                        //计数变量
//        static uint count2=0;                        //计数变量
        if(!key1)   
        {  
                count1++;  
                if(count1==key_L)                                //长按
                        KeySec=4;                                        //输出键值4
                if(count1>key_L)                                //防止count溢出
                        count1=key_L+1;          
        }  
        else                                                                        //按键抬起
        {  
                if(count1>key_S && count1<key_L)//短按
                {                       
                        num++;
                        if(num==4)
                                num=1;
                        KeySec=num;                                        //输出键值num
                }       
                count1=0;                                        //count清0
        }   
/*        if(!key2)   
        {  
                count2++;  
                if(count2==key_L)                                //长按
                        KeySec=4;                                        //输出键值4
                if(count2>key_L)                                //防止count溢出
                        count2=key_L+1;          
        }  
        else                                                                        //按键抬起
        {  
                if(count2>key_S && count2<key_L)//短按
                        KeySec=3;                                        //输出键值3
                        count2=0;                                        //count清0
        }*/   
}

void key_service()                                        //按键服务程序
{
        switch(KeySec)                                                //按键服务状态切换
        {
                case 1:LED1=~LED1;KeySec=0;break;
                case 2:LED2=~LED2;KeySec=0;break;
                case 3:LED3=~LED3;KeySec=0;break;
                case 4:LED4=~LED4;KeySec=0;break;
                default: break;
        }
}

void main()
{
        Timer0Init();                //初始化定时器
        while(1)
        {
                key_service();        //按键服务程序
        }
}
void timer0() interrupt        1//1毫秒@12.000MHz
{
        TL0 = 0x18;                //设置定时重装值
        TH0 = 0xFC;                //设置定时重装值
        keyscan();                //按键扫描程序
}
回复

使用道具 举报

ID:424598 发表于 2018-11-30 07:48 来自手机 | 显示全部楼层
HelloPan111 发表于 2018-11-29 16:34
这个我知道,但是我的问题不是这个。请看看我对一楼的回复,我的问题所在

还是看你变量的应用和判断的写法,如果要区分长按和短按的累计,那就分成二个变量,分别在长按和短按的判断中进行累计
回复

使用道具 举报

ID:258164 发表于 2018-11-30 09:31 | 显示全部楼层
wulin 发表于 2018-11-29 20:48
给你写一个单键长短按实现多任务的示例程序

#include

谢谢,我的长短按程序已经实现了。之前的问题是怎么处理两次短按的间隔问题,不过我自己想到了解决的办法,还是谢谢你的回复
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表