OpenEdv-开源电子网

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

关于按键检测 ,

[复制链接]

62

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2013-11-15
在线时间
85 小时
发表于 2018-6-16 11:42:48 | 显示全部楼层 |阅读模式
1金钱
程序中按键怎么写,连开三贴了,谢谢老师们的指点,我愚笨 ,还是没有想清楚 。所以决定把问题问的详细点 ,然后暂时成为我的套路 。求老师们可以上传些成功历程,或是详细指点一下 ,那么 ,问题来了  :

情景: 如果我程序中要做的事情很多 ,按键处理只是其中部分功能 ,那么


1 扫描IO口的方法好  ,还是外部中断中断的方式好 ?

2 如果是用定时器扫描IO口的话 ,这部分代码写在哪里 ?
3如果程序裸奔的话 ,怎么把按键按下这一事件告知按下按键想要触发的那个事件?
4如果还有松手检测,松手检测怎么写?
5想写一个长时间,比如按下3秒才认为按下,怎么写 ,同样长按下怎么告知想要触发的那个事件?
6同一按键怎么区分长时间按下和短时间按下 ?
7如果写组合键 ,思路套路又是怎样 ?

工作多年 ,水平薄浅 。别笑我 ,求赐教!!


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

49

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
352
金钱
352
注册时间
2016-11-13
在线时间
40 小时
发表于 2018-6-16 16:42:18 | 显示全部楼层

鉴于任务很多,强烈建议操作系统

本帖最后由 fantasyfeather 于 2018-6-16 16:59 编辑

鉴于任务很多,强烈建议操作系统
1.外部中断吧,定时器中断的话中断太频繁了。
3.可以用操作系统,也可以用全局变量标记一下按键按下。
4.中断可以在上升沿,下降沿,也可以上升沿下降沿都产生。
5.在中断里面可以计时,在这里感觉用实时时钟可以,定时器也行
6.同上
7.多个全局变量,标记多个按键,或者操作系统





回复

使用道具 举报

62

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2013-11-15
在线时间
85 小时
 楼主| 发表于 2018-6-16 18:36:17 | 显示全部楼层
fantasyfeather 发表于 2018-6-16 16:42
鉴于任务很多,强烈建议操作系统
1.外部中断吧,定时器中断的话中断太频繁了。
3.可以用操作系统,也可 ...

有写好的历程上传一下吗 ?
回复

使用道具 举报

2

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
336
金钱
336
注册时间
2018-5-14
在线时间
69 小时
发表于 2018-6-16 19:00:57 | 显示全部楼层
1,定时器加IO扫描就可以了。
2,按键程序基本都是判断,写到定时器中断里不会有什么影响,当然,也可以中断置标志然后主循环里扫描。
3,全局变量置按键状态,需要的事件自己读取;
4,知道怎么判断按下,能不知道怎么判断松开吗……按键本身是个开关量,也就是只有两个状态,非按即松;
5,定时器计数;
6,多个按键一起读就可以了
回复

使用道具 举报

62

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2013-11-15
在线时间
85 小时
 楼主| 发表于 2018-6-16 19:22:56 | 显示全部楼层
kvdong 发表于 2018-6-16 19:00
1,定时器加IO扫描就可以了。
2,按键程序基本都是判断,写到定时器中断里不会有什么影响,当然,也可以中 ...

说着真容易 ,单写不出来  ,可以给个历程不  ?
回复

使用道具 举报

2

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
336
金钱
336
注册时间
2018-5-14
在线时间
69 小时
发表于 2018-6-16 20:53:07 | 显示全部楼层
u8 KeyData,KeyDownFlag,KeyLosseFlag;
u8 KeyDownBuf[KEY_NUM];
u8 KeyLooseBuf[KEY_NUM];

u8 key_scan(void)
{
        if(KEY1 == TURE)
       {
              KeyDownBuf[KEY1_F]++;

      }
     else
    {
          KeyLooseBuf[KEY1_F]++;

   }
// 其它按键程序类似添加
  if (KeyDownBuf[KEY1_F] >= KEY_LOOP_NUM)
  {
        KeyDownFlag |= (1<<KEY1_F);//KeyDownFlag 里面已经是按下的按键并且去抖后的值了。
  }
   if (KeyLooseBuf[KEY1_F] >= KEY_LOOP_NUM)
  {
        if (KeyDownFlag & (1<<KEY1_F))
        {
               KeyLosseFlag |= (1<<KEY1_F);//KeyLosseFlag里面的值就是按下又松开的按键
        }
  }
//下面可以根据KeyDownFlag的值和KeyLooseFlag的值给KeyData赋值即可。赋值以后记得根据情况清零两个标志即可。
}


找个低优先级中断,10ms延时,调用就行了。
PS:在网页上打字格式不好弄,做的有些简略,你可以自己补充想要的。
再PS:按键的程序不只是说着容易,而是真的没什么麻烦的。
回复

使用道具 举报

2

主题

168

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
336
金钱
336
注册时间
2018-5-14
在线时间
69 小时
发表于 2018-6-16 20:55:28 | 显示全部楼层
归荑洵 发表于 2018-6-16 19:22
说着真容易 ,单写不出来  ,可以给个历程不  ?

里面的一些纯大写的(例如KEY_NUM)是预定义,你自己添加。
要去看阿根廷比赛了,顾不上多说了,剩下的自己捣鼓吧
回复

使用道具 举报

62

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2013-11-15
在线时间
85 小时
 楼主| 发表于 2018-6-16 21:52:02 | 显示全部楼层
kvdong 发表于 2018-6-16 20:55
里面的一些纯大写的(例如KEY_NUM)是预定义,你自己添加。
要去看阿根廷比赛了,顾不上多说了,剩下的 ...

谢谢了  ,潘帕斯加油  
回复

使用道具 举报

21

主题

299

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1836
金钱
1836
注册时间
2013-7-29
在线时间
278 小时
发表于 2018-6-17 10:38:51 | 显示全部楼层
外部中断。硬件做个RC滤波或软件做个延时滤波程序。
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2018-6-19 11:29:20 | 显示全部楼层
对于按键的驱动,任何情况下都不建议直接使用外部中断,使用中断的特点是响应快,但是按键的应用不需要响应很快。而使用外部中断引起的麻烦却不少。1.该不该在中断里做毫秒级的延时?如果只是中断发送消息,主循环里的按键处理才是主体,才进行延时,那这个中断就一点意义都没有,还不如用定时器去触发按键扫描周期。2.按键功能如果比较丰富,怎么做到不干扰别的任务。比如你说的长按功能,如果没有定时器参与进来,那这3秒就不能干别的了,如果进一步想做出按住后连续触发的功能,程序就彻底不能用了。


如果任务较多,个人建议用操作系统。按键的驱动就是很典型的适用于操作系统的应用,毫秒级的延时正好可以用taskDelay这种函数,释放了cpu的占用,程序可以去干别的。
如果不想用操作系统,那可以定时器来辅助。基本思路就是使用状态机的模式,将按键的处理做成周期性执行的操作,如果某些场合需要的延时不一样,那就用计数变量把长延时拆成短延时。每个周期按键扫描函数执行一次,用定时器同步,函数内没有任何软延时。
建议将去抖动和按键功能触发做成2个层次,底层的去抖动处理只实时更新每个按键IO的电平,上层的触发检测根据不同的电平和每个按键的模式配置、状态机的状态,来判断需要执行的操作。 假如以后移植到rtos里,直接做一个周期性执行的任务即可。

目前手里没有现成的代码,这个只是思路。不过前几年在这个论坛上见过有人发过很详细的按键驱动代码,功能很全,当时我还没收藏,你可以找找看。

回复

使用道具 举报

16

主题

203

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1896
金钱
1896
注册时间
2015-7-5
在线时间
483 小时
发表于 2018-6-19 13:01:50 | 显示全部楼层
我从来有没有用过中断方式读取按键。
一般,按键只是在需要时才去读取,“需要时”意味着可以用查询方式解决问题。
回复

使用道具 举报

31

主题

1954

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4511
金钱
4511
注册时间
2018-5-11
在线时间
944 小时
发表于 2018-6-19 16:42:52 来自手机 | 显示全部楼层
huyounong 发表于 2018-6-19 13:01
我从来有没有用过中断方式读取按键。
一般,按键只是在需要时才去读取,“需要时”意味着可以用查询方式解 ...

中断方式读取按键并没有什么不可以的,对于单片机系统,大部分用于控制,其实按键在99%以上的时间都是闲置的,而外部中断既能快速响应按键,又基本不占用CPU时间,在按键较少又不常用的情况下恰好适合。
回复

使用道具 举报

62

主题

202

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2013-11-15
在线时间
85 小时
 楼主| 发表于 2018-6-21 09:35:53 | 显示全部楼层
如果是用AD的方式  呢  
回复

使用道具 举报

3

主题

28

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
207
金钱
207
注册时间
2017-9-6
在线时间
45 小时
发表于 2018-7-27 11:12:01 | 显示全部楼层
AD按键可以保证少量按键不冲突,另外,按键出现的问题主要在延时上,如果有可能加上硬件消抖电路...
回复

使用道具 举报

9

主题

796

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2038
金钱
2038
注册时间
2017-8-2
在线时间
522 小时
发表于 2018-7-27 11:18:26 | 显示全部楼层
本帖最后由 323232 于 2018-7-27 11:19 编辑

裸奔我这里有个状态机按键扫描  你可以参考下https://download.csdn.net/download/qq_26664187/10489613
看了一下还是比较符合你要求的
猪猪熊呢?
回复

使用道具 举报

9

主题

796

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2038
金钱
2038
注册时间
2017-8-2
在线时间
522 小时
发表于 2018-7-27 11:23:04 | 显示全部楼层
323232 发表于 2018-7-27 11:18
裸奔我这里有个状态机按键扫描  你可以参考下https://download.csdn.net/download/qq_26664187/10489613
...

当然你也可以把他当成一个任务
猪猪熊呢?
回复

使用道具 举报

10

主题

561

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1826
金钱
1826
注册时间
2014-6-27
在线时间
979 小时
发表于 2019-7-18 15:43:46 | 显示全部楼层
你的这些按键功能都是最基本的按键扫描功能,都可以在一个函数里面完成了,短按,长按,组合键,松手检测都用键值表示就行了,至于扫描方式,就在主函数里面扫描,定时器里面做个节拍标志就行了。
回复

使用道具 举报

32

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
617
金钱
617
注册时间
2013-1-16
在线时间
131 小时
发表于 2020-5-12 17:30:59 | 显示全部楼层
在freertos里面,有什么好的检测按键的程序的
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-29 17:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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