一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 4488|回复: 21
收起左侧

[其他综合] 按键另类处理高效程序V1.0

[复制链接]
发表于 2014-3-1 12:16 | 显示全部楼层 |阅读模式
本帖最后由 sunny20 于 2014-3-1 12:33 编辑

嗨!..大家好,我是SUNNY。本人学51单片机到现在基本是掌握了8成了,打算再过一阵子学习AVRARM了。现在给大家出一套本人自己开发的按键程序,本程序占用资源极低,并且支持长按连续执行。举个例子,如果你在调节分钟,那么长按的话会连续按照150ms的速度连加或者连减。此版本暂时不支持长按短按识别!工作原理:一般的按键处理采用延时避开抖动,并且通过while语句识别弹起,这样在延时就浪费了CPU时间不说,就那个while语句就使程序死了,其他都不执行,并且难以做到长按。本人根据windows键盘原理,采用定时识别法,以150ms扫描一次键盘,如果按键按下就读键值,通过不同的键值处理不同的程序。本人经过多次试验,150ms刚刚好,不但有效避开抖动,而且执行速度刚好在人的识别范围内。本人下面这个例子是两个按键控制两个数码管的数增加或者减少,99最大!不废话,下面是程序:
捕获1.JPG 捕获2.JPG 捕获3.JPG
发表于 2014-3-1 12:37 | 显示全部楼层
我之前有写过单片机做的类似PLC的控制板!用定时器以3.3ms的速度扫描I/O口,当连续比较三次相同则认为确实变化了并设置对应缓存,如果三次不同则认为是干扰,保持原状态,简洁高效,长按检测只需要加入连续比较相同的次数就可以实现了!这种方法基本不会占用CPU太多时间,非常实际,

void time0_prg()  interrupt 1 using 1                          //中断入口1程序   输入I/O扫描
{                                                                                                           //以3.3ms的速度扫描输入I/O,并将数据放入内存缓存区以便后续输入滤波处理
    TH0 = 0x0F3;                                                                            //12M 3.3ms
    TL0 = 0x1C;                                               //设置中断扫描时间
        WDT_CONTR=0x38;                                                                          //喂狗  (3.3ms刷新看们狗)
        key_buffer[nc1+1]=in_put;                                                           //扫描输入
        if(nc1>=2) nc1=0;                                                                   //NC1 计时器 扫描触发时钟
                else nc1++;



void in_scan()                                               //输入滤波 输入抗干扰处理  
{                                                                       //原理:比较每个输入I/O的连续三次高低电位状态当某I/O连续3次数据不同的时候
        uchar n1,n2;                                                                       //则认为是干扰!当连续的某位3次数据相同则认为I/O确实变化了!并输出相应位的变化
        for(n1=0;n1<8;n1++)                                           //比较8个I/O口
        {       
                n2=key_buffer[1]&key_constant[n1];

                if(n2==(key_buffer[2]&key_constant[n1]))
                {
                        if(n2==(key_buffer[3]&key_constant[n1]))
                        {
                                if(n2) in_buffer=in_buffer&~key_constant[n1];         //检测到三次输入相同为0, 则判断输入对应位为0;
                                        else in_buffer=in_buffer|key_constant[n1];         //检测到三次输入相同为1, 则判断输入对应位为1;
                        }
                }
                                                                                                                                                 
        }
}
发表于 2014-3-1 12:39 | 显示全部楼层
灰常支持原创,学习了!
发表于 2014-3-1 12:39 | 显示全部楼层
使用while也可以做到长按和连续执行,在while中增加一个计数值即可,达到某个计数值就返回,下次扫描还会继续进入while,并且可以判断长按和短按。
发表于 2014-3-1 12:44 来自手机 | 显示全部楼层
我上面的代码可以处理多按键组合和多通道io同时虑波,以及长按短按时间计算
发表于 2014-3-1 13:10 | 显示全部楼层
很实用的例子 讨论
发表于 2014-3-1 14:06 | 显示全部楼层
150ms扫描一次  的话间隔太长了,会反应不灵敏的。

一般都是十几二十毫秒一次,判断多次即可(软件分频)
发表于 2014-3-1 15:15 | 显示全部楼层
150ms是不是有点长?楼主用的机械按键所以说可能消抖正好,如果换种按键呢?……
发表于 2014-3-1 15:43 | 显示全部楼层
我的方法与2楼也差不多
一般爱好
定时器用不完   10ms扫按键   多按键取值
进入中断关闭定时器
按下计数   达到x  或者Y  或者z  而且值在几个周期内不在增加判松手   执行



发表于 2014-3-1 16:21 | 显示全部楼层
按键数量少的话用中断也是个不错的选择,示意图:
QQ截图20140301162105.png

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-6-2 05:09 , Processed in 0.070139 second(s), 51 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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