OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 16455|回复: 9

独立键盘扫描程序,带松手检测,可区别长击与短击

[复制链接]

19

主题

248

帖子

2

精华

高级会员

Rank: 4

积分
842
金钱
842
注册时间
2012-2-8
在线时间
19 小时
发表于 2012-6-10 18:54:11 | 显示全部楼层 |阅读模式
      花了一个星期写出来的,四个按键的独立键盘扫描程序。可以区别长击和短击,同时采用计数方式来消抖。按下键一定时间内,松手后返回对应值;按下键超过一定时间,返回对应值。短击的返回值是在松手后才产生,长击则是超过时间就产生,长击松手后不会返回短击的值。

u8 Key_Scan(void)
{
 u8 key_ret = 0;
 static u8 key_num = 0,del_count,tim_count;
 static bit key_flag = 0;
 if((!SET)||(!KUP)||(!KDN)||(!KOK)){/*判断是否有键按下*/
  if(++del_count==5){/*计数消抖*/
   del_count = 0;
   if(++tim_count>4){/*长按识别*/
    key_flag = 0;/*短按无效*/
    tim_count = 4;/*锁定长按*/
    switch(key_num){
     case 1:key_ret = 5;break;
     case 2:key_ret = 6;break;
     case 3:key_ret = 7;break;
     case 4:key_ret = 8;break;
    } 
   }
   else{/*短按有效*/
    key_flag = 1;/*短按标志位*/
    if(!SET)key_num = 1;/*一下用于识别按键*/
    if(!KUP)key_num = 2;
    if(!KDN)key_num = 3;
    if(!KOK)key_num = 4;
   }
  } 
 }else{/*松手之后*/
  tim_count = 0;
  if(key_flag){/*松手*/
   key_flag = 0;
   switch(key_num){
    case 1:key_ret = 1;break;
    case 2:key_ret = 2;break;
    case 3:key_ret = 3;break;
    case 4:key_ret = 4;break;    
   }
  }
 }
 return key_ret;
}

不过感觉程序还有地方可以改进。贴出来跟大家一起讨论。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

15

主题

138

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
227
金钱
227
注册时间
2012-8-10
在线时间
2 小时
发表于 2012-8-16 20:58:05 | 显示全部楼层
用实验板的例程就可以改了哈,我就调试成功了4*3(也就是手机键盘),带松手检测,带滑动检测等。。
学海无涯,回头是岸
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2012-6-10 19:20:07 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

19

主题

248

帖子

2

精华

高级会员

Rank: 4

积分
842
金钱
842
注册时间
2012-2-8
在线时间
19 小时
 楼主| 发表于 2012-6-10 20:18:27 | 显示全部楼层
原子哥,指点一下啊
回复 支持 反对

使用道具 举报

3

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
61
金钱
61
注册时间
2012-8-1
在线时间
0 小时
发表于 2012-8-2 13:21:48 | 显示全部楼层
不错不错,收藏了
为我们吹过的NB奋斗终身
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
22
金钱
22
注册时间
2012-8-13
在线时间
0 小时
发表于 2012-8-13 17:01:36 | 显示全部楼层
早就在做这个实验了,就是总出问题,用楼主的试试哈,
回复 支持 反对

使用道具 举报

20

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
151
金钱
151
注册时间
2012-8-13
在线时间
0 小时
发表于 2012-8-17 13:39:21 | 显示全部楼层
楼主好厉害
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
353
金钱
353
注册时间
2012-3-11
在线时间
48 小时
发表于 2014-4-3 13:15:16 | 显示全部楼层
回去测试一下看看
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

5

主题

33

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2014-3-16
在线时间
4 小时
发表于 2014-4-10 22:12:47 | 显示全部楼层
嗯,看起来不错,有没有写过矩形键盘的呢,我谢了个2行5个按键的键盘,还望赐教;
另外问一下松手检测是什么意思,是松手后再执行函数吗?
#include<reg51.h>
#include"delay/delay.h"
#define uchar unsigned char
#define uint unsigned int

sbit led_1 = P2^0;
sbit led_2 = P2^1;
sbit led_0 = P2^2;

sbit line1 = P3^3;
sbit line2 = P3^4;

uchar table_key[2][3]={{0xF6,0xF5,0xF3},{0xEE,0xED}}; //按键码

void keyscan(void)
{
#define f_longkey 30000

uchar i=0;
uint key_time=0;
//=================Line1=======================================
line2 = 1;
line1 = 0;
for(i=0;i<3;i++)
{
if((P3 |table_key[0])==table_key[0])
{
delayms(10);
if((P3 |table_key[0])==table_key[0])  
{
while(((P3 |table_key[0])==table_key[0]) && (++key_time<f_longkey)); //等待释放
if(key_time<f_longkey) //短按
{
if(i==0)   //按键0
{
led_1=0;
}
else if(i==1)   //按键1
{
led_2=0;
}
else if(i==2)  //按键2
{
led_0=1;
led_1=1;
led_2=1;
}
while((P3 |table_key[0])==table_key[0]);   //等待释放
}
else //长按
{
if(i==0)
{
led_2=0;
}
else if(i==1)
{
led_0=0;
}
else if(i==2)
{
led_2=1;
led_1=1;
led_0=1;
}  
while((P3 |table_key[0])==table_key[0]);   //等待释放
}

}
}
}
//===============line2=====================================================


    line2 = 0;
line1 = 1;
key_time = 0;

for(i=0;i<2;i++)
{
 
if((P3 |table_key[1])==table_key[1])
{
delayms(10);
if((P3 |table_key[1])==table_key[1])
{
while(((P3 |table_key[1])==table_key[1]) && (++key_time<f_longkey)); //等待释放
if(key_time<f_longkey)//短按
{
if(i==0)   //按键0
{
led_0=1;
}
else if(i==1)   //按键1
{
led_0=0;
}
while((P3 |table_key[1])==table_key[1]);   //等待释放
}
else //长按
{
if(i==0)   //按键0
{
led_2=1;
led_1=1;
led_0=1;
}
else if(i==1) //按键1
{
led_2=0;
led_1=0;
led_0=0;
}  
while((P3 |table_key[1])==table_key[1]);   //等待释放
}
}
}
}

}

void main()
{
init_delay();
while(1)
{
keyscan();
}



}

QQ截图20140410220916.png
回复 支持 反对

使用道具 举报

7

主题

50

帖子

0

精华

初级会员

Rank: 2

积分
100
金钱
100
注册时间
2014-6-14
在线时间
1 小时
发表于 2015-6-17 22:23:12 | 显示全部楼层
留个记号,明天白天测试一下,正需要这个程序
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 09:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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