找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2410|回复: 13
收起左侧

单片机6个数码管动态显示程序问题

[复制链接]
ID:1048353 发表于 2022-10-22 15:49 | 显示全部楼层 |阅读模式
利用动态扫描的方式在6个数码管上显示出稳定的654321;
但是如图6个数码管显示出错了;
单片机代码如下,请问是哪里的问题
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
sbit dula=P2^7;
sbit wela=P2^6;
uchar num,numwe,numdu;
void init();
void main()
{
        numwe=0xfe;
        numdu=8;
        init();//初始化子程序

        while(1)
        {
               
        }
}
void init()//设置定时器方式来达到动态显示效果
{
        TMOD=0x01;
        TH0=(65336-500)/256;
        TL0=(65336-500)%256;
        EA=1;
        ET0=1;
        TR0=1;
}
void timer0() interrupt 1
{
        TH0=(65336-500)/256;
        TL0=(65336-500)%256;
        num++;
        if(num==1)
        {
                num=0;
                numdu--;
                if(numdu==0)
                numdu=8;
                dula=1;//送段选数据
                P0=table[numdu];//赋值6,5,4,3,2,1显示
                dula=0;
                P0=0xff;//消影
                wela=1;//送位选数据
                P0=numwe;
                numwe=_crol_(numwe,1);//循环左移1位,使6个数码管轮流显示
                wela=0;
                if(numwe==0xbf)
                numwe=0xfe;
               
        }
}

51hei图片_20221022154538.jpg
回复

使用道具 举报

ID:1007932 发表于 2022-10-22 18:52 | 显示全部楼层
讲真看不懂你的中断程序,这个num有啥用?还有P0=table[numdu];中的numdu确定是在1-6之间循环?另外把驱动芯片型号发一下。
回复

使用道具 举报

ID:1048353 发表于 2022-10-22 19:00 | 显示全部楼层
一事无成 发表于 2022-10-22 18:52
讲真看不懂你的中断程序,这个num有啥用?还有P0=table[numdu];中的numdu确定是在1-6之间循环?另外把驱动 ...

芯片是89C52RC;P0=table[numdu]这我就是想不明白哪里出错了;中断程序设置的是5ms,来达到数码管动态显示的目的;
这个是郭天祥10天入门单片机里的例题,这个出错的是我的解法
回复

使用道具 举报

ID:1048353 发表于 2022-10-22 19:01 | 显示全部楼层
/*******************************************************************/
/* TX-1C单片机实验板实验例程                                                                   */
/*******************************************************************/
/*                                                         
利用动态扫描方法在六位数码管上显示出稳定的654321.
时钟频率为11.0592M
*/
/*********************************************************/
#include<reg52.h>  //52单片机头文件
#include <intrins.h> //包含有左右循环移位子函数的库
#define uint unsigned int    //宏定义
#define uchar unsigned char  //宏定义
sbit dula=P2^6;       //数码管段选锁存端
sbit wela=P2^7;       ////数码管位选锁存端
uchar code table[]={   //数码管显示编码
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void display(uchar,uchar,uchar,uchar,uchar,uchar); //函数声明
void delay(uint);
void main()
{
        while(1)
        {
                display(6,5,4,3,2,1);         //始终显示
        }
}

void display(uchar one,uchar two,uchar three,uchar four,uchar five,uchar six)
{
        dula=1;
                P0=table[one];   //送段数据
                dula=0;
                P0=0xff;                //送位数据前关闭所有显示,防止打开位选锁存后段选数据通过位选锁存器
                wela=1;
                P0=0xfe;
                wela=0;
                delay(1);

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

                dula=1;
                P0=table[three];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0xfb;
                wela=0;
                delay(1);

                dula=1;
                P0=table[four];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0xf7;
                wela=0;
                delay(1);

                dula=1;
                P0=table[five];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0xef;
                wela=0;
                delay(1);

                dula=1;
                P0=table[six];
                dula=0;
                P0=0xff;
                wela=1;
                P0=0xdf;
                wela=0;
                delay(1);
}

void delay(uint z)       //延时子函数
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
回复

使用道具 举报

ID:1048353 发表于 2022-10-22 19:31 | 显示全部楼层
上面是郭天祥老师的解法
回复

使用道具 举报

ID:161164 发表于 2022-10-22 20:29 | 显示全部楼层
P0=0xFF;消影消了个寂
正确写法该是
wela=1
P0=0xff
wela=0
dula=1
P0=table
dula=0
wela=1
P0=numwe
wela=0
回复

使用道具 举报

ID:1048353 发表于 2022-10-22 22:08 | 显示全部楼层
lkc8210 发表于 2022-10-22 20:29
P0=0xFF;消影消了个寂寞
正确写法该是
wela=1

        num=0;
                numdu--;
                wela=1;
                P0=0xff;
                wela=0;
                if(numdu==0)
                numdu=8;
                dula=1;//送段选数据
                P0=table[numdu];//赋值6,5,4,3,2,1显示
                dula=0;
                //P0=0xff;//消影
                wela=1;//送位选数据
                P0=numwe;
                numwe=_crol_(numwe,1);//循环左移1位,使6个数码管轮流显示
                wela=0;
                if(numwe==0xbf)
                numwe=0xfe;
回复

使用道具 举报

ID:1048353 发表于 2022-10-22 22:15 | 显示全部楼层

这样消影?但是如图的话,动态显示654321还是不行啊
51hei图片_20221022221232.jpg
回复

使用道具 举报

ID:213173 发表于 2022-10-23 08:22 | 显示全部楼层
86爆缸 发表于 2022-10-22 22:15
这样消影?但是如图的话,动态显示654321还是不行啊

用位消隐和段消隐都一样有效,楼主用500us周期扫描速度太快,削弱了消隐效果。通常扫描一轮不低于20ms不会看出闪烁。一般每个数码管显示1ms,6ms完成一轮扫描为宜。
123.jpg



代码修改如下:
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. #define uint unsigned int
  4. #define uchar unsigned char
  5. uchar code table[]={
  6. 0x3f,0x06,0x5b,0x4f,
  7. 0x66,0x6d,0x7d,0x07,
  8. 0x7f,0x6f,0x77,0x7c,
  9. 0x39,0x5e,0x79,0x71};
  10. sbit dula=P2^6;
  11. sbit wela=P2^7;
  12. uchar num;//numwe,numdu;
  13. void init();
  14. void main()
  15. {
  16. //        numwe=0xfe;
  17. //        numdu=8;
  18.         init();//初始化子程序
  19.        
  20.         while(1)
  21.         {
  22.        
  23.         }
  24. }
  25. void init()//设置定时器方式来达到动态显示效果
  26. {
  27.         TMOD=0x01;
  28.         TH0=(65536-1000)/256;
  29.         TL0=(65536-1000)%256;
  30.         EA=1;
  31.         ET0=1;
  32.         TR0=1;
  33. }
  34. void timer0() interrupt 1
  35. {
  36.         TH0=(65536-1000)/256;
  37.         TL0=(65536-1000)%256;

  38.         num++;
  39.         if(num==6)
  40.                 num=0;

  41.         dula=1;
  42.         P0=0x00;//消影
  43.         dula=0;

  44.         wela=1;
  45.         P0=~(0x01<<num);//送位码
  46.         wela=0;

  47.         dula=1;
  48.         P0=table[6-num];//赋值6,5,4,3,2,1显示
  49.         dula=0;
  50. }
复制代码



回复

使用道具 举报

ID:121859 发表于 2022-10-23 09:06 | 显示全部楼层
定时器定时时间太短,将500改为2000到5000之间。另外显示应该先位码再段码
回复

使用道具 举报

ID:1048353 发表于 2022-10-23 11:28 | 显示全部楼层
zhxiufan 发表于 2022-10-23 09:06
定时器定时时间太短,将500改为2000到5000之间。另外显示应该先位码再段码

先位码后段码的话,段码未赋初值,当dula=1的时候,P0还是位选的数据,会先出现乱码吧,所以我才先段码后位码的
回复

使用道具 举报

ID:1048353 发表于 2022-10-23 12:03 | 显示全部楼层
wulin 发表于 2022-10-23 08:22
用位消隐和段消隐都一样有效,楼主用500us周期扫描速度太快,削弱了消隐效果。通常扫描一轮不低于20ms不 ...

谢谢大佬,你的代码写的很漂亮,我定义的变量还是多了;
不过消影应该是P0=0xff,我这个是共阴极数码管;
同时我试了下用不用消影的区别,数码管显示都正常,没有乱码
回复

使用道具 举报

ID:1048353 发表于 2022-10-23 12:10 | 显示全部楼层
wulin 发表于 2022-10-23 08:22
用位消隐和段消隐都一样有效,楼主用500us周期扫描速度太快,削弱了消隐效果。通常扫描一轮不低于20ms不 ...

大佬你的代码我能看懂没问题,但我自己的代码试了下延长扫描周期,但就是没法显示和你一样的效果;
找不到我的代码错在哪里了
回复

使用道具 举报

ID:1048353 发表于 2022-10-23 12:15 | 显示全部楼层
wulin 发表于 2022-10-23 08:22
用位消隐和段消隐都一样有效,楼主用500us周期扫描速度太快,削弱了消隐效果。通常扫描一轮不低于20ms不 ...

我找到我代码的问题了,位选赋值那的if语句用错了,输出结果就是6个数码管流水灯亮,然后同时每个数码管都赋值6,5,4,3,2,1;难怪我这都是乱码了
回复

使用道具 举报

ID:1048353 发表于 2022-10-23 12:26 | 显示全部楼层
86爆缸 发表于 2022-10-23 12:15
我找到我代码的问题了,位选赋值那的if语句用错了,输出结果就是6个数码管流水灯亮,然后同时每个数码管 ...

试了下还是不行,我想我这个应该是定义的变量多了,扫描时间又短,段选位选多个变量造成的乱码?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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