找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4034|回复: 2
打印 上一主题 下一主题
收起左侧

单片机按键消抖经典算法,亲测很好用,不信自己试试,分享就是快乐!

  [复制链接]
跳转到指定楼层
楼主
ID:114701 发表于 2020-7-12 23:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*功能:实现按键计数,4位数码管上显示计数值,   实验目的:按键稳定消抖,按键按下一次只执行一次操作,*/

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. typedef unsigned char uint8;
  4. #include<reg52.h>
  5. #include<intrins.h>
  6. typedef unsigned char uint8;                          
  7. typedef unsigned int uint16;                           
  8. typedef unsigned long uint32;

  9. sbit KEYGND=P3^4; //矩阵按键的一条列线,此程序将KEYGND=0,模拟出3个独立按键的到地
  10. sbit K1 = P3^5;
  11. sbit K2 = P3^6;
  12. sbit K3 = P3^7;
  13. sbit LED = P1^7;
  14. uint8 code seg[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; //0-9段码
  15. uint8 dis[4]={0,0,0,0};//位显缓存
  16. uint16 count=0,ms;

  17. void KeyScan(void)  //这里的松手检测很好用,值得记住,在定时中断函数中每20ms调用一次KeyScan(),非常完美,基本不会不影响其程序运行,
  18. {                   //按下只产生一次操作
  19.      static bit KeyOnOff = 0;  //这里一定要定义为静态变量或者全局变量
  20.      if(K1==0||K2==0||K3==0)             //  判断是否有按键按下
  21.       {
  22.         if(KeyOnOff == 0)         //  自锁变量
  23.          {
  24.              KeyOnOff = 1;   // 屏蔽这句话,将没有松手检测,数字加的快
  25.              if(K1==0) //按K1加数
  26.              {
  27.                 count++;
  28.              }
  29.              if(K2==0)  //按K2减数
  30.              {
  31.                 count--;
  32.              }
  33.              if(K3==0)  //按K3归零
  34.              {
  35.                 count=0;
  36.              }
  37.           }
  38.       }
  39.      else
  40.       {
  41.         KeyOnOff = 0;    //  当没有按键按下时  解锁
  42.       }
  43. }
  44. /*********************毫秒延时函数************************************/
  45. void delay1ms(unsigned char n)   
  46. {
  47.     unsigned char a,b,c;
  48.                 for(c=n;c>0;c--)
  49.     for(b=102;b>0;b--)
  50.         for(a=3;a>0;a--);
  51. }

  52. /**************************数据处理和刷新显示函数*********************/
  53. void disp_count()  //数码管显示函数
  54. {
  55.         uint8 i=0;        
  56.         dis[0]=count%10;       //计数器显示用刷新函数
  57.         dis[1]=count/10%10;    //计数器显示用刷新函数
  58.         dis[2]=count/100%10;    //计数器显示用刷新函数
  59.         dis[3]=count/1000%10;   //计数器显示用刷新函数
  60.         
  61.         if(dis[3]==0)
  62.         {
  63.                  dis[3]=0x0a;  //高位为零不显示,
  64.                  if(dis[2]==0)
  65.                  {
  66.             dis[2]=0x0a;  //高位为零不显示,
  67.             if(dis[1]==0)
  68.             {
  69.                 dis[1]=0x0a;  //高位为零不显示,
  70.             }
  71.                  }
  72.         }

  73.         for (i=0;i<4;i++)
  74.         {
  75.                         switch(i)           
  76.             {
  77.                 case 0: P0=0Xff; P2=0xfe;break;  //这里的P0=0XFF的目的是消除鬼影
  78.                 case 1: P0=0Xff; P2=0xfd;break;         //这里的P0=0XFF的目的是消除鬼影
  79.                 case 2: P0=0Xff; P2=0xfb;break;  //这里的P0=0XFF的目的是消除鬼影
  80.                 case 3: P0=0Xff; P2=0xf7;break;  //这里的P0=0XFF的目的是消除鬼影
  81.             }
  82.                         P0=seg[dis[i]];
  83.                         delay1ms(1);
  84.         }
  85. }

  86. /*************定时器初始化函数*************/
  87. void InitTimer0(void)
  88. {
  89.     TMOD = 0x01;
  90.     TH0 = 0xfc;  //TH0=0xfc,TL0=0x66组合是1毫秒的初值
  91.     TL0 = 0x66;  //
  92.     EA = 1;
  93.     ET0 = 1;
  94.     TR0 = 1;
  95. }   

  96. /*****************************************主函数*******************************/
  97. void main()
  98. {
  99.     P0=0xff;  //4位数码管段码
  100.     P2=0xff;  //4位数码管位码
  101.     KEYGND=0;
  102.     InitTimer0(); //定时器初始化函数
  103.     while(1)
  104.     {

  105.         disp_count();  //数码管显示函数
  106.         delay1ms(1);   
  107.     }
  108. }

  109. /************************************INT0定时中断函数****************************/
  110. void Timer0Interrupt(void) interrupt 1
  111. {
  112.     TH0 = 0xfc;
  113.     TL0 = 0x66;
  114.                 ms++;      
  115.         if(ms%20==0) //每20ms执行一次按键检测
  116.         {
  117.            KeyScan();
  118.         }
  119.                
  120. }  
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:328014 发表于 2020-7-13 15:29 | 只看该作者
很好的思路,值得学习
回复

使用道具 举报

板凳
ID:17647 发表于 2020-7-13 15:38 | 只看该作者
经典!收藏了。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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