找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 11643|回复: 31
收起左侧

如何用单片机定时器进行按键消抖

  [复制链接]
ID:219181 发表于 2017-8-27 16:06 | 显示全部楼层 |阅读模式
我这个是0~9999的循环按键加减,按一下加/减一,长按连续加减,但是短按加的时候会连续加几下,减的话会反应慢很多。不确定是不是消抖没做好,求各位大神指教!!!!!

  1. #includ<reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. sbit Seg_W1  = P2^1;               
  5. sbit Seg_W4  = P2^2;
  6. sbit Seg_W3  = P2^3;
  7. sbit Seg_W2  = P1^7;

  8. sbit key1    =  P3^4;//加
  9. sbit key2    =  P2^6;//减

  10. code uint biao[]=        {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};      
  11. uint array[]={0,1,2,3,4,5,6,7,8,9};

  12. uchar displayDelayCount = 0;
  13. uchar displayIndex = 0;
  14. uint displayData =240;
  15. uint delay = 0;

  16. void delayms(unsigned int x)                              
  17. {
  18. unsigned int i;
  19. while(x--)
  20. {
  21. for(i=0;i<113;i++);
  22. }
  23. }
  24. void xianshi(void
  25. {
  26.       
  27.         if(displayDelayCount >0
  28.         {
  29.                 displayDelayCount = 0;
  30.                 if(displayIndex < 3)
  31.                 {
  32.                         displayIndex ++;
  33.                 }
  34.                 else
  35.                 {
  36.                         displayIndex = 0;               
  37.                 }
  38.                 if(displayIndex == 0)      
  39.                 {      
  40.                         Seg_W1 = Seg_W2 = Seg_W3 = Seg_W4 = 0        ;
  41.                         P1=0X7F;
  42.                         P1=biao[displayData%10]
  43.                         Seg_W1=1;
  44.                 }

  45.                 if(displayIndex == 1)      
  46.                 {
  47.                         Seg_W1 = Seg_W2 = Seg_W3 = Seg_W4 = 0        ;
  48.                         P1=0X7F;
  49.                         P1=biao[displayData/10%10];
  50.                         Seg_W2=1;                       
  51.                 }

  52.                 if(displayIndex == 2)               
  53.                 {
  54.                         Seg_W1 = Seg_W2 = Seg_W3 = Seg_W4 = 0        ;
  55.                         P1=0X7F;
  56.                         P1=biao[displayData/100%10];
  57.                         Seg_W3=1;                       
  58.                 }
  59.                
  60.                 if(displayIndex == 3)
  61.                 {
  62.                         Seg_W1 = Seg_W2 = Seg_W3 = Seg_W4 = 0        ;
  63.                         P1=0X7F;
  64.                         P1=biao[displayData/1000%10];
  65.                         Seg_W4=1;
  66.                 }
  67.         }
  68. }

  69. #define         NO_AJ  1
  70. #define         UP     2
  71. #define         DOWM   3

  72. uchar anjian_yansi = 0;
  73. uchar anjianhuoqu(void)
  74. {
  75.         {
  76.                 if(!key1)
  77.                 {
  78.                 }
  79.                 else if(!key2)
  80.                 {
  81.                 }
  82.                 else
  83.                         anjian_yansi = 0;               
  84.         }
  85.       
  86.         if(anjian_yansi == 0)
  87.         {
  88.                 if(!key1)
  89.                 {
  90.                         anjian_yansi = 100;
  91.                         return UP;
  92.                 }
  93.                 else if(!key2)
  94.                 {
  95.                         anjian_yansi = 100;
  96.                         return DOWM;
  97.                 }
  98.                 else
  99.                         return NO_AJ;
  100.         }
  101.         else
  102.                         return NO_AJ;
  103. }

  104. void anjian ()
  105. {      
  106.         if(anjianhuoqu() == UP)
  107.         {
  108.                 displayData++;
  109.         }
  110.         else if(anjianhuoqu() == DOWM)
  111.         {
  112.                 displayData--;
  113.         }
  114. }      
  115. void time0()interrupt 1     //¶¨ê±¼ÆêyÆ÷£¬èë¿ú1
  116. {
  117.         TH0=(65535-5000)/256;
  118.         TL0=(65535-5000)%256;
  119.         displayDelayCount++;
  120.         delay++;
  121.          if(anjian_yansi > 0)
  122.                         anjian_yansi --;
  123. }

  124. void main()
  125. {
  126.         EA=1;     
  127.         ET0=1;     
  128.         TMOD=0X01;
  129.         TH0=(65535-5000)/256;
  130.         TL0=(65535-5000)%256;   
  131.         TR0=1;
  132.       
  133.         while(1)
  134.         {        key1=key2=key3=key4=1;
  135.                 xianshi();
  136.                 anjian ();
  137.         }      
  138. }
复制代码


回复

使用道具 举报

ID:190832 发表于 2017-8-27 21:44 | 显示全部楼层
你的29行少了一个‘)’

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:229626 发表于 2017-8-28 00:52 | 显示全部楼层
外部可以加个104电容

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:111634 发表于 2017-8-28 08:07 | 显示全部楼层

回帖奖励 +2

消抖期间,是不需要执行其他任务的,因此用延时程序,而不是用宝贵的定时器资源。
回复

使用道具 举报

ID:219181 发表于 2017-8-28 10:58 | 显示全部楼层
zl2168 发表于 2017-8-28 08:07
消抖期间,是不需要执行其他任务的,因此用延时程序,而不是用宝贵的定时器资源。

可以说说具体该怎么做吗?谢谢大神
回复

使用道具 举报

ID:198530 发表于 2017-8-28 11:45 | 显示全部楼层
一般都是延时消抖,就检测一次如果按键按下就延时然后再检测一下按键还是按下就执行

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:229690 发表于 2017-8-28 14:08 | 显示全部楼层
谢谢楼主分享
回复

使用道具 举报

ID:229711 发表于 2017-8-28 15:59 | 显示全部楼层
消抖用条延时函数就可以实现了
回复

使用道具 举报

ID:111634 发表于 2017-8-28 16:46 | 显示全部楼层
本帖最后由 zl2168 于 2017-8-28 16:53 编辑
sinho 发表于 2017-8-28 10:58
可以说说具体该怎么做吗?谢谢大神

介绍你一本书:《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41682-1,内有常用的单片机应用100案例,用于仿真实验操作,电路与程序真实可靠可信可行。其中:
第6章  键盘
6.1  独立式按键
实例69  74HC373并行输入8位按键状态
实例70  74HC165串行输入8位按键状态
实例71  CC4021串行输入8位按键状态
实例72  CC4014串行输入8位按键状态
实例73  74HC148编码输入8位按键状态
实例74  按键扩展shif t功能
6.2  矩阵式键盘
实例75  4×4矩阵式键盘
实例76  8279扩展8×8键盘
实例63 8279扩展键盘和显示.rar (63.08 KB, 下载次数: 11)
回复

使用道具 举报

ID:219181 发表于 2017-8-28 18:07 | 显示全部楼层
zl2168 发表于 2017-8-28 16:46
介绍你一本书:《80C51单片机仿真设计实例教程——基于Keil C和Proteus》清华大学出版社ISBN 978-7-302-41 ...

好的!谢谢
回复

使用道具 举报

ID:225822 发表于 2017-8-29 11:41 | 显示全部楼层
if(p34==0)
{
     delay(200);        //延时消抖
   if(p34==0)
     {
         while(!p34);        /////等待按键松手
      SendByte(5);
      }
}

void delay (unsigned int Z)//延时程序    Z倍    MS
{
        unsigned int  x,y;
        for(x=Z;x>0;x--)
        for(y=110;y>0;y--) ;
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:229889 发表于 2017-8-29 16:02 | 显示全部楼层
用一个延时就行
回复

使用道具 举报

ID:123289 发表于 2017-8-31 21:19 | 显示全部楼层
不同意地板的观点!
做了许许多多产品,所有键的消抖,没有一次是用延时做的,全部用定时器。
1、用延时会占用CPU时间。
2、用定时器,只需在顺便“插一个扫键”即可,还不耽误其它任务对此定时器的使用。
回复

使用道具 举报

ID:230352 发表于 2017-9-1 09:42 | 显示全部楼层
像这样        if(key==0)         {                 delay(10);                 if(key==0)                         {                                 wela=1;                                 P0=0xc0;                              wela=0;                                 dula=1;                                 P0=0x01;                                 dula=0;                         }         }

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:219181 发表于 2017-9-4 23:37 | 显示全部楼层
yzwzfyz 发表于 2017-8-31 21:19
不同意地板的观点!
做了许许多多产品,所有键的消抖,没有一次是用延时做的,全部用定时器。
1、用延时 ...

教我的人也是这么说的,所以大神知道怎么消吗?是在中断加个变量?
回复

使用道具 举报

ID:231116 发表于 2017-9-5 13:10 | 显示全部楼层
使用延时消抖.不要用定时器
回复

使用道具 举报

ID:231116 发表于 2017-9-5 13:14 | 显示全部楼层
sinho 发表于 2017-9-4 23:37
教我的人也是这么说的,所以大神知道怎么消吗?是在中断加个变量?

在中断中加入一个比较按键状态的程序就行
回复

使用道具 举报

ID:230915 发表于 2017-9-5 14:22 | 显示全部楼层
我是新手,前几天也狠狠搞了下消抖,感觉效果还行,代码不在这,说下当初的思路,请指教:

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:230915 发表于 2017-9-5 15:11 | 显示全部楼层
我是新手,前几天刚搞过消抖,代码不在这,说下思路,请大家指教:
1.  不用延时函数,这不是个好东西;
2.  I/O口变低一定是按键被按下,启动计数器,我是以10ms计一次数;
3.  赋第一次健值,我用的5个键,第一个键按下就是10,第三个按下就是30,判别是哪个键按下;
3、启动计数器后再检测按键是否释放,按键释放后,取计数值,按计数值时间长短做区分。
4.  关闭计数器,第二次赋健值,比如第二个短按是21,第二个长按是22;
5、该清零的变量都清零。等待按键再次按下;
6、给不同健值分配事件。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:231182 发表于 2017-9-5 16:28 来自手机 | 显示全部楼层
加一个延时函数消抖试一下

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:219181 发表于 2017-9-5 17:50 | 显示全部楼层
gaochang000000 发表于 2017-9-5 15:11
我是新手,前几天刚搞过消抖,代码不在这,说下思路,请大家指教:
1.  不用延时函数,这不是个好东西;
...

不错,受教了,待会尝试一下
回复

使用道具 举报

ID:231291 发表于 2017-9-6 01:09 | 显示全部楼层
可以使用程序消抖,这个程序不难找,就不复述了,也可以用大电容,在硬件方面消抖

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:231444 发表于 2017-9-6 17:04 | 显示全部楼层
liang ci yanshi jiu ke yi le
回复

使用道具 举报

ID:230667 发表于 2017-9-6 17:56 | 显示全部楼层
这有个硬件消抖的电路

硬件消抖电路

硬件消抖电路

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:219181 发表于 2017-9-9 12:57 | 显示全部楼层
tiexiedaqin 发表于 2017-9-6 17:56
这有个硬件消抖的电路

好的,谢谢
回复

使用道具 举报

ID:454000 发表于 2019-1-31 20:48 | 显示全部楼层

能用软件解决的问题最好不要用硬件来解决

评分

参与人数 5黑币 +175 收起 理由
Trump1438 + 35
#include51.h + 35
刀刀见红 + 35
areyouok + 35
jinsheng7533967 + 35

查看全部评分

回复

使用道具 举报

ID:660895 发表于 2021-6-9 17:48 | 显示全部楼层
zl2168 发表于 2017-8-28 08:07
消抖期间,是不需要执行其他任务的,因此用延时程序,而不是用宝贵的定时器资源。

兄弟是不是写反了,没有的话好好回去翻翻书
回复

使用道具 举报

ID:160500 发表于 2021-6-10 12:40 | 显示全部楼层
按键消抖动,完全看你自己的程序来决定使用软件延时还是定时器,或者中断。要根据你的程序要求决定。首先你要做好程序规划
回复

使用道具 举报

ID:916624 发表于 2021-6-13 15:18 | 显示全部楼层
可以看一下我写的独立按键和矩阵按键的程序

按键.7z

21.88 KB, 下载次数: 12

回复

使用道具 举报

ID:937124 发表于 2021-6-13 17:49 | 显示全部楼层
觉得是长按短按的区分问题;
回复

使用道具 举报

ID:57657 发表于 2021-6-14 13:45 | 显示全部楼层
定时器中断检测按键是否按住并进行毫秒计数,松开清0。
25毫秒为有效按键,1000毫秒为长按按键。
回复

使用道具 举报

ID:883031 发表于 2021-6-15 09:18 | 显示全部楼层
做一个20ms或者再大点的定时器,每中断一次检测一下按键状态,不用软件延时也可以。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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