OpenEdv-开源电子网

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

外部中断实验按键去抖?

[复制链接]

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
发表于 2018-8-9 20:39:55 | 显示全部楼层 |阅读模式
4金钱
[mw_shl_code=c,true]void EXTI0_IRQHandler(void)
{
        delay_ms(10);
        if(WK_UP==1)
        {                                 
                LED0=!LED0;
        }
        EXTI_ClearITPendingBit(EXTI_Line0);
}[/mw_shl_code]
这是例程里代码,运行的过程中,现象不是稳定的按一下响,按一下灭,有时候按下的时候灭,松开的时候就亮了,我感觉是按键抖动的问题,在外部中断的时候,怎么解决这个问题呢?因为现象不稳定,总以为是程序的问题,谢谢

最佳答案

查看完整内容[请看2#楼]

delay_ms(10);你这个不是用了吗? 让你再加大点试试,先把问题压缩一下再说。 说中断里用延时不好,这是一个一般的原则, 要具体情况具体运用不能死板, 原子的例程也是这样用的。 如果你的主程序没有什么特别的情况,按键中断用几十毫秒来消抖也没有什么大的问题。 事实上,一般按键操作占程序的运行时间在万分之一都不到。简单程序没有太好的办法的时候在按键中断时延时几十MS消抖也是可行的办法,这也是原子作为例程也这 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-9 20:39:56 | 显示全部楼层
伊森亨特 发表于 2018-8-13 17:31
听说不好,就一直没用,所以问问有没有正确的方法

delay_ms(10);你这个不是用了吗? 让你再加大点试试,先把问题压缩一下再说。
说中断里用延时不好,这是一个一般的原则,
要具体情况具体运用不能死板,
原子的例程也是这样用的。
如果你的主程序没有什么特别的情况,按键中断用几十毫秒来消抖也没有什么大的问题。
事实上,一般按键操作占程序的运行时间在万分之一都不到。简单程序没有太好的办法的时候在按键中断时延时几十MS消抖也是可行的办法,这也是原子作为例程也这么干的原因。
更好的办法是通过定时器或SYSTICK定时检测计时消抖或者多任务调度。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-9 22:48:58 | 显示全部楼层
增加延时,20ms试试。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

1

主题

430

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1461
金钱
1461
注册时间
2011-12-1
在线时间
110 小时
发表于 2018-8-10 11:33:55 | 显示全部楼层
加个松手检测就完事了!
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
21
金钱
21
注册时间
2018-8-10
在线时间
4 小时
发表于 2018-8-10 12:16:36 | 显示全部楼层
u8 EXit_Delay(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//消抖 延时以后去读 如果还是低电平 那就是中断!
{
    OSTimeDlyHMSM(0, 0, 0, 100);
    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==RESET)       
        return 1;
    else
        return 0;
}
回复

使用道具 举报

12

主题

144

帖子

0

精华

高级会员

Rank: 4

积分
545
金钱
545
注册时间
2017-8-1
在线时间
92 小时
发表于 2018-8-10 13:11:50 | 显示全部楼层
这种问题也问?
青涩不及当初,聚散不由你我!
回复

使用道具 举报

2

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
200
金钱
200
注册时间
2017-10-31
在线时间
42 小时
发表于 2018-8-10 17:15:25 | 显示全部楼层
延时个50ms,然后再去捕捉按键状态,前后两次比较一下,在比较结果里面去执行灯的状态命令。
敬往事一杯酒,再爱也不回头
回复

使用道具 举报

90

主题

534

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1059
金钱
1059
注册时间
2017-4-12
在线时间
280 小时
发表于 2018-8-10 17:17:13 | 显示全部楼层
用示波器直接抓它的波形,然后加大延迟对比看看。
穷不可怕,可怕的是穷的是我~~~
回复

使用道具 举报

12

主题

23

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
238
金钱
238
注册时间
2018-8-2
在线时间
39 小时
发表于 2018-8-10 18:16:14 | 显示全部楼层
void EXTI0_IRQHandler(void)
{
    delay_ms(10);
    if(WK_UP==1)
    {               
        LED0=!LED0;
        LED1 = 0;
        while(!WK_UP)
        {
            LED1 = 1;
        }
    }
    EXTI_ClearITPendingBit(EXTI_Line0);
}



可以试试这个松手检测,按下后LED1灭,松开LED1亮
哈哈,加油
回复

使用道具 举报

36

主题

227

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3096
金钱
3096
注册时间
2016-4-15
在线时间
350 小时
发表于 2018-8-10 19:32:42 | 显示全部楼层
这个叫常识
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 13:00:46 | 显示全部楼层
warship 发表于 2018-8-9 22:48
增加延时,20ms试试。

中断里面加中断不好啊
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 13:02:33 | 显示全部楼层
Scilence 发表于 2018-8-10 17:15
延时个50ms,然后再去捕捉按键状态,前后两次比较一下,在比较结果里面去执行灯的状态命令。

中断里加延时好吗
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 13:03:02 | 显示全部楼层
烈日灼心 发表于 2018-8-10 17:17
用示波器直接抓它的波形,然后加大延迟对比看看。

中断里加延时好吗,据说中断要时间短,简洁
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 13:03:48 | 显示全部楼层

你觉得这几楼有好的解决方法吗?
回复

使用道具 举报

19

主题

82

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
466
金钱
466
注册时间
2018-6-8
在线时间
114 小时
发表于 2018-8-13 13:15:37 | 显示全部楼层
void EXTI0_IRQHandler(void)
{
    if(a==0)
    {              
        a = 1;
        LED0=!LED0;
    }
    EXTI_ClearITPendingBit(EXTI_Line0);
}

main()
{
    if (a == 1)    {
        delay_ms(500);
        a = 0;
    }
}


回复

使用道具 举报

0

主题

28

帖子

0

精华

高级会员

Rank: 4

积分
762
金钱
762
注册时间
2018-7-25
在线时间
276 小时
发表于 2018-8-13 13:31:59 | 显示全部楼层
之前在RTOS的应用中做过使用信号量实现外中断与任务同步,我是设置了一个全局的变量,利用一个定时器中断或者RTOS的Tick hook函数间隔一定时间控制变量从一个初始值开始自增一,初始值对应消抖的时间。
当外中断发生后,在中断服务例程中对变量进行判断,只有变量当前值大于初始值才执行中断的任务代码,并且对变量进行清零,否则不执行任何操作。这样实现消抖,也避免了在中断中延时降低系统实时性。
不知道各位坛友有没有更好的方法。
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-13 14:45:25 | 显示全部楼层

你不是已经在中断里用延时了吗?先看加了延时能不能解决问题,然后再探讨更好的方法不行吗
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 17:31:03 | 显示全部楼层
warship 发表于 2018-8-13 14:45
你不是已经在中断里用延时了吗?先看加了延时能不能解决问题,然后再探讨更好的方法不行吗

听说不好,就一直没用,所以问问有没有正确的方法
回复

使用道具 举报

37

主题

142

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
278
金钱
278
注册时间
2016-9-13
在线时间
73 小时
 楼主| 发表于 2018-8-13 17:32:24 | 显示全部楼层
wbyrnygrysc 发表于 2018-8-13 13:15
void EXTI0_IRQHandler(void)
{
    if(a==0)

你这个思路不错,吧延时放在外面来写
回复

使用道具 举报

20

主题

227

帖子

0

精华

高级会员

Rank: 4

积分
605
金钱
605
注册时间
2017-7-14
在线时间
116 小时
发表于 2018-8-13 17:57:56 | 显示全部楼层
本帖最后由 SimpleLife 于 2018-8-13 18:00 编辑

中断内使用delay,实时性会降低,可以考虑在中断内加标志位(一个按键对应一个bit,占用资源也会少点),在mian内添加按键检查函数。这是我的驱动:  https://github.com/LifeSimpleLwq ... ob/master/KEY/key.c


回复

使用道具 举报

2

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
200
金钱
200
注册时间
2017-10-31
在线时间
42 小时
发表于 2018-8-27 20:06:47 | 显示全部楼层

外面任务延时+比较两次结果,触发中断,
敬往事一杯酒,再爱也不回头
回复

使用道具 举报

31

主题

1955

帖子

3

精华

论坛元老

Rank: 8Rank: 8

积分
4524
金钱
4524
注册时间
2018-5-11
在线时间
947 小时
发表于 2018-8-27 20:19:20 | 显示全部楼层
查看我的主题,下载测试最新按键扫描程序。
我的开源链接 https://github.com/ShuifaHe/STM32.git  请关注,点赞支持哦。
回复

使用道具 举报

3

主题

312

帖子

0

精华

高级会员

Rank: 4

积分
907
金钱
907
注册时间
2011-10-19
在线时间
196 小时
发表于 2018-8-28 08:48:41 | 显示全部楼层
一般来说,裸机做软件消抖其实都不划算,还是用硬件消抖为好,只需在按键两端并联一个104左右的电容即可(片内或外部已经上拉)。

真要做软件消抖,在中断里延时是非常不明智的;我通常这样处理:在中断里置标志位、关闭按键中断、在主函数里根据标志位进行消抖及按键检测、完成后再重新打开按键中断。
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-11 03:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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