找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1651|回复: 19
收起左侧

单片机按键数字显示8会多一个点?代码怎么改

[复制链接]
ID:976910 发表于 2021-11-9 18:57 | 显示全部楼层 |阅读模式
单片机按键实验,有两个问题想请教
1.如图,只有8多了一个小点,但是不知道代码如何改才能去掉小点?
2.独立按键k3,k4没有反应,只有1,2可以控制,代码如何改。代码放在这里,感谢。
51hei图片_20211109185136.jpg 51hei图片_20211109185142.jpg
单片机源程序如下:
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit DU = P2^6;//数码管段选
  6. sbit WE = P2^7;//数码管段选
  7. sbit key_s2 = P3^0;//独立按键S2
  8. sbit key_s3 = P3^1;//独立按键S3
  9. sbit key_s4 = P3^2;//独立按键S4
  10. sbit key_s5 = P3^3;//独立按键S5
  11. sbit beep=P2^3;
  12. uchar num;//数码管显示的值

  13. //共阴数码管段选表0-9
  14. uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
  15. uchar i;


  16. //毫秒级延时函数定义
  17. void delay(uint z)
  18. {
  19.         uint x,y;
  20.         for(x = z; x > 0; x--)
  21.                 for(y = 114; y > 0 ; y--);                 
  22. }

  23. void main()
  24. {
  25.         WE = 1;//打开位选锁存器
  26.         P0 = 0XFE; //1111 1110
  27.         WE = 0;//锁存位选数据
  28.         
  29.         while(1)
  30.         {
  31.                 if(key_s2 == 0)//判断S2是否被按下
  32.                 {
  33.                         delay(20);//按键消抖
  34.                         if(key_s2 == 0)
  35.                         {
  36.                                 if(num != 9)//如果值不等于9则+1,功能把值限定为小于9
  37.                                 num++;
  38.                                 while(!key_s2);//松手检测
  39.                         }        
  40.                 }
  41.                 if(key_s3 == 0)//判断S3是否被按下
  42.                 {
  43.                         delay(20);//按键消抖
  44.                         if(key_s3 == 0)
  45.                         {
  46.                                 if(num > 0)        //如果大于0则执行减一
  47.                                         num--;
  48.                                 while(!key_s3);//松手检测
  49.                         }        
  50.                 }
  51.                 //松手之后刷新显示
  52.                 DU = 1;//打开段选锁存器
  53.                 P0 = tabel[num];//
  54.                 DU = 0;//锁存段选数据

  55.                 if(key_s4==0)//判断S3是否被按下
  56.                 {
  57.                   delay(20); //按键消抖
  58.                   if(key_s4==0)
  59.                   {
  60.                     //while(key_s4==0)//按下S3时循环这个LED灯
  61.                          while(key_s2==1&&key_s3==1&&key_s5==1)//按下S3时循环这个LED灯
  62.                         {
  63.                         P1=0x7e;
  64.             delay(150);
  65.             P1=0xbd;
  66.             delay(150);
  67.             P1=0xdb;
  68.             delay(150);
  69.             P1=0xe7;
  70.             delay(150);
  71.             P1=0x00;
  72.             delay(150);
  73.                    }
  74.                         while(key_s2==0||key_s3==0||key_s5==0);        //松手检测
  75.                         {
  76.                   P1=0xff;
  77.                 }
  78.                   }
  79.                  
  80.                     
  81.                 }
  82.                 if(key_s5==0)
  83.                 {
  84.                           delay(20);
  85.                         if(key_s5==0)
  86.                         {
  87.                           beep=0;
  88.                         }
  89.                         while(!key_s5);
  90.                 }
  91.         }        
  92. }  
复制代码


回复

使用道具 举报

ID:624769 发表于 2021-11-9 20:00 | 显示全部楼层
       WE = 1;//打开位选锁存器
        P0 = 0XFE; //1111 1110
        WE = 0;//锁存位选数据

这里的 P0 = 0;    8个灯都开看看情况,是每个8都多点,还是只有第一个 8 多点。
回复

使用道具 举报

ID:220661 发表于 2021-11-9 20:10 | 显示全部楼层
uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
修改这里的第9个
回复

使用道具 举报

ID:883242 发表于 2021-11-9 20:35 | 显示全部楼层
gongnn 发表于 2021-11-9 20:10
uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
修改这里的第9个

0x7f没错,问题肯定不在这里。
回复

使用道具 举报

ID:976910 发表于 2021-11-9 21:49 | 显示全部楼层
188610329 发表于 2021-11-9 20:00
WE = 1;//打开位选锁存器
        P0 = 0XFE; //1111 1110
        WE = 0;//锁存位选数据

还是不对,0到8有点,8到0也有点,每个8都有
回复

使用道具 举报

ID:976910 发表于 2021-11-9 21:53 | 显示全部楼层
Hephaestus 发表于 2021-11-9 20:35
0x7f没错,问题肯定不在这里。

大哥认为错在哪里?可以指点一下吗
回复

使用道具 举报

ID:624769 发表于 2021-11-9 22:08 | 显示全部楼层
茴香打卤面 发表于 2021-11-9 21:49
还是不对,0到8有点,8到0也有点,每个8都有

我知道不对,我只是看看是电路问题,还是数码管问题,现在基本可以认为是电路问题了,

你把这句:                P0 = tabel[num];//
变成 P0= 0x80;  看看除了  点, 还有哪个段会亮?(正常的话,应该只有点会亮)
回复

使用道具 举报

ID:213173 发表于 2021-11-10 06:55 | 显示全部楼层
茴香打卤面 发表于 2021-11-9 21:53
大哥认为错在哪里?可以指点一下吗

楼主没有按照实验板实际电路写程序,出现奇怪现象是必然的。建议楼主先用此板配套示例程序测试,熟悉后再按自己意图修改。随便把别人的程序加自己意图胡乱修改不会取得成功。给楼主按普中实验板电路修改代码,基本符合楼主意图。
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. //sbit DU = P2^6;//数码管段选
  6. //sbit WE = P2^7;//数码管段选
  7. sbit key_s1 = P3^1;//独立按键S1
  8. sbit key_s2 = P3^0;//独立按键S2
  9. sbit key_s3 = P3^2;//独立按键S3
  10. sbit key_s4 = P3^3;//独立按键S4
  11. sbit beep=P1^5;
  12. uchar num;//数码管显示的值

  13. //共阴数码管段选表0-9
  14. uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
  15. uchar i;


  16. //毫秒级延时函数定义
  17. void delay(uint z)
  18. {
  19.         uint x,y;
  20.         for(x = z; x > 0; x--)
  21.                 for(y = 114; y > 0 ; y--);
  22. }

  23. void main()
  24. {
  25.         beep=0;
  26. //        WE = 1;//打开位选锁存器
  27.         P0 = tabel[num];
  28. //        WE = 0;//锁存位选数据       
  29.         while(1)
  30.         {
  31.                 if(key_s1 == 0)//判断S2是否被按下
  32.                 {
  33.                         delay(20);//按键消抖
  34.                         if(key_s1 == 0)
  35.                         {
  36.                                 if(num < 9)//如果值不等于9则+1,功能把值限定为小于9
  37.                                 {
  38.                                         num++;
  39.                                         P0 = tabel[num];
  40.                                 }
  41.                                 while(!key_s1);//松手检测
  42.                         }        
  43.                 }
  44.                 if(key_s2 == 0)//判断S3是否被按下
  45.                 {
  46.                         delay(20);//按键消抖
  47.                         if(key_s2 == 0)
  48.                         {
  49.                                 if(num > 0)        //如果大于0则执行减一
  50.                                 {
  51.                                         num--;
  52.                                         P0 = tabel[num];
  53.                                 }
  54.                                 while(!key_s2);//松手检测
  55.                         }        
  56.                 }
  57.                 //松手之后刷新显示
  58. //                DU = 1;//打开段选锁存器
  59. //                P0 = tabel[num];//
  60. //                DU = 0;//锁存段选数据
  61.        
  62.                 if(key_s3==0)//判断S3是否被按下
  63.                 {
  64.                         delay(20); //按键消抖
  65.                         if(key_s3==0)
  66.                         {
  67.                                 //while(key_s4==0)//按下S3时循环这个LED灯
  68.                                 while(!key_s3)//按下S3时循环这个LED灯
  69.                                 {
  70.                                         P0 = 0x00;//关闭数码管
  71.                                         P2=~(0x01<<i);//流水灯
  72.                                         delay(500);
  73.                                         i=++i%8;//循环计数
  74.                                 }
  75. //                                while(key_s1==0||key_s2==0||key_s4==0);        //松手检测
  76. //                                {
  77.                                 i=0;//清0
  78.                                 P0 = tabel[num];//开数码管
  79.                                 P2=0xff;//关闭流水灯
  80. //                                }
  81.                         }
  82.                 }
  83.                 if(key_s4==0)
  84.                 {
  85.                         delay(20);
  86.                         if(key_s4==0)
  87.                         {
  88.                                 beep=1;
  89.                         }
  90.                         while(!key_s4);
  91.                         beep=0;
  92.                 }
  93.         }        
  94. }  
复制代码
回复

使用道具 举报

ID:976910 发表于 2021-11-10 12:34 | 显示全部楼层
wulin 发表于 2021-11-10 06:55
楼主没有按照实验板实际电路写程序,出现奇怪现象是必然的。建议楼主先用此板配套示例程序测试,熟悉后再 ...

感谢回复,但是问题没有解决。8还是会有点,每个8都有,且独立按键3虽然有反应,但是只是对数字闪烁了一下,按键4还是没有反应
回复

使用道具 举报

ID:213173 发表于 2021-11-10 14:00 | 显示全部楼层
茴香打卤面 发表于 2021-11-10 12:34
感谢回复,但是问题没有解决。8还是会有点,每个8都有,且独立按键3虽然有反应,但是只是对数字闪烁了一 ...

这是按普中的相关电路做的仿真
无标题.jpg

回复

使用道具 举报

ID:976910 发表于 2021-11-10 16:04 来自手机 | 显示全部楼层
188610329 发表于 2021-11-9 22:08
我知道不对,我只是看看是电路问题,还是数码管问题,现在基本可以认为是电路问题了,

你把这句:     ...

一个警告
B0DC5413-3D55-4412-82C4-1B278B63E282.jpeg
回复

使用道具 举报

ID:976910 发表于 2021-11-10 16:07 来自手机 | 显示全部楼层
wulin 发表于 2021-11-10 14:00
这是按普中的相关电路做的仿真

很厉害,虽然我看不懂
回复

使用道具 举报

ID:624769 发表于 2021-11-10 16:34 | 显示全部楼层

警告不用管,没有调用那个数组,只要恢复那个  P0 = tabel[num];  警告就没了,你照着这样写进单片机,看看除了 .  还有什么段是亮的, 好分析是什么位子出了问题, 基本可以确定,你程序没有问题,是板子的硬件问题。就看看有没有可能自己排除。
回复

使用道具 举报

ID:976910 发表于 2021-11-10 17:34 | 显示全部楼层
188610329 发表于 2021-11-10 16:34
警告不用管,没有调用那个数组,只要恢复那个  P0 = tabel[num];  警告就没了,你照着这样写进单片机, ...

是的,只有点亮了
回复

使用道具 举报

ID:624769 发表于 2021-11-10 17:48 | 显示全部楼层

我怀疑…… 锁存器这里可能有问题,当拉高多的引脚电平时会把 7 脚位一起拉高。

DU = 1;//打开段选锁存器
P0 = tabel[num];//
_nop_();
_nop_();                       <=  你在这里 加两个nop 看看能不能有效果, 如果有效就凑活着用,如果无效,只能联系卖家看能不能换了,这个属于硬件问题了。
DU = 0;//锁存段选数据
回复

使用道具 举报

ID:976910 发表于 2021-11-10 21:19 | 显示全部楼层
188610329 发表于 2021-11-10 17:48
我怀疑…… 锁存器这里可能有问题,当拉高多的引脚电平时会把 7 脚位一起拉高。

DU = 1;//打开段选锁 ...

你这里的 <= 加上后目标未创建,去掉后才可以运行。但是还是没有把.去掉。可是这个代码在别的单片机上也是有.的
回复

使用道具 举报

ID:213173 发表于 2021-11-11 06:43 | 显示全部楼层
茴香打卤面 发表于 2021-11-10 16:07
很厉害,虽然我看不懂

楼主什么看不懂?电路看不懂还是代码看不懂?在8楼回复的文字总该能看懂吧。你这个程序可以在天祥实验板上运行,不可以在普中实验板上运行。因为两者单片机虽然相同但其它外围电路差异很大。这是用你的原程序按天祥的相关电路做的仿真,只改了按键端口定义和添加beep=1复位,其它未做任何改动。你探讨其它细枝末叶都是隔靴瘙痒。 无标题.jpg
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define uint unsigned int
  4. #define uchar unsigned char

  5. sbit DU = P2^6;//数码管段选
  6. sbit WE = P2^7;//数码管段选
  7. sbit key_s2 = P3^4;//独立按键S2
  8. sbit key_s3 = P3^5;//独立按键S3
  9. sbit key_s4 = P3^6;//独立按键S4
  10. sbit key_s5 = P3^7;//独立按键S5
  11. sbit beep=P2^3;
  12. uchar num;//数码管显示的值

  13. //共阴数码管段选表0-9
  14. uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};
  15. uchar i;


  16. //毫秒级延时函数定义
  17. void delay(uint z)
  18. {
  19.         uint x,y;
  20.         for(x = z; x > 0; x--)
  21.         for(y = 114; y > 0 ; y--);                 
  22. }

  23. void main()
  24. {
  25.         WE = 1;//打开位选锁存器
  26.         P0 = 0XFE; //1111 1110
  27.         WE = 0;//锁存位选数据
  28.        
  29.         while(1)
  30.         {
  31.                 if(key_s2 == 0)//判断S2是否被按下
  32.                 {
  33.                         delay(20);//按键消抖
  34.                         if(key_s2 == 0)
  35.                         {
  36.                                 if(num != 9)//如果值不等于9则+1,功能把值限定为小于9
  37.                                 num++;
  38.                                 while(!key_s2);//松手检测
  39.                         }        
  40.                 }
  41.                 if(key_s3 == 0)//判断S3是否被按下
  42.                 {
  43.                                 delay(20);//按键消抖
  44.                         if(key_s3 == 0)
  45.                         {
  46.                                 if(num > 0)        //如果大于0则执行减一
  47.                                         num--;
  48.                                 while(!key_s3);//松手检测
  49.                         }        
  50.                 }
  51.                 //松手之后刷新显示
  52.                 DU = 1;//打开段选锁存器
  53.                 P0 = tabel[num];//
  54.                 DU = 0;//锁存段选数据
  55.        
  56.                 if(key_s4==0)//判断S3是否被按下
  57.                 {
  58.                         delay(20); //按键消抖
  59.                         if(key_s4==0)
  60.                         {
  61.                                 //while(key_s4==0)//按下S3时循环这个LED灯
  62.                                 while(key_s2==1&&key_s3==1&&key_s5==1)//按下S3时循环这个LED灯
  63.                                 {
  64.                                         P1=0x7e;
  65.                                         delay(150);
  66.                                         P1=0xbd;
  67.                                         delay(150);
  68.                                         P1=0xdb;
  69.                                         delay(150);
  70.                                         P1=0xe7;
  71.                                         delay(150);
  72.                                         P1=0x00;
  73.                                         delay(150);
  74.                                 }
  75.                                 while(key_s2==0||key_s3==0||key_s5==0);        //松手检测
  76.                                 {
  77.                                         P1=0xff;
  78.                                 }
  79.                         }
  80.                 }
  81.                 if(key_s5==0)
  82.                 {
  83.                         delay(20);
  84.                         if(key_s5==0)
  85.                         {
  86.                                 beep=0;
  87.                         }
  88.                         while(!key_s5);
  89.                         beep=1;
  90.                 }
  91.         }        
  92. }  
复制代码








回复

使用道具 举报

ID:824490 发表于 2021-11-11 09:17 | 显示全部楼层
一天多了。还没搞定?
如果只是LED乱显示,这个故障其实用很简单的方法就能找出问题所在了:
代码先所有段不亮,再一段一段地点亮,看实际效果,
所有段不点亮,但“DP”还是亮了,说明硬件肯定坏了。重点就在锁存器;
一段一段地点,只有某段亮时,“DP”亮了,说明该段与“DP”存在短路,可能是PCB、也可能是锁存器;
如果都是正常的,说明是之前的代码有问题。
回复

使用道具 举报

ID:624769 发表于 2021-11-11 20:53 | 显示全部楼层

你说的,在别的“单片机”上,是指别的单片机装在这块板子上,还是这个代码,写到另一块同样板子的单片机上?
回复

使用道具 举报

ID:690831 发表于 2021-11-12 03:08 | 显示全部楼层
主函数里最简化,只写
P0=0x00;
烧进单片机通电,用万用表测试P0八个管脚电平和对应排针的电平,正常情况应该都是低电平。如果有异常,就要自己跑电路了
还有要注意就是,把除了P30和P31之外的无用连接拔掉。我看到是红圈圈里的跳线,红外接收器,温度IC,或者还有其他,自己检查。
185154fau2mzyu0zjy429u.jpg



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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