7.最终按键程序

发布日期:2020-12-26 09:10:14 来源:网络转载

1.代码及解析

我们先贴出代码,下面再进行解析原理

u8 KEY_Scan(u8 mode,u16 TIMES)
{  
    static u8 key_up=1; //按键松开标志
    static u16 times;
    if(mode)key_up=1;   //如果mode等于1,支持连按    
    if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))//只要在key_up等于1时,其中一个按键被按下就可以进入执行代码
    {
        times++;        //记录进入低电平的时间
        if(times>=TIMES)//抖动的时间已经过去
        { 
            times=0;
            key_up=0;
            if(KEY4==0)return 4;
            else if(KEY8==0)return 8;
            else if(KEY12==0)return 12;
            else if(KEY16==0)return 16;
        }
    }
    else if(KEY4==1&&KEY8==1&&KEY12==1&&KEY16==1)key_up=1;      
    return 0;// 无按键按下
}

1.假设我们传入的参数mode为0,进入函数,第一次初始化时key_up为1,然后没有去执行“if(mode)key_up=1;”,此时若没有按键按下,则满足

“else if(KEY4==1&&KEY8==1&&KEY12==1&&KEY16==1)key_up=1;”,所以key_up还是等于1,返回值为0。


2.假设有按键按下,持续够一定的低电平时间了(抖动时间过去了),清零times,让key_up等于0,然后判断此时是哪个按键按下就返回对应的值。


3.返回对应的值之后,如果我们一直按着不放,第二次执行这个函数就会因为key_up在前一次函数执行中已经等于0,所以我们就算按着按键不放也进入不了

“if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))”,那么一次按键动作只能有一次返回值为4、8、12或16的机会,其他时候都是返回0。如果我们按键松手了,那就满足

“else if(KEY4==1&&KEY8==1&&KEY12==1&&KEY16==1)key_up=1;”,这样key_up恢复为1了,下次按键动作又能够进入

“if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))”从而可以返回对应的按键值。不支持连按模式就讲解完了。


4.参数mode为1时,总会执行“if(mode)key_up=1;”,所以按键按着不放函数的执行都会进入

“if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))”,这样返回的按键值的机会比不支持连按时候还要多,

这就是mode等于1时呈现的支持连按功能。

原理解析就讲解完了,可以看到,该代码在不支持连按模式下是按下之后就执行返回值了的,而不是像以前一样要抬起按键之后才会执行返回值的语句,所以不管我们的按键手速是快是慢,程序都会在最快时间内去执行返回值的语句。

 

2.补充

我们不再使用“#define TIMES 1000”,因为有时“KEY_Scan()”在各种不同的循环体里扫描返回值,有些循环一次执行时间很快,有些却很慢,我们在第五章已经分析过这些情况了,所以TIMES的值需要随机应变。我们决定让TIMES作为按键程序的第二个参数,这样在某些循环体里如果循环一次的时间很快,我们调为“KEY_Scan(0,1000);”,循环一次的时间很慢就改为“KEY_Scan(0,300);”

 

3.测试代码

#include <reg52.h> 
#include <function.h>
sbit KEY4  = P2^3;
sbit KEY8  = P2^2;
sbit KEY12 = P2^1;
sbit KEY16 = P2^0;
 
u8 KEY_Scan(u8 mode,u16 TIMES)
{  
    static u8 key_up=1; //按键松开标志
    static u16 times;
    if(mode)key_up=1;   //如果mode等于1,支持连按    
    if(key_up&&(KEY4==0||KEY8==0||KEY12==0||KEY16==0))//只要在key_up等于1时,其中一个按键被按下就可以进入执行代码
    {
        times++;        //记录进入低电平的时间
        if(times>=TIMES)//抖动的时间已经过去
        { 
            times=0;
            key_up=0;
            if(KEY4==0)return 4;
            else if(KEY8==0)return 8;
            else if(KEY12==0)return 12;
            else if(KEY16==0)return 16;
        }
    }
    else if(KEY4==1&&KEY8==1&&KEY12==1&&KEY16==1)key_up=1;      
    return 0;// 无按键按下
}
 
void KEY_Init()
{   
    P2=0X7F;//让P2.7输出低电平,其他输出高电平,这样就可以使能4个按键了
}
 
void main()
{  
    u8 key;    //用来读取按键动作的返回值
    LED_Init();//初始化LED硬件模块
    KEY_Init();//初始化按键模块
    P0=0xFE;   //先点亮LED2
    while(1)
    {      
        key=KEY_Scan(0,1000); //不支持连按模式,判断阈值为1000
        if(key==4)LED2=!LED2; //执行功能代码
        if(key==8)LED4=!LED4; //执行功能代码
        if(key==12)LED6=!LED6;//执行功能代码
        if(key==16)LED8=!LED8;//执行功能代码
    }
}

把“KEY_Scan(0,1000);”改为“KEY_Scan(1,1000);”就是支持连按了。

关键词 :
网站违法和不良信息举报邮箱:23139485@qq.com
CopyRight@2020-2030 www.haoapp8.cn All Rights Reserved.C语言学习网版权所有 粤ICP备15061369号
免责声明:本站内容来源于用户自行提供或网络收集,其真实性、准确性和合法性,www.haoapp8.cn不提供任何保证,亦不承担任何法律责任.而产生的法律关系及法律纠纷,由您自行协商解决。