找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2262|回复: 12
收起左侧

51单片机楼道延时开关程序,为什么一次加就是加50s.数字太大会乱

  [复制链接]
ID:938708 发表于 2021-6-18 15:44 | 显示全部楼层 |阅读模式
设计一楼道触摸延时开关控制器,其功能是当人用手触摸开关时,照明灯点亮,并持续一段时间后自动熄灭。开关的延时时间可设置并有显示。
触摸即是按键开关,程序出现了错误,为什么一次加就是加50s.数字太大会乱。
51hei图片20210618154332.jpg

程序如下:

  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. uchar ledtab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
  4. uchar KEY,keyval,dat[2],sec,num,tick,time;
  5. sbit D1=P1^0;
  6. sbit D2=P1^1;
  7. void delay(uchar x)
  8. {
  9. uchar i,j;
  10. for(i=0;i<x;i++)
  11. for(j=0;j<125;j++);
  12. }
  13. void dischg()
  14. {
  15. dat[0]=time/10;
  16. dat[1]=time%10;
  17. }
  18. void getkey(void)
  19. {
  20. keyval=0xff;
  21. KEY=P3&0x0f;
  22. if(KEY!=0xf)
  23. {
  24.   delay(10);
  25.   KEY=P3&0x0f;
  26.   if(KEY!=0x0f)
  27.   {
  28.   switch(KEY)
  29.   {
  30.   case 0x0e:
  31.    while(P3&0x0f==0x0e);
  32.    keyval=1;
  33.    break;
  34.   case 0x0d:
  35.    while(P3&0x0f==0x0d);
  36.    keyval=2;
  37.    break;
  38.   case 0x0b:
  39.    while(P3&0x0f==0x0b);
  40.    keyval=3;
  41.    break;
  42.   case 0x07:
  43.    while(P3&0x0f==0x07);
  44.    keyval=4;
  45.    break;
  46.   default:break;
  47.   }
  48.   }
  49. }
  50. }
  51. void t0_isr() interrupt 1
  52. {
  53. TR0=0;
  54. TH0=(65536-50000)/256;
  55. TL0=(65536-50000)%256;
  56. TR0=1;
  57. tick++;
  58. if(tick>=20)
  59. {
  60.   tick=0;
  61.   if(time>0)time--;
  62.   else
  63.   {
  64.   D1=0;
  65.   D2=0;
  66.   TR0=0;
  67.   time=sec;
  68.   }
  69. dischg();
  70. }
  71. }
  72. t1_isr() interrupt 3
  73. {
  74. TR1=0;
  75. TH1=(65536-5000)/256;
  76. TL1=(65536-5000)%256;
  77. TR1=1;
  78. if(num)P2=0x01;
  79. else P2=0x02;
  80. P0=~ledtab[dat[num]];
  81. num++;
  82. num&=0x01;
  83. }
  84. main()
  85. {
  86. TMOD=0x11;
  87. TH0=(65536-50000)/256;
  88. TL0=(65536-50000)%256;
  89. TH1=(65536-5000)/256;
  90. TL1=(65536-5000)%256;
  91. dat[0]=0x00;
  92. dat[1]=0x05;
  93. tick=0;
  94. sec=5;
  95. time=5;
  96. // dischg();
  97. TR0=0;
  98. ET0=1;
  99. TR1=1;
  100. ET1=1;
  101. D1=0;
  102. D2=0;
  103. EA=1;
  104. while(1)
  105. {
  106.   getkey();
  107.   switch(keyval)
  108.   {
  109.   case 1:
  110.    TR0=0;
  111.    sec++;
  112.    time=sec;
  113.    dischg();
  114.    break;
  115.   case 2:
  116.    TR0=0;
  117.    if(sec>1)sec--;
  118.    time=sec;
  119.    dischg();
  120.    break;
  121.   case 3:
  122.    D1=1;
  123.    D2=0;
  124.    TR0=1;
  125.    time=sec;
  126.    dischg();
  127.    break;
  128.   case 4:
  129.    D1=0;
  130.    D2=1;
  131.    TR0=1;
  132.    time=sec;
  133.    dischg();
  134.    break;
  135.   default:break;
  136.   }
  137. }
  138. }
复制代码

回复

使用道具 举报

ID:739545 发表于 2021-6-18 16:29 | 显示全部楼层
按键没有做防抖延迟处理,当你按下去的时候,你以为只按了一下,实际sec值不知道跑了多少下了,就4个按键,不要用键值的方法,就直接比较按键是否为另,如果为0 while(P-30==0)
回复

使用道具 举报

ID:356290 发表于 2021-6-18 16:34 | 显示全部楼层
按键没消抖,所以一直加了,你可以判断按下松开再加
回复

使用道具 举报

ID:938708 发表于 2021-6-18 16:45 | 显示全部楼层
lovezjf234 发表于 2021-6-18 16:29
按键没有做防抖延迟处理,当你按下去的时候,你以为只按了一下,实际sec值不知道跑了多少下了,就4个按键, ...

确实没有防抖延迟嘻嘻 谢谢老师
回复

使用道具 举报

ID:938708 发表于 2021-6-18 16:46 | 显示全部楼层
Haisi 发表于 2021-6-18 16:34
按键没消抖,所以一直加了,你可以判断按下松开再加

√明白了,我现在想修改那个按下增加的秒数却改不了,代码找不到了,请问大佬具体是哪些代码控制按键增加或者减少秒数吗
回复

使用道具 举报

ID:668693 发表于 2021-6-18 16:55 | 显示全部楼层
switch(KEY)
{
       case 0x0e:
                       keyval=1;
                       while(P3&0x0f==0x0e);
                       break;
}

需要把执行的操作放在按键松开之前,然后再去等待按键释放
回复

使用道具 举报

ID:938708 发表于 2021-6-18 17:12 | 显示全部楼层
林神经 发表于 2021-6-18 16:55
switch(KEY)
{
       case 0x0e:

改了试了一下还是会抖动
回复

使用道具 举报

ID:844772 发表于 2021-6-18 17:28 | 显示全部楼层
看得很粗啊,我觉得不是防抖问题,是keyval没有清零,所以只要按一次,就会一直累加,我觉得每次switch(keyval)之后,加上keyval=0;就会好了
回复

使用道具 举报

ID:81196 发表于 2021-6-18 17:48 | 显示全部楼层
稍微进行10ms的消抖动处理,即可解决
回复

使用道具 举报

ID:1036367 发表于 2022-6-22 13:01 | 显示全部楼层
这个代码是全部了嘛
回复

使用道具 举报

ID:329625 发表于 2022-6-23 17:12 | 显示全部楼层
延时的话肯定会出问题,建议改成中断模式
回复

使用道具 举报

ID:161164 发表于 2022-6-24 15:27 | 显示全部楼层
  1. void Delay1ms()                //@12.000MHz
  2. {
  3.         unsigned char i, j;

  4.         i = 2;
  5.         j = 239;
  6.         do
  7.         {
  8.                 while (--j);
  9.         } while (--i);
  10. }
  11. void getkey(void)
  12. {
  13.         static unsigned char DelayXD = 0;
  14.     keyval = 0xff;
  15.     KEY = P3 & 0x0f;
  16.     if(KEY != 0xf)
  17.     {
  18.                         Delay1ms();
  19.         if(DelayXD<0xFF)DelayXD++;
  20.                         if(DelayXD == 20)
  21.                         {
  22.                                 KEY = P3 & 0x0f;
  23.         if(KEY != 0x0f)
  24.         {
  25.             switch(KEY)
  26.             {
  27.             case 0x0e:
  28.                 while(P3 & 0x0f == 0x0e);
  29.                 keyval = 1;
  30.                 break;
  31.             case 0x0d:
  32.                 while(P3 & 0x0f == 0x0d);
  33.                 keyval = 2;
  34.                 break;
  35.             case 0x0b:
  36.                 while(P3 & 0x0f == 0x0b);
  37.                 keyval = 3;
  38.                 break;
  39.             case 0x07:
  40.                 while(P3 & 0x0f == 0x07);
  41.                 keyval = 4;
  42.                 break;
  43.             default:
  44.                 break;
  45.             }
  46.         }
  47.                         }
  48.         
  49.     }else
  50.                 {
  51.                         DelayXD = 0;
  52.                 }
  53. }
复制代码


回复

使用道具 举报

ID:213173 发表于 2022-6-24 19:09 | 显示全部楼层
三岁而 发表于 2021-6-18 17:12
改了试了一下还是会抖动

给你改了,你试试。
测试程序 仿真.rar (87.48 KB, 下载次数: 11)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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