OpenEdv-开源电子网

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

新型独立按键扫描程序,申明不是原创,感觉很好用,与大家共享一下。大家的独立按键要是有高效的方法,不防也来讨论讨论

[复制链接]

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
发表于 2012-10-21 17:26:47 | 显示全部楼层 |阅读模式
说明:3个独立按键分别接stm32的PB10, PB11和 PB12
具体原理请参照: http://www.amobbs.com/thread-4308630-1-1.html  
下面是自己移植的,不足之处,希望各位指点:


#define KEY12 0x10   //安照八位单片机来算,对独立按键的信号端进行宏定义 ,方便后面检测用(PB10, B11和 B12就按PB2, B3和 B4来定义)
#define KEY11 0x08    //也可以按照实际来定义,但KeyRead(void) 函数需要做适当修改
#define KEY10 0x04
unsigned char KEY_Trg; //扫描按键用(单击一次用) 全局变量
unsigned char KEY_Count;//扫描按键(长按用)用全局变量
unsigned char ms;//毫秒计数器 全局变量 
unsigned char t;// 表示长按按键的时间 =t*扫描时间?这里有个疑问,这个变量应该申明位全局还是局部?测试了一下都可以
void KeyRead(void) //按键扫描函数
{
    unsigned char ReadData ;
unsigned int temp; //若按键接的是IO口的高8位,需要定义一个缓冲区
//ReadData=((GPIOB->IDR^0xff)); //若按键接的是低8位的话,用这一句话就行,下面3句不需要
        temp=GPIOB->IDR&0xff00;// 若按键接的是IO口的高8位 使用 ;GPIOB->IDR不能写,需要定义一个缓冲区
temp>>=8;  // 若按键接的是IO口的高8位 使用
        ReadData=temp^0xff; // 若按键接的是IO口的高8位高8位用
    KEY_Trg = ReadData & (ReadData ^ KEY_Count);      // 2
    KEY_Count = ReadData;                            // 3
}
void KeyProcess(void)
{
    if((KEY_Trg & KEY10))//短按
                {do something}
    else if((KEY_Trg & KEY11))
                {do something} 
    else if((KEY_Trg & KEY12))
                {do something} 
    if(( KEY_Count  & KEY10))//长按
    {
        t++;    
        if(t>30)  //根据需要修改长安时间  
        {
        t=0;
        {do something} 
        }
    }
}
void main(void)
{

if(ms>80)//主程序每隔80ms去扫描一次按键
{
ms =0; 
KeyRead() ;
KeyProcess() ;
}
else {do something}

}

stm32的初始化配置就省啦,相信大家都会拉










这辈子只会两件事:这也不会,那也不会!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-10-21 21:24:24 | 显示全部楼层
回复 支持 反对

使用道具 举报

50

主题

207

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
427
金钱
427
注册时间
2012-7-21
在线时间
0 小时
发表于 2012-10-21 21:59:07 | 显示全部楼层
回复【楼主位】hkys_lxh:
---------------------------------
状态机嘛。马潮老师的书有说过
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2012-10-21 22:09:27 | 显示全部楼层
具体也不知道这个方法叫啥。以前都是呆呆的延时20毫秒,偶然发现了这个帖子,就移植了一下。不用延时了,效率提高了。教学课本上从来没见过这玩意,如果还有人用传统的延时,不妨试试这个思路
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

6

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2012-10-19
在线时间
0 小时
发表于 2013-3-21 17:22:13 | 显示全部楼层
if((KEY_Trg & KEY10))//短按
                {do something}
    else if((KEY_Trg & KEY11))
                {do something} 
    else if((KEY_Trg & KEY12))
                {do something} 
当这个时候刚刚有一个脉冲(干扰脉冲)来的话,会不会误动作!那怎么解决?我想了很久。。。。
没什么歌星
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-21 21:48:36 | 显示全部楼层
回复【5楼】wuguobo5439:
---------------------------------
测试下先!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2013-3-22 21:43:50 | 显示全部楼层
在一些项目中,按键少的话,都用这种方式。具体原理还没搞透,看原帖能增加理解
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
28
金钱
28
注册时间
2013-4-2
在线时间
1 小时
发表于 2013-4-2 16:42:14 | 显示全部楼层
回复【楼主位】hkys_lxh:
---------------------------------
你好 在吗?
回复 支持 反对

使用道具 举报

25

主题

683

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1351
金钱
1351
注册时间
2012-4-25
在线时间
195 小时
发表于 2013-4-5 17:20:09 | 显示全部楼层
两个 状态 变量, 利用的就是  C中的 异或操作,相同为 0,不同为 1,其中一个保存 上次的状态量,就是这么个原理。
1-1
回复 支持 反对

使用道具 举报

96

主题

762

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1228
金钱
1228
注册时间
2012-10-19
在线时间
15 小时
发表于 2013-4-6 11:13:11 | 显示全部楼层
void KEY_Scan(void)
{  
    static u8 keytemp=0;
static u16 key_count=0;   
if(KEY0==0||KEY1==0)

if(key_count<200) 
{
if(KEY0==0)  keytemp=1;
if(KEY1==0)  keytemp=2;
}
else if(key_count==200)
{  
if(KEY0==0)  keynum=3;
if(KEY1==0)  keynum=4;
keytemp=3;
}
key_count++;
}
else if(KEY0==1&&KEY1==1)
{
    if(key_count>1)
{
if(keytemp!=3)  keynum=keytemp;
key_count=0;
}    
}      
}
一样的原理~,如果加其他功能 长按,同时按,真的很方便
回复 支持 反对

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
69
金钱
69
注册时间
2013-3-24
在线时间
3 小时
发表于 2013-6-1 15:17:15 | 显示全部楼层
好神奇的按键 去抖动一流。看了很久都不是很明白,自己写一遍就懂了
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-6-2 11:12:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2013-7-20 07:27:02 | 显示全部楼层
1秒以上 每100毫秒连发一次  一秒发10次 ,是个什么意思,不太明白,望楼上说的再详细一点,正好在测试菜单结构,用到按键,顺便再测试一下你这个“游戏手柄”玩意
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2013-7-20 07:27:53 | 显示全部楼层
回复【12楼】xouou_53320:
---------------------------------
1秒以上 每100毫秒连发一次  一秒发10次 ,是个什么意思,不太明白,望您说的再详细一点,正好在测试菜单结构,用到按键,顺便再测试一下你这个“游戏手柄”玩意
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

头像被屏蔽

6168

主题

7036

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
19705
金钱
19705
注册时间
2012-12-27
在线时间
25 小时
发表于 2013-7-20 10:01:19 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

6

主题

35

帖子

1

精华

中级会员

Rank: 3Rank: 3

积分
421
金钱
421
注册时间
2014-4-1
在线时间
11 小时
发表于 2014-4-1 15:11:15 | 显示全部楼层
不错
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2014-4-2 09:56:01 | 显示全部楼层
有一小问题,这种方法,“长按操作”会执行“一次短按动作”,这个问题暂时还没解决
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

19

主题

248

帖子

2

精华

高级会员

Rank: 4

积分
842
金钱
842
注册时间
2012-2-8
在线时间
19 小时
发表于 2014-4-2 21:42:59 | 显示全部楼层
回复 支持 反对

使用道具 举报

69

主题

269

帖子

0

精华

高级会员

Rank: 4

积分
977
金钱
977
注册时间
2014-7-4
在线时间
237 小时
发表于 2015-5-6 14:25:39 | 显示全部楼层
没必要高8位,低8位分开 处理
 u16 Trg; 
    u16 Cont;
void KeyRead(void) 
{
    u16 ReadData ;
  u16 temp;
    temp=GPIOD->IDR&0xffff; 
    ReadData=temp^0xffff;
  /*********************************/
    Trg = ReadData & (ReadData ^ Cont);      // 2
    Cont = ReadData;    
}
回复 支持 反对

使用道具 举报

32

主题

286

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1366
金钱
1366
注册时间
2014-3-27
在线时间
358 小时
发表于 2015-12-2 18:45:33 | 显示全部楼层
回复【17楼】hkys_lxh:
---------------------------------
问题最后怎么解决的。
回复 支持 反对

使用道具 举报

头像被屏蔽

65

主题

277

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2013-8-11
在线时间
29 小时
发表于 2015-12-3 12:08:12 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

1

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2016-2-19
在线时间
16 小时
发表于 2016-2-20 21:19:09 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

22

主题

92

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
446
金钱
446
注册时间
2014-4-7
在线时间
53 小时
发表于 2016-4-22 17:06:41 | 显示全部楼层
好像有问题,这个程序,长按这里有问题吧!!!每次长按 都会触发短按,并且t++这也是问题!!!个人意见!!!
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2016-6-22 21:37:41 | 显示全部楼层
STM32新学习者 发表于 2016-4-22 17:06
好像有问题,这个程序,长按这里有问题吧!!!每次长按 都会触发短按,并且t++这也是问题!!!个人意见! ...

对的,需要想办法解决
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

21

主题

123

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
355
金钱
355
注册时间
2012-3-11
在线时间
49 小时
 楼主| 发表于 2016-6-22 21:40:54 | 显示全部楼层
wuguobo5439 发表于 2013-3-21 17:22
if((KEY_Trg&nbsp;&&nbsp;KEY10))//短按
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n ...

曾经在一个工业实际项目中使用过,有时候会出现干扰。这个算法应该需要加滤波,后来改为传统的按下后,开启定时器计时这种方式,解决bug
这辈子只会两件事:这也不会,那也不会!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-12-4
在线时间
0 小时
发表于 2016-12-4 11:58:50 | 显示全部楼层
这种方法 怎样去抖动?   
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2016-12-4
在线时间
0 小时
发表于 2016-12-4 12:01:31 | 显示全部楼层
每隔一定时间  扫描一次这两个函数:KeyRead() ;
KeyProcess() ;   用这种方式去抖动?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-25 21:44

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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