历史上的今天
返回首页

历史上的今天

今天是:2025年08月21日(星期四)

正在发生

2021年08月21日 | 51单片机-最终按键程序

2021-08-21 来源:eefocus

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  

#include

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);”就是支持连按了。

推荐阅读

史海拾趣

益升华(Essentra)公司的发展小趣事

益升华(Essentra)公司深知客户是企业发展的基石。因此,公司始终将客户服务放在首位,致力于为客户提供优质的产品和服务。公司建立了完善的客户服务体系,为客户提供从产品咨询、选购、安装到售后维护的全流程服务。同时,公司还积极开展客户回访和满意度调查活动,及时了解客户需求和反馈意见,不断改进产品和服务质量。这些努力使益升华(Essentra)公司赢得了客户的广泛赞誉和信任。

Amphenol Aerospace公司的发展小趣事

为了提高生产效率和降低成本,益升华(Essentra)公司不断优化供应链。公司与多家优质供应商建立了长期稳定的合作关系,确保原材料的质量和供应的稳定性。同时,公司还引入先进的生产设备和工艺,提高生产自动化水平,降低人工成本。此外,益升华(Essentra)公司还建立了完善的物流体系,确保产品能够及时送达客户手中。这些措施的实施,使公司的竞争力得到了显著提升。

华润微(CRMICRO)公司的发展小趣事

2020年,华润微成功在科创板上市,开启了公司发展的新篇章。上市以来,华润微充分利用资本市场的力量,不断扩大生产规模,提升技术水平。在科创板挂牌上市的推动下,公司业绩实现了快速增长。2022年,公司营收突破百亿大关,净利润达到26亿元,较2019年增长5.5倍。这一成绩的取得,充分展示了华润微在电子行业中的强大实力和竞争力。

ENPIRION公司的发展小趣事

在电源管理领域,ENPIRION公司不断面临各种技术挑战。例如,如何满足企业级、工业级、通信等市场对产品的高可靠性要求?如何提供最优的电源转换率以降低成本和散热?为了应对这些挑战,ENPIRION公司不断投入研发力量,推出了一系列创新的电源管理解决方案。这些解决方案不仅满足了市场的需求,还进一步巩固了ENPIRION公司在电源管理领域的领先地位。

ELMEC Technology Of America Inc公司的发展小趣事

在ELMEC Technology Of America Inc公司初创时期,创始人李明和他的团队面临着一个巨大的挑战:如何开发一款能在市场上脱颖而出的电子产品。经过无数次的实验和失败,他们最终成功研发了一款高效能、低功耗的半导体芯片。这款芯片的问世不仅为公司带来了第一笔可观的收入,也奠定了ELMEC在电子行业的技术领先地位。

Astro Industries Inc公司的发展小趣事

随着产品的热销,Astro Industries Inc开始积极寻求市场拓展的机会。公司加强了与各大销售渠道的合作,通过线上线下相结合的方式,将产品推向更广阔的市场。同时,公司也注重品牌建设,通过统一的品牌形象和宣传策略,提升了品牌知名度和美誉度。这些举措使得Astro Industries Inc在电子行业中逐渐崭露头角。

问答坊 | AI 解惑

变频器发生短路的原因及其解决方法

变压器短路事故情况 其事故主要表现形式为:       1) 外部多次短路冲击,线圈变形逐渐严重,最终绝缘击穿损坏居多;       2) 外部短时内频繁受短路冲击而损坏;       3) 长时 ...…

查看全部问答>

台湾清云科技大学TMS320C54X中文课件

台湾清云科技大学TMS320C54X中文课件…

查看全部问答>

430AD模块

本帖最后由 paulhyde 于 2014-9-15 04:16 编辑 超好用、超全面的AD底层程序,有了它,AD操作随心所欲!  …

查看全部问答>

发短信请假的童鞋们,想过老板的感受吗

春节回家,一位自己开公司的朋友聊起来,说也不知道现在的小孩是怎么回事,雇的一个小女孩请假从来都是用短信。而且比如说今天9点上班,她就8点45发短信给你,说要请假,弄得你一点儿办法都没有。跟她说过几次,还是这样。不过看着这小女孩平时做事 ...…

查看全部问答>

具体谈谈中国LED和国外LED封装的差异之六------------LED核心技术性能的差异!!!

LED器的性能核心指标主要表现在如下六方面 1亮度或流明值;2光衰;3失效率;4光效;5一致性;6光学分布特性 2、光衰 一般研究认为,光衰与芯片关联度不大,与封装材料与工艺关联度最大。影响光衰的封装材料主要有固晶底胶、荧光胶、外封胶等,影响 ...…

查看全部问答>

AIGaN/GaN H EMT功率放大器设计

在小信号 参数不适于微波功率放大器的设计而大信号 参数不易获得的情况下,利用ADS软件,采用负载牵引法和输入端共轭匹配, 成功的设计出A1GaN/GaN HEMT微波功率放大器。为了解决晶体管端口出现负阻的问题,设计了输入输出端并联电阻和反馈网络两 ...…

查看全部问答>

关于我的e2world的生活臆断

准确的来讲,在“eeworld”里,我就是一位freshman,因为刚进来不久。看到这里面有这么多高手,还能下载那么多难能可贵的资料,我甚是欣喜.在这个电子行业里, 我还是一只菜鸟(或许菜鸟都谈不上)。想想自己都已经大三了,虽然对嵌入式系统很是感 ...…

查看全部问答>

使用STC12C5410AD产生可调占空比PWM问题

//使用stc12c5410ad输出PWM波形,系统时钟用27MHz,输出的PWM固定频率是8.7kHz,可调占空比 #include\"stc12c5410ad.h\"#define uchar unsigned char#define uint unsigned intuchar table[]={0xac,0x80,0x03,0x03,0x80,0xac};//占空比 void main ...…

查看全部问答>

upsd内部sram数据保存问题

如题,PC2脚接一电池,掉电情况下电池的电压下降得比较快(芯片功耗很大),当电压下降到低于2v时,就会丢数据了。哪位大哥了解的说一下啊…

查看全部问答>

做一个运放,把0832的电流输出转化为电压输出

各位,我想做一个运放,把0832的电流输出转化为电压输出,谁能提供点资料,我做了几个都不理想,用的是op07…

查看全部问答>