搜索
bottom↓
回复: 24

发一个厉害的4*4矩阵按键去抖扫描程序

[复制链接]

出0入0汤圆

发表于 2012-1-29 16:25:27 | 显示全部楼层 |阅读模式
先说明,此方法是之前我一个老师给我的,但是当时是单个按键的程序,我把它改成了矩阵按键的程序。

这个程序特别不好理解,但是特别巧妙。

实现的功能是,按键松开有效,换句话说,你按下不会触发,当你松开后才回触发,完美去抖。


此程序基于mage128单片机  

/ *******************************************************/
/ ****** 16*16矩阵按键扫描程序头文件——2010.8.16 追雪***/
/ *******************************************************/
/ *******************************************************/
/ ******   key_scan_0(void)     按键判断 松开有效  ******/
/ ******   uchar key_scan(void) 返回按键号1~16     ******/
/ *******************************************************/
#define key_board  PINC           //按键I/0口
#define key_num    0xf0           //提取有用位系数

static unsigned char key_release=0;
unsigned char key=0xf0;//没有任何按键按下的时候P1.3/1.4/1.5都是1,是初始值。我们只关心P1.3/1.4/1.5,不关心别的引脚。
/ *******************************************************/
/ ******   函数名称: key_scan_0(void)              ******/
/ ******   功    能: 按键判断松开有效             ******/
/ ******   参    数: 无                            ******/
/ ******   返 回 值: 无                            ******/
/ *******************************************************/
void key_scan_0(void)//按键松开才认为是有效按键
{
unsigned char key1,key2;
key1=key_board;
key1&=key_num;
delay_nus(200);
key2=key_board;
key2&=key_num;

if(key1!=key2) return;

if((key1==key)) //按键扫描结果和上次相同,可能是没有按键,也有可能是同一个按键
{
return;
}
else //按键扫描结果与上次不同
  if(key1==key_num) {key_release=1;}//按键松开
  else //有按键按下
  {
  key_release=0;
  key=key1;
  }
}
/ *******************************************************/
/ ******   函数名称: unsigned char key_scan(void)  ******/
/ ******   功    能: 返回按键号1~16                ******/
/ ******   参    数: 无                            ******/
/ ******   返 回 值: unsigned char                 ******/
/ *******************************************************/
unsigned char key_scan(void)
{
unsigned char key1=0,i;

PORTC=0xff;
for(i=0;i<=3;i++)
  {
   PORTC&=~(1<<i);
   key_scan_0();
   if(key_release)
   {
    switch(key)
    {
     case 0xe0:{key1=1+4*i;key=0xf0;key_release=0;return key1;}
     case 0xd0:{key1=2+4*i;key=0xf0;key_release=0;return key1;}
     case 0xb0:{key1=3+4*i;key=0xf0;key_release=0;return key1;}  
     case 0x70:{key1=4+4*i;key=0xf0;key_release=0;return key1;}
     default  :{key1=0;key=0xf0;key_release=0;break;}
    }
   }
  }
return key1;
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-12-6 23:20:55 | 显示全部楼层
mark!!!!

出0入76汤圆

发表于 2012-12-6 23:58:35 | 显示全部楼层
没发现厉害之处 ....

出0入264汤圆

发表于 2012-12-7 00:23:55 来自手机 | 显示全部楼层
看楼主文字,""特别不好理解,但是特别巧妙""差点被唬住了,看完程序,才发现楼主在唬人。程序一般般,没什么出彩的地方。

出0入0汤圆

发表于 2012-12-14 21:46:12 来自手机 | 显示全部楼层
路过,学习一下

出0入0汤圆

发表于 2012-12-14 21:52:43 | 显示全部楼层
别丢人了

出0入0汤圆

发表于 2012-12-14 22:00:24 | 显示全部楼层
mark,学习一下!!!

出0入0汤圆

发表于 2012-12-14 22:16:39 | 显示全部楼层
看看,看看

出0入0汤圆

发表于 2012-12-14 22:48:26 | 显示全部楼层
程序一般,我自己写的都可以计算长短按下时间了。。。。。。。比你的强得多

出0入0汤圆

发表于 2013-4-10 19:51:51 | 显示全部楼层
看评论就不想看了!!!!!!!!!!

出0入0汤圆

发表于 2013-8-8 15:32:04 | 显示全部楼层
学习学习

出0入10汤圆

发表于 2014-7-3 09:00:39 | 显示全部楼层
这样子信息量也减少了,你无法实现长按,组合按键等功能

出0入0汤圆

发表于 2014-7-3 09:06:30 | 显示全部楼层
楼主的程序很简单一般吧,我自己用的基于状态扫描的,支持消抖,支持单击按下,单击抬起,单击长按,单击长按抬起,持续长按等多种按键状态,可定制长按或者持续按的时间等,什么时候有空了整理下放论坛。

出0入0汤圆

发表于 2014-7-3 09:07:21 来自手机 | 显示全部楼层
delay_nus(200);     巧妙?完美?

出0入0汤圆

发表于 2014-9-3 14:13:52 | 显示全部楼层
重新定义了“巧妙”


出0入0汤圆

发表于 2014-9-3 14:22:12 | 显示全部楼层
程序质量一般,很常规的写法

出0入0汤圆

发表于 2014-9-3 15:49:43 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2014-9-3 16:29:47 | 显示全部楼层
楼主被回帖打击了一下

出0入0汤圆

发表于 2014-9-3 17:03:46 | 显示全部楼层
不错,够短的,只是给新手看就蛋蛋的忧伤了

出0入0汤圆

发表于 2014-9-3 22:16:30 | 显示全部楼层
很早前也这样写的
unsigned char scan(void)                       
{
        unsigned char k, i;
        k=0xff;  
          for(i=0;i<=3;i++)
          {
                KEYB = ~(0x01 <<i);//行扫描低4位        1111 1110
                delay(10);
                switch(KEYB & 0xf0)//列读取高4位        xxxx nnnn                                       
                {
                        case 0xe0: k = 0+(i <<2);break;        //在第1列有按键 加上偏移量
                          case 0xd0: k = 1+(i <<2);break;        //在第2列有按键
                          case 0xb0: k = 2+(i <<2);break;        //在第3列有按键
                          case 0x70: k = 3+(i <<2);break;        //在第4列有按键
                          default:   k = 0xff;    break;        //该行按键无效或无按键
                }
                if(k <= 0x0f) break;//已扫描到有效按键
          }
        return k;
}

出0入0汤圆

发表于 2014-9-3 22:37:29 | 显示全部楼层
路过学习

出0入0汤圆

发表于 2014-10-11 14:41:38 | 显示全部楼层
学习借鉴!

出0入0汤圆

发表于 2014-10-11 14:43:19 | 显示全部楼层
进来学习下,刚开始学编程

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-8-26 09:16

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

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