社区导航

 

搜索
查看: 581|回复: 18

[问题讨论] GD32E231 DIY大赛(4)——如何获得长短按键?

[复制链接]

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

发表于 2019-5-6 13:58 | 显示全部楼层 |阅读模式
    开发板上仅有一个用户按键"Wakeup",而我的项目中至少需要用户输入的两种状态,最简单的方法则通过识别用户的长按或短按。我是这样处理的,设置按键为中断方式,在中断处理程序中将全局变量keys = 1,这是中断处理程序的代码:
void EXTI0_1_IRQHandler(void)
{
    if(RESET != exti_interrupt_flag_get(EXTI_0)){
        keys = 1;
        gd_eval_led_toggle(LED4);
  
    }
   
    exti_interrupt_flag_clear(EXTI_0);
}  


    在main循环中检测到keys>0就跳转到按键处理程序,代码如下:
  if(keys > 0)          //有键按下
            key_processing();

    在按键处理程序中通过延时后再检测按键是否仍在按下状态,代码如下:
    delay_1ms(100);
    if(SET == gpio_input_bit_get(GPIOA,GPIO_PIN_0))
        keys = 3;
    delay_1ms(200);
    if(SET == gpio_input_bit_get(GPIOA,GPIO_PIN_0))
        keys = 6;

    中断处理和主循环判断都很正常,但在按键处理中却不能达到目的,无论按键时间长短,keys始终为1。
    我将中断处理程序里面的keys = 1改为keys++,注释掉按键处理这段代码,则返回的keys值会变化,但不能稳定地与按键时间长短对应。
    整个五一节日都在反复调试工,至今仍无法得到满意的结果,请各位大侠帮忙看看是何原因,应该采取何种方式才能达到要求。先谢谢各位!

来源:EEWorld GD32 MCU板块,转载请附上链接


回复

使用道具 举报

932

TA的帖子

6

TA的资源

版主

Rank: 6Rank: 6

发表于 2019-5-6 14:02 | 显示全部楼层

点评

感谢,资料不错~  详情 回复 发表于 2019-5-10 12:05
谢谢提供链接!正在学习中,若有不理解的地方再向您请教。  详情 回复 发表于 2019-5-6 14:53


回复

使用道具 举报

5649

TA的帖子

453

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

发表于 2019-5-6 14:16 | 显示全部楼层
为什么按键不用定时器查询呢?10ms读一次,累计大于200次都是按下就认为长按!

点评

是不是设置定时时间为10ms,然后在中断处理里取按键状态,键按下则keys值加1。  详情 回复 发表于 2019-5-6 14:26


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-6 14:18 | 显示全部楼层
这个问题我在GD32E230开发板上也遇到过,最后只好启用两个按键来解决,好在230的板子上共有3个按键(包括复位键)。我在STM32F103下面用类似的办法实现过,能正确分辨出长短按键。


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-6 14:26 | 显示全部楼层
蓝雨夜 发表于 2019-5-6 14:16
为什么按键不用定时器查询呢?10ms读一次,累计大于200次都是按下就认为长按!

是不是设置定时时间为10ms,然后在中断处理里取按键状态,键按下则keys值加1。

点评

如果你一定使用响应外部中断的话,那就按下开始启动定时器,释放的时候读取定时值,然后判断时间长短 你说呢!  详情 回复 发表于 2019-5-6 15:28


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-6 14:53 | 显示全部楼层
RCSN 发表于 2019-5-6 14:02
https://github.com/0x1abin/MultiButton 了解下

谢谢提供链接!正在学习中,若有不理解的地方再向您请教。


回复

使用道具 举报

5649

TA的帖子

453

TA的资源

五彩晶圆(高级)

Rank: 9Rank: 9Rank: 9

发表于 2019-5-6 15:28 | 显示全部楼层
hujj 发表于 2019-5-6 14:26
是不是设置定时时间为10ms,然后在中断处理里取按键状态,键按下则keys值加1。

如果你一定使用响应外部中断的话,那就按下开始启动定时器,释放的时候读取定时值,然后判断时间长短

你说呢!



回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-6 15:35 | 显示全部楼层
我再试试看。


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-7 12:28 | 显示全部楼层
简单问题复杂化了,为了这个按键长短问题弄了6~7天,总是没能达到目的,期间还尝试过MultiButton、flexible_button、ButtonDrive_master等例程,这些例程功能齐全、接口规范、适用面广,但要想用起来却不容易,不是这个参数不符合要求就是那个设置不正确,导致编译通不过。今天豁然开朗,用最简单的轮询按键加DELAY延时,成功地达到了目的,尽管这样做效率低,但对我这个项目来说不成问题。代码如下:

    while(1){
        keys = 0;
                while(gd_eval_key_state_get(KEY_WAKEUP))
                {
                    keys++;
                        delay_1ms(100);
                }
                if(keys > 0)          //有键按下
                    key_processing();


回复

使用道具 举报

35

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-5-7 13:53 | 显示全部楼层
在按键按下时,MCU全被delay占用……,太浪费了。

点评

是浪费MCU,不过在我的项目中,MCU不用在这里也是空循环,不在乎了。  详情 回复 发表于 2019-5-7 17:40
intersil TW88系列软件应用工程师


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-7 17:40 | 显示全部楼层
李百仪 发表于 2019-5-7 13:53
在按键按下时,MCU全被delay占用……,太浪费了。

是浪费MCU,不过在我的项目中,MCU不用在这里也是空循环,不在乎了。


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-5-7 18:09 来自手机 | 显示全部楼层
李百仪 发表于 2019-5-7 13:53
在按键按下时,MCU全被delay占用……,太浪费了。

大神  看得透


回复

使用道具 举报

23

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-5-10 12:05 | 显示全部楼层
RCSN 发表于 2019-5-6 14:02
https://github.com/0x1abin/MultiButton 了解下

感谢,资料不错~


回复

使用道具 举报

76

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-5-11 11:50 | 显示全部楼层
其实你可以使用定时器来做的。上一次的GD比赛,需要用的按键比较多,我也是使用长短按来区别不同的功能的,我的实现方式就是使用定时器。
定会器没10ms或者1ms检测一次按键状态,然后使用一个static变量counter进行累计,我当时使用的10ms的,短按的时间就是小于1s,长安的时间是大于1s。在按键被松开的时候检测counter的数值大小,如果counter大于100就是长按,小于100就是短按,我感觉这种方式还是比较好的,当然还可以加上40ms的滤波,也是在定时器中可以完成的

点评

谢谢您的提示!3楼的坛友也是这样建议的。我开始也准备试试,但没有找到合适的参考代码,再说轮询方式虽说效率低下,但能满足项目的需要,所以就暂时先用了,等项目主要部分完成后若还有时间,则再试试定时器方式,  详情 回复 发表于 2019-5-11 13:14


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-11 13:14 | 显示全部楼层
hehung 发表于 2019-5-11 11:50
其实你可以使用定时器来做的。上一次的GD比赛,需要用的按键比较多,我也是使用长短按来区别不同的功能的, ...

谢谢您的提示!3楼的坛友也是这样建议的。我开始也准备试试,但没有找到合适的参考代码,再说轮询方式虽说效率低下,但能满足项目的需要,所以就暂时先用了,等项目主要部分完成后若还有时间,则再试试定时器方式,优化代码。

点评

我写了一个由定时器的长短按的判断的程序,你可以看看:http://bbs.eeworld.com.cn/thread-1076729-1-1.html  详情 回复 发表于 2019-5-12 00:15


回复

使用道具 举报

885

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-5-11 15:12 | 显示全部楼层
在按键按下时,MCU全被delay占用……,太浪费了

点评

什么叫浪费?在主循环中空循环就不浪费了么?  详情 回复 发表于 2019-5-11 18:55


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-11 18:55 | 显示全部楼层
zhuyebb 发表于 2019-5-11 15:12
在按键按下时,MCU全被delay占用……,太浪费了

什么叫浪费?在主循环中空循环就不浪费了么?


回复

使用道具 举报

76

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-5-12 00:15 | 显示全部楼层
hujj 发表于 2019-5-11 13:14
谢谢您的提示!3楼的坛友也是这样建议的。我开始也准备试试,但没有找到合适的参考代码,再说轮询方式虽 ...

我写了一个由定时器的长短按的判断的程序,你可以看看:http://bbs.eeworld.com.cn/thread-1076729-1-1.html

点评

谢谢分享!准备借用您的代码试试看。  详情 回复 发表于 2019-5-12 09:30


回复

使用道具 举报

628

TA的帖子

3

TA的资源

纯净的硅(初级)

Rank: 4

 楼主| 发表于 2019-5-12 09:30 | 显示全部楼层
hehung 发表于 2019-5-12 00:15
我写了一个由定时器的长短按的判断的程序,你可以看看:http://bbs.eeworld.com.cn/thread-1076729-1-1.h ...

谢谢分享!准备借用您的代码试试看。


回复

使用道具 举报

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

关闭

站长推荐上一条 /6 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-10-14 15:45 , Processed in 0.520793 second(s), 16 queries , Gzip On, MemCache On.

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