搜索
bottom↓
楼主: zhuhanliang

新型的按键扫描程序,仅三行程序

  [复制链接]

出0入0汤圆

发表于 2015-5-25 16:36:51 | 显示全部楼层
好东西 mark

出0入0汤圆

发表于 2015-5-26 08:31:45 | 显示全部楼层
确实有点新意

出0入0汤圆

发表于 2015-5-26 08:53:37 | 显示全部楼层
好东西,确实不错。

出0入0汤圆

发表于 2015-6-7 23:04:52 | 显示全部楼层
et502 发表于 2010-12-13 16:00
讲到键盘的刁钻设计,~_~ 话说十多年前偶曾检修过一只俄国佬的电控装置,面板有7个按键而背板是3路独立(估 ...

这个可能是用的AD转换,一个管脚就够了。

出0入0汤圆

发表于 2015-6-8 13:57:22 | 显示全部楼层
受教了,确实巧妙

出0入4汤圆

发表于 2015-6-9 16:37:12 | 显示全部楼层
有点意思,按键状态机才是王道

出0入0汤圆

发表于 2015-6-9 17:21:14 | 显示全部楼层
N年前就已经看过了

出0入0汤圆

发表于 2015-6-13 20:02:28 | 显示全部楼层
学习受教了,谢谢     mark         

出0入0汤圆

发表于 2015-6-27 08:30:09 | 显示全部楼层
本帖最后由 单飞 于 2015-6-27 08:31 编辑

51版的这里有:
在写按键处理函数时最常用的应该是延时去抖吧,顶多在加上个按键等待什么的,这个写法非常传统也用的比较普遍,但是相较而言它执行效率不高比较浪费时钟周期,那有没有一个执行效率比较高占用时钟周期短的写法呢?亲,这个是有的!
     这个也是我在网上无意间看到的,感觉比较有用就分享给大家。分享之前先说明这个写法比较有意义的几个方面:第一,执行效率比较高占用时钟周期少;第二,可以方便实现单按跟常按按键的功能;第三,自己发现。。。。。。。。
    核心部分:
     unsigned char Trg,Cont;  //Trg触发有效,Cont连续有效
     void keyread(void)
    {
         unsigned char ReadData = P1IN^0XFF;   //读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来
         Trg = ReadData&(ReadData^Cont);       //用来计算触发变量的
         Cont = ReadData;                                 //用来计算连续变量

     }

(1)       没有按键的时候
                P1IN = 0XFF;
                ReadData = 0;
                Trg = 0;
                Cont = 0;

(2)       第一次PB0按下的情况
                P1IN = 0XF7;     //这里用的是P1.3端口
                ReadData = 0X08;
                Trg = 0X08;
                Cont = 0X08;

(3)       PB0按着不松(长按键)的情况
                P1IN = 0XF7;     //这里用的是P1.3端口
                ReadData = 0X08;
                Trg = 0;
                Cont = 0X08;

(4)       按键松开的情况
                P1IN = 0XF7;     //这里用的是P1.3端口
                ReadData = 0;
                Trg = 0;
                Cont = 0;
  看到这应该差不多明白了吧。那就举个例子验证一下:

   程序中最开始用的延时去抖的写法没有删掉,想让大家看着比较一下两种写法

#include
unsigned char Trg,Cont;  //Trg触发有效,Con连续有效

void keyread(void)
{
    unsigned char ReadData = P1IN^0XFF;
    Trg = ReadData&(ReadData^Cont);
    Cont = ReadData;

}

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR = 0X41;           //设置P1.6、P1.6输出

  P1OUT = 0X09;          //点亮LED1,并设置P1.3上拉
  P1REN = 0X08;          //设置P1.3上使能,代替硬件上拉电阻

while(1)
{
   keyread();
   if(Trg&0x08)
   {
        P1OUT^= 0X41;
   }
//    if(!(P1IN&0X08))
//    {
//        __delay_cycles(50000);    //延时去抖
//        if(!(P1IN&0X08))
//        {
//            while(!(P1IN&0X08)); //释放有效
//            
//                P1OUT^= 0X41;   //LED取反
//            
//            
//        }
//    }
//
}
}


  看完这个程序或许感觉这种写法没什么,都不如延时去抖写着方便,其实节约时钟中期这点你不能否认,那就让我们看看它很能干什么,在举一个长按效果的程序.

    if (Cont & 0x08) // 如果“加”按键被按着不放
    {
         cnt_plus++;       // 计时
         if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到
         {
              Func();      // 你需要的执行的程序
         }           
    }

但是最后我发现,它根本解决不了按键抖动问题。。。
http://blog.sina.com.cn/s/blog_a00aafb40101dxtu.html

出0入0汤圆

发表于 2015-6-27 11:31:15 | 显示全部楼层
N年前已经发的资料,又拿出来炒

出0入0汤圆

发表于 2015-6-30 20:41:13 | 显示全部楼层
学习了,谢谢

出0入0汤圆

发表于 2015-7-1 00:35:01 | 显示全部楼层
收藏收藏收藏收藏

出0入0汤圆

发表于 2015-7-1 14:07:33 | 显示全部楼层
真是经典的按键处理方法

出0入0汤圆

发表于 2015-7-4 13:39:20 | 显示全部楼层
收藏了。。。

出0入0汤圆

发表于 2015-7-31 11:25:05 | 显示全部楼层
三行按键程序 mark

出0入0汤圆

发表于 2015-7-31 16:00:11 | 显示全部楼层
make~~~~~~

出0入0汤圆

发表于 2015-8-1 22:05:19 | 显示全部楼层
果然好经典

出0入0汤圆

发表于 2015-8-1 23:07:48 | 显示全部楼层
好东西,mark,谢谢楼主

出0入0汤圆

发表于 2015-8-1 23:08:52 | 显示全部楼层
很好的东西,谢谢

出0入0汤圆

发表于 2015-8-2 19:01:45 | 显示全部楼层
单飞 发表于 2015-6-27 08:30
51版的这里有:
在写按键处理函数时最常用的应该是延时去抖吧,顶多在加上个按键等待什么的,这个写法非常传 ...

可以消抖,稍微修改即可。注意按键消抖和释放这么长的时间工程上一般是不允许软件延时的

出0入0汤圆

发表于 2015-8-5 16:18:16 | 显示全部楼层
顶一个123456789

出0入0汤圆

发表于 2015-8-5 20:14:32 | 显示全部楼层
zxq6 发表于 2010-10-8 13:56
真的有那么神奇?

张工,你试过的哦?

出0入0汤圆

发表于 2015-8-5 21:37:27 | 显示全部楼层
老帖了,没想到今天又见到了。东西很实用的说。

出0入0汤圆

发表于 2015-8-6 09:53:06 | 显示全部楼层
mark,回头试试

出0入0汤圆

发表于 2015-8-6 11:23:46 | 显示全部楼层
嗯,有点意思。

出0入0汤圆

发表于 2015-8-6 16:27:39 | 显示全部楼层
Mark, 按键处理。谢谢lz分享

出0入0汤圆

发表于 2015-8-7 01:26:02 | 显示全部楼层
看起来不错

出0入0汤圆

发表于 2015-8-7 08:10:43 | 显示全部楼层
收藏研究,多谢楼主

出0入0汤圆

发表于 2015-8-7 08:37:24 | 显示全部楼层
作为菜鸟,感觉受益匪浅,谢谢楼主无私分享

出0入0汤圆

发表于 2015-8-7 08:38:37 | 显示全部楼层
没有搞过按键扫描,mark留待以后

出0入0汤圆

发表于 2015-8-7 18:12:26 | 显示全部楼层
佩服 细读中

出0入0汤圆

发表于 2015-8-12 13:50:24 | 显示全部楼层
这个要好好学习学习啊!!!

出0入0汤圆

发表于 2015-8-12 19:24:51 | 显示全部楼层
牛人啊,受教了

出0入42汤圆

发表于 2015-8-12 20:40:45 | 显示全部楼层
非常好,很简洁、高效,谢谢分享

出0入0汤圆

发表于 2015-8-13 09:23:44 | 显示全部楼层
此贴必顶

出0入0汤圆

发表于 2015-8-14 17:19:06 | 显示全部楼层
MARK`````````````````

出0入4汤圆

发表于 2015-8-14 22:15:47 | 显示全部楼层
经典~!!!!!!!!!!!!!!!!!!!!!!!

出0入0汤圆

发表于 2015-8-18 15:32:52 | 显示全部楼层
思路很巧妙啊!学习了

出0入0汤圆

发表于 2015-8-19 09:21:17 | 显示全部楼层
这个算法只能处理 常态为1,触发态为0的情况吧?也就是只能加上拉电阻,触发时置0的情况才能用吧?我用下拉电阻,触发时置1的情况推算貌似结果不对啊

出0入0汤圆

发表于 2015-8-19 17:15:22 | 显示全部楼层
像这种程序我一般只管调用,验证。没问题直接用,有问题在排查问题。

出0入0汤圆

发表于 2015-8-30 09:48:41 | 显示全部楼层
不错,好办法。

出0入0汤圆

发表于 2015-9-4 18:04:48 | 显示全部楼层
神与小丑 发表于 2015-8-19 09:21
这个算法只能处理 常态为1,触发态为0的情况吧?也就是只能加上拉电阻,触发时置0的情况才能用吧?我用下拉 ...


unsigned char ReadData = P1IN^0XFF;   //这条语句其实是异或求反
可以改成  
unsigned char ReadData = ~P1IN;//按下为0的情况
如果是按下为1的情况则为
unsigned char ReadData = P1IN;//按下为1的情况
这样理解比较简单

出0入0汤圆

发表于 2015-9-4 18:35:52 | 显示全部楼层
若要再进一步化简的话...
由于A^B=A & ~B + ~ A & B; A & A=A;A & ~A=0所以ReadData & (ReadData ^ Cont)=ReadData & (~ReadData & Cont+ReadData & ~Cont)=ReadData & ~ReadData & Cont+ReadData & ReadData & ~Cont=ReadData & ~Cont
于是就可以化简得
unsigned char Trg=0;
unsigned char Cont=0;
void KeyRead( void )
{
    unsigned char ReadData = ~PINB;  // 1
    Trg   = ReadData & ~Cont;             // 2;注~优先级高于& ;ReadData为本次键状态,Cont为上次键状态
    Cont = ReadData;                        // 3
}
不知有没有错误,没有实际验证

出0入0汤圆

发表于 2015-9-7 23:19:12 | 显示全部楼层
key scan three line code

出0入0汤圆

发表于 2015-9-10 09:14:59 | 显示全部楼层
mark一下

出0入0汤圆

发表于 2015-9-10 13:17:38 | 显示全部楼层
感谢楼主  写的很精彩  已实际应用 学习了

出0入0汤圆

发表于 2015-9-23 22:14:39 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2015-10-12 23:35:45 | 显示全部楼层
这个很牛叉......

出0入0汤圆

发表于 2015-10-13 11:10:38 | 显示全部楼层
受教了啊~

出0入8汤圆

发表于 2015-10-13 15:01:37 | 显示全部楼层
从楼主发帖就一直在用这种方式结合状态机做按键处理,非常好用!

出0入0汤圆

发表于 2015-10-24 21:38:29 | 显示全部楼层
ndt2000 发表于 2010-10-8 23:19
回复【25楼】linghu2 令狐二中
----------------------------------------------------------------------- ...

域名解析错误哦!!!

出0入0汤圆

发表于 2015-10-30 10:19:36 | 显示全部楼层
学习了   收藏

出0入0汤圆

发表于 2015-10-30 10:48:47 | 显示全部楼层
这个不错!!!下次用

出0入0汤圆

发表于 2015-10-30 12:07:28 | 显示全部楼层
这么厉害?我回头试一下看看。不过还是要感谢一下你的分享。

出0入0汤圆

发表于 2015-11-2 14:45:02 | 显示全部楼层
6666666666666666

出0入0汤圆

发表于 2015-11-3 18:28:42 | 显示全部楼层
mark, 学习了

出0入0汤圆

发表于 2015-11-3 18:33:31 | 显示全部楼层
人按键最快75ms

出0入0汤圆

发表于 2015-11-7 19:03:04 | 显示全部楼层
ndt2000 发表于 2010-10-8 23:19
回复【25楼】linghu2 令狐二中
----------------------------------------------------------------------- ...

那个链接打不开   能重新给一个吗

出0入0汤圆

发表于 2015-11-7 19:05:26 | 显示全部楼层
楼主,这个能用于矩阵键盘吗

出0入0汤圆

发表于 2015-12-6 00:50:55 | 显示全部楼层
回头细读

出0入0汤圆

发表于 2015-12-6 22:47:50 | 显示全部楼层
ndt2000 发表于 2010-10-8 23:19
回复【25楼】linghu2 令狐二中
----------------------------------------------------------------------- ...

打不开网页

出0入4汤圆

发表于 2015-12-21 22:06:31 | 显示全部楼层
mark!!!!!!!!!!!!

出0入0汤圆

发表于 2015-12-22 09:25:57 | 显示全部楼层
mark               

出0入0汤圆

发表于 2015-12-22 11:24:46 | 显示全部楼层
先记号一下,慢慢研究

出0入0汤圆

发表于 2015-12-22 21:17:50 | 显示全部楼层
记录一下

出0入0汤圆

发表于 2015-12-23 15:47:50 | 显示全部楼层
mark,学习学习

出0入0汤圆

发表于 2015-12-24 11:53:42 | 显示全部楼层
原来有人发过,就是利用按键按下时各种状态特性,达到按键读取的信息

出0入0汤圆

发表于 2016-1-2 22:53:55 | 显示全部楼层
        好东西,学习学习

出0入0汤圆

发表于 2016-1-3 15:06:18 | 显示全部楼层
思路应该来自于硬件描述语言,比如vhdl:
if rising_edge(clk) and clk='1'

实际并没有那么大作用。个人认为软件防抖才是关键。另外矩阵扫描也不能这么做。

出0入0汤圆

发表于 2016-1-3 17:27:59 | 显示全部楼层
本帖最后由 rain73 于 2016-1-3 17:29 编辑
runapp 发表于 2016-1-3 15:06
思路应该来自于硬件描述语言,比如vhdl:
if rising_edge(clk) and clk='1'


我前一段时间研究过,已经成功解决防抖问题,可进行任意次采样,应该是比较完美的解决方案了。
另外也解决了用于矩阵键盘上的简单方法,只是没有发上来。
看该贴的36楼:
http://www.amobbs.com/thread-5635315-1-1.html

出0入0汤圆

发表于 2016-4-5 09:15:27 | 显示全部楼层
好思路,不过还是喜欢之前的定时扫描

出0入0汤圆

发表于 2016-4-5 09:44:03 | 显示全部楼层
Mark 神奇的按键程序

出0入0汤圆

发表于 2016-4-5 11:10:18 | 显示全部楼层
可以试着用用看。

出0入0汤圆

发表于 2016-4-9 14:38:28 | 显示全部楼层
精品就是精品。。不会随时间而隐没!

出0入0汤圆

发表于 2016-4-9 15:40:48 | 显示全部楼层
经典老帖

出0入0汤圆

发表于 2016-4-10 12:30:45 | 显示全部楼层
很好的资料,学习了

出0入0汤圆

发表于 2016-4-15 18:15:37 | 显示全部楼层
刚翻到这,挖一下坟

出0入0汤圆

发表于 2016-4-16 12:44:37 | 显示全部楼层
学习了

出140入115汤圆

发表于 2016-4-16 14:55:43 | 显示全部楼层
mark ,字数补丁

出0入10汤圆

发表于 2016-4-19 11:14:48 | 显示全部楼层
受教了,非常感谢!

出0入0汤圆

发表于 2016-4-20 17:59:02 | 显示全部楼层
原理很简单,楼主分享出来了应该都能看懂。谢谢分享,只是那个防抖处理不是很好操作。还得加一段程序,也就不止3行了。

出0入0汤圆

发表于 2016-4-25 22:04:10 | 显示全部楼层
顶,谢谢分享

出0入0汤圆

发表于 2016-4-26 15:41:38 | 显示全部楼层
学习了!

出0入0汤圆

发表于 2016-4-26 18:34:50 | 显示全部楼层
MARK,有时间仔细看看

出0入0汤圆

发表于 2016-4-26 19:01:45 | 显示全部楼层
如果没mark过,就再mark一次吧

出0入0汤圆

发表于 2016-4-28 17:24:43 | 显示全部楼层
程序精简 好用 不错 学习了

出0入0汤圆

发表于 2016-5-5 14:07:29 | 显示全部楼层
好方法,学习了!

出0入0汤圆

发表于 2016-5-5 16:05:04 | 显示全部楼层
其实就是一简单的状态机,然后通过程序主程序循环时间来作为消抖,思路还是挺巧妙的,^_^
我按键检测是用中断控制的

出0入0汤圆

发表于 2016-5-5 16:46:30 | 显示全部楼层
MARK 学习         

出0入0汤圆

发表于 2016-5-5 17:43:22 | 显示全部楼层
不觉得有多神奇啊!

出0入0汤圆

发表于 2016-5-7 15:21:07 | 显示全部楼层
这么好的帖子,必须mark下!!!

出0入0汤圆

发表于 2016-6-8 09:58:38 | 显示全部楼层
这样的代码出现在我们公司, 直接扔掉

出0入0汤圆

发表于 2016-6-12 09:58:40 | 显示全部楼层
在公司的产品上看到类似的按键扫描程序

出0入0汤圆

发表于 2016-8-5 17:02:24 | 显示全部楼层
谢谢分享~

出0入0汤圆

发表于 2016-9-14 09:11:36 | 显示全部楼层
收藏收藏

出0入0汤圆

发表于 2016-9-21 14:35:43 | 显示全部楼层
牛人

出0入0汤圆

发表于 2016-9-21 16:32:17 | 显示全部楼层
想要的时候找了半天没找到,感觉收藏

出190入0汤圆

发表于 2016-9-28 10:48:00 | 显示全部楼层
这种方法的出处:
《Embedded Systems Dictionary》page 71

uint8_t
debounce(uint8_t current)
{
static uint8_t asserted = 0x00;
static uint8_t previous = 0x00;
/*
* Compare the current and previous states of each input.
*/
asserted |= (previous & current); // Assert newly "on" inputs.
asserted &= (previous | current); // Clear newly "off" inputs.
/*
* Update the history.
*/
previous = current;
/*
* Return the debounced inputs to the caller.
*/
return (asserted);
} /* debounce() */

出0入10汤圆

发表于 2016-9-28 13:28:01 | 显示全部楼层
过段时间正打算做一个玩的,看来可以用用这个:)

出0入0汤圆

发表于 2016-10-10 09:07:39 | 显示全部楼层
谢谢。。。非常不错哦!!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 12:32

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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