找回密码
 立即注册

QQ登录

只需一步,快速开始

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

我想按一下键盘就让数码管上的显数加1 单片机程序逻辑漏洞

[复制链接]
跳转到指定楼层
楼主
ID:632567 发表于 2020-5-31 17:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我想按一下键盘就让数码管上的显数加1,但是实际却是这样显示的,自己也没找到逻辑漏洞,实际视频和原理图已上传 网址 https://v.youku.com/v_show/id_XN ... hcb.playlsit.page.1
程序:
#include<reg52.h>
sbit key1=P3^4;
sbit dula=P2^6;
sbit wela=P2^7;
#define uint unsigned int
#define uchar unsigned char
uchar i,bai,shi,ge;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z)
{        
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}


void main()
{        
        P3=0xff;//P3口全部送高电平        
         i=0;
        while(1)
        {        
                bai=i/100;
                shi=i%100/10;           
                ge=i%10;
                if(key1==0)//按下键盘时键盘端接地为低电平
                {        i++;                 
                        delay(10);//消抖
                        while(!key1);//对键盘进行松手检查
                        delay(10);//消抖
                        if(i<=10)
                {        
                        wela=1;
                        P0=0xfe;//第一个数码管亮
                        wela=0;
                        dula=1;
                        P0=table[ge];
                        dula=0;
                        delay(10);
                }
                        if(10<i&&i<100)
                {        
                        dula=1;
                        P0=table[ge];
                        dula=0;
                        P0=0xff;
                        wela=1;
                        P0=0xfd;//第二个数码管亮
                        wela=0;
                        delay(10);

                        dula=1;
                        P0=table[shi];
                        dula=0;
                        wela=1;
                        P0=0xfe;
                        wela=0;
                        delay(5);                        
                }
                        /*if(i==100)
                {

                        dula=1;
                        P0=table[bai];
                        dula=0;
                        wela=1;
                        P0=0xfe;
                        wela=0;
                        P0=0xff;
                        delay(5);

                          dula=1;
                        P0=table[shi];
                        dula=0;
                        wela=1;
                        P0=0xfd;
                        wela=0;
                        P0=0xff;
                        delay(5);

                        dula=1;
                        P0=table[ge];
                        dula=0;
                        wela=1;
                        P0=0xfb;
                        wela=0;
                        P0=0xff;
                        delay(5);
                        i=0;
                        while(!key1);
                        delay(10);
                        i=0;
                }*/
            }
                           
        }
        
}
   


TX-1C型单片机开发板原理图.pdf

1015.98 KB, 下载次数: 4

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

使用道具 举报

沙发
ID:686782 发表于 2020-6-2 10:44 | 只看该作者
你的数码管在没有按键按下事件时只给了高位显示,并没有进行扫描。
所以只有当按下按键时数码管低位会跳过短暂的显示,这之后就一直保留着高位位选打开的状态,并没有再对低位进行显示。
回复

使用道具 举报

板凳
ID:764107 发表于 2020-6-2 16:37 | 只看该作者
楼上的説得对,像这种就应该将显示和按钮扫描分开,你讲按钮执行里面的显示全部弄到外面就行了
回复

使用道具 举报

地板
ID:213173 发表于 2020-6-2 18:35 | 只看该作者
不能用按键松手死循环等待while(!key1);,会影响数码管动态显示,郭天祥的类似示例只为说明一个道理,完全不能实战,楼主这程序只要小改一下问题都解决了。
  1. #include<reg52.h>
  2. sbit key1=P3^4;
  3. sbit dula=P2^6;
  4. sbit wela=P2^7;
  5. #define uint unsigned int
  6. #define uchar unsigned char
  7. uchar i,j,bai,shi,ge;
  8. uchar code table[]={
  9. 0x3f,0x06,0x5b,0x4f,
  10. 0x66,0x6d,0x7d,0x07,
  11. 0x7f,0x6f,0x77,0x7c,
  12. 0x39,0x5e,0x79,0x71};

  13. void delay(uint z)
  14. {        
  15.         uint x,y;
  16.         for(x=z;x>0;x--)
  17.                 for(y=110;y>0;y--);
  18. }


  19. void main()
  20. {        
  21.         P3=0xff;//P3口全部送高电平        
  22.         i=0;
  23.         while(1)
  24.         {
  25.                 if(key1==0)//按下键盘时键盘端接地为低电平
  26.                 {                        
  27.                         j++;//消抖
  28.                         if(key1==0&&j==2)
  29.                         {
  30.                                 j=2;
  31.                                 i++;
  32.                                 if(i>99)
  33.                                         i=0;
  34.                                 shi=i/10;           
  35.                                 ge        =i%10;
  36.                         }      
  37.                 }
  38.                 else j=0;//松手

  39.                 wela=1;
  40.                 P0=0xfe;//第一个数码管亮
  41.                 wela=0;
  42.                 dula=1;
  43.                 P0=table[shi];
  44.                 dula=0;
  45.                 delay(5);
  46.                
  47.                 wela=1;
  48.                 P0=0xfd;//第二个数码管亮
  49.                 wela=0;
  50.                 dula=1;
  51.                 P0=table[ge];
  52.                 dula=0;
  53.                 delay(5);
  54.         }       
  55. }

复制代码

回复

使用道具 举报

5#
ID:332444 发表于 2020-6-3 09:19 | 只看该作者
回复

使用道具 举报

6#
ID:632567 发表于 2020-6-4 20:11 | 只看该作者
wulin 发表于 2020-6-2 18:35
不能用按键松手死循环等待while(!key1);,会影响数码管动态显示,郭天祥的类似示例只为说明一个道理,完全 ...

为什么j++可以消抖呢?
回复

使用道具 举报

7#
ID:632567 发表于 2020-6-4 20:19 | 只看该作者
specialClass 发表于 2020-6-2 16:37
楼上的説得对,像这种就应该将显示和按钮扫描分开,你讲按钮执行里面的显示全部弄到外面就行了

额,我没听懂但是把显示函数调出后确实可以了
回复

使用道具 举报

8#
ID:213173 发表于 2020-6-5 06:51 | 只看该作者
单片机在想peach 发表于 2020-6-4 20:11
为什么j++可以消抖呢?

一旦按键按下,j++,j就=1,由于显示程序占用主循环时间大于10ms,等到再次判断按键状态时抖动时间已越过,所以j==2确认键被按下,否则没有按下j清0。如果主循环周期短,判断次数相应增加。如果程序写得效率高主循环时间一般不大于1ms,这样j就要以100~200判断。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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