找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机数码管显示程序 为什么1,2,5没有显示出来?而且顺序是乱的

[复制链接]
跳转到指定楼层
楼主
调不出来

1.png (44.87 KB, 下载次数: 101)

1.png

3.png (17.23 KB, 下载次数: 99)

3.png

2.png (28.46 KB, 下载次数: 110)

2.png

4.png (15.77 KB, 下载次数: 109)

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

使用道具 举报

沙发
ID:824490 发表于 2022-9-1 07:36 | 只看该作者
无语了~~~~这么个问题连续发了这么多贴。
你的代码 有问题!
1、573的OE脚本来是为消隐而生的,你把它接地了。代码中的消隐又是错的!
2、573的LE脚是电平触了,不是边沿触发,所以你的时序也有问题!
这个是匹配你电路图的代码,可以正常显示,你试试:

  1. #include <reg51.h>
  2. #include <stdio.h>
  3. #include <intrins.h>

  4. sbit d1=P2^0;       //锁存段码
  5. sbit d2=P2^1;      // 锁存位选

  6. unsigned  char dis_buf[8];  //显示缓存
  7. unsigned char dig;            //位选
  8. unsigned code segout[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};    //0--9共阳段码表

  9. void disp_8_num(void);

  10. void main(void)
  11. {
  12.     unsigned char i;
  13.     while (1)
  14.   {
  15.   
  16.     for(i=0;i<8;i++)  dis_buf[i]=i; //缓存刷新:01234567
  17.    
  18.      disp_8_num();  //显示一帧
  19.     }
  20. }

  21. void disp_8_num()
  22. {
  23.       unsigned char i,j;   
  24.   
  25.      dig=0xfe;  //从第一位开始扫显
  26.       for (i=0;i<8;i++)  //共8个位的数码管
  27.       {
  28.       
  29.         P0=segout[dis_buf[i]];   //送段码
  30.         d1=1;        
  31.         d1=0;
  32.      
  33.        P0=dig;    //送位码      
  34.        d2=1;      
  35.        d2=0;

  36.        j=60;     //延时以稳定显示
  37.        while(j--);

  38.        P0=0xff;    //消隐位码,段码和位码2选1或全选都可以
  39.        d2=1;
  40.        d2=0;
  41.       
  42.        P0=0x00;    //消隐段码
  43.        d1=1;
  44.        d1=0;     
  45.         
  46.        dig= _crol_(dig,1); //准备下一位的位码
  47.         }
  48.   }
复制代码



回复

使用道具 举报

板凳
ID:824490 发表于 2022-9-1 07:50 | 只看该作者
让你把代码或工程发上来也不做。。。。
也就是我闲的蛋疼,才会花时间画图、敲代码、仿真了。。
这个是Proteus8.13的仿真工程,你看一下。

74HC573.rar (19.45 KB, 下载次数: 5)

回复

使用道具 举报

地板
ID:155507 发表于 2022-9-1 08:00 | 只看该作者
你的位码不对

  1. #include <reg52.h>
  2. #define uchar unsigned char
  3. #define uint  unsigned int
  4. #define LEDPort P0
  5. uchar code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //数码管段码选表
  6. uchar code wei[] ={0xFE ,0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};         //数码管位码
  7. sbit DU = P2^0;
  8. sbit WE = P2^1;

  9. void delay(int z)
  10. {
  11.         int x,y;
  12.         for(x=50;x>0;x--)
  13.             for(y=z;y>0;y--);
  14. }

  15. void main()
  16. {
  17.         while(1)  
  18.         {       
  19.         WE = 1;
  20.         LEDPort = wei[0];
  21.         WE = 0;
  22.         DU = 1;
  23.         LEDPort = duan[ 1];
  24.         DU = 0;
  25.         delay(2);
  26.        
  27.         WE = 1;
  28.         LEDPort = wei[1];
  29.         WE = 0;
  30.         DU = 1;
  31.         LEDPort = duan[ 2 ];
  32.         DU = 0;
  33.         delay(2);
  34.        
  35.         WE = 1;
  36.         LEDPort = wei[2];
  37.         WE = 0;
  38.         DU = 1;
  39.         LEDPort = duan[ 3];
  40.         DU = 0;
  41.         delay(2);
  42.        
  43.         WE = 1;
  44.         LEDPort = wei[3];
  45.         WE = 0;
  46.         DU = 1;
  47.         LEDPort = duan[ 4];
  48.         DU = 0;
  49.         delay(2);
  50.        
  51.         WE = 1;
  52.         LEDPort = wei[4];
  53.         WE = 0;
  54.         DU = 1;
  55.         LEDPort = duan[ 5 ];
  56.         DU = 0;
  57.         delay(2);
  58.        
  59.         WE = 1;
  60.         LEDPort = wei[5];
  61.         WE = 0;
  62.         DU = 1;
  63.         LEDPort = duan[ 6];
  64.         DU = 0;
  65.         delay(2);        
  66.        
  67.         WE = 1;
  68.         LEDPort = wei[6];
  69.         WE = 0;
  70.         DU = 1;
  71.         LEDPort = duan[ 7 ];
  72.         DU = 0;
  73.         delay(2);
  74.        
  75.         WE = 1;
  76.         LEDPort = wei[7];
  77.         WE = 0;
  78.         DU = 1;
  79.         LEDPort = duan[ 8];
  80.         DU = 0;
  81.         delay(2);
  82.         }
  83. }



复制代码
回复

使用道具 举报

5#
ID:121859 发表于 2022-9-1 11:02 | 只看该作者
只要共阴共阳没有弄错,先送位码,再送段码,就会正确显示,不用消隐也可以的。
回复

使用道具 举报

6#
ID:824490 发表于 2022-9-1 11:06 | 只看该作者

你这个代码,我在Proteus中运行,显示 乱码。。
因为573的LE是高电平触发锁存的,所以,你这个时序有点不对:

        WE = 1;     //运行之后
                          //这时573已发生锁存,存的是上一次的LEDPort值
        LEDPort = wei[0]; //这个值要等到WE或DU为1时才会被锁存。
        WE = 0;
        DU = 1;               //按逻辑,这个运行过后LEDPort = wei[0];会被锁存到段驱573里
        LEDPort = duan[ 1]; //而这个值会被锁存到下一位的位驱573中。
        DU = 0;
        delay(2);


  欢迎探讨~~
回复

使用道具 举报

7#
ID:824490 发表于 2022-9-1 11:14 | 只看该作者
zhxiufan 发表于 2022-9-1 11:02
只要共阴共阳没有弄错,先送位码,再送段码,就会正确显示,不用消隐也可以的。

“。。。。先送位码,再送段码。。。。。”

不用消隐的话,你显示12345678时, 显示第1位“1”之后,第2位在刷显时也会显示“1”,之后才显示“2”。
你分析一下~或单步跟踪一下就能看出来了。
回复

使用道具 举报

8#
ID:278457 发表于 2022-9-1 13:20 | 只看该作者
谢谢各位了
回复

使用道具 举报

9#
ID:213173 发表于 2022-9-1 15:33 | 只看该作者


  1. #include <reg52.h>
  2. unsigned char code duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00}; //数码管段码
  3. sbit DU = P2^0;
  4. sbit WE = P2^1;

  5. void delay_ms(unsigned int t)//12T@12MHz
  6. {
  7.         unsigned int i,j;
  8.         for(i=t;i>0;i--)
  9.                 for(j=120;j>0;j--);
  10. }

  11. void main()
  12. {
  13.         unsigned char i;
  14.         while(1)  
  15.         {        
  16.                 P0=0x00;       DU=1;DU=0;//消隐       
  17.                 P0=~(0x01<<i); WE=1;WE=0;//段码
  18.                 P0=duan[i];    DU=1;DU=0;//位码
  19.                 i=++i%8;//循环计数
  20.                 delay_ms(1);//延时
  21.         }
  22. }

复制代码



回复

使用道具 举报

10#
ID:155507 发表于 2022-9-1 18:48 | 只看该作者
名字不是重点 发表于 2022-9-1 11:06
你这个代码,我在Proteus中运行,显示 乱码。。
因为573的LE是高电平触发锁存的,所以,你这个时序有点 ...

如果你比较 LE 和 CP 两个 Pin 你会发现它们是完全不同的,74HC573 只需要一个高电平来激活 D 锁存器,而 74HC374 需要一个低到高电平的时钟来锁存 D 触发器。
573:“当 LATCH ENABLE (LE) 引脚为高电平时,Q 输出跟随 D 输入。当 LE 变为低电平时,D 输入端的数据将保留在输出端”
574:“D 输入的数据......在 CLOCK (CK) 输入的正向转换时传输到 Q 输出。”
回复

使用道具 举报

11#
ID:824490 发表于 2022-9-1 21:34 | 只看该作者
angmall 发表于 2022-9-1 18:48
如果你比较 LE 和 CP 两个 Pin 你会发现它们是完全不同的,74HC573 只需要一个高电平来激活 D 锁存器,而 ...

所以,573是电平触发锁存,在LE高电平之前,数据必需先准备好:
  P0=data;  // 先备好数据
  LE=1;    // LE高电平时,锁存使能,P0口数据(即data)被存入573内部,
                 //如果OE被接地,573此时的输出将会是data;OE是高则573输出高阻
  LE=0;    // LE低电平时,锁存失能,573内部的数据不再受到P0口电平的影响,即保持原数据
而574是边沿触发锁存,(在CP的上升沿,将D的状态传到Q),所以574要这样(类似74HC595):
  CP=0;    // 拉低CP
  P0=data;//传数据
  CP=1;      //拉高CP,产生一个上升沿
如果是这样:
  P0=data;//传数据
  CP=0;    // 拉低CP
  //// //可能在此处产生中断
  CP=1;      //拉高CP,产生一个上升沿
也可以,但代码不强壮,无法保证在CP=0之后的某种中断,改变P0的值,当中断恢复后的CP=1,锁存了错误的数据
回复

使用道具 举报

12#
ID:278457 发表于 2022-9-2 01:45 | 只看该作者
调试成功!太感谢了爱你们
回复

使用道具 举报

13#
ID:278457 发表于 2022-9-2 01:46 | 只看该作者

特别感谢你
回复

使用道具 举报

14#
ID:1023753 发表于 2022-9-2 08:02 | 只看该作者
名字不是重点 发表于 2022-9-1 11:06
你这个代码,我在Proteus中运行,显示 乱码。。
因为573的LE是高电平触发锁存的,所以,你这个时序有点 ...

他应该不需要锁存  只是当驱动提供电流用
回复

使用道具 举报

15#
ID:883242 发表于 2022-9-2 13:35 | 只看该作者

也感谢你
回复

使用道具 举报

16#
ID:213173 发表于 2022-9-2 14:25 | 只看该作者
haiyang201 发表于 2022-9-2 08:02
他应该不需要锁存  只是当驱动提供电流用

不锁存,P0怎么复用分别控制段码和位码?你有什么高招分享出来。
回复

使用道具 举报

17#
ID:278457 发表于 2022-9-5 02:50 | 只看该作者

我调试出来了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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