微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求助 关于80C51 单片机数码管动态扫描

求助 关于80C51 单片机数码管动态扫描

时间:10-02 整理:3721RD 点击:
大家好,本人为新入门学习单片机,购买了郭天祥老师学习板用于学习,在学到数码管动态扫描时自己写了个程序,
题:利用动态扫描方法在六位数码管上显示出稳定的654321

但是在运行时出现如下问题:       第一个数码管显示0和6,第二个数码管显示6和5,第三个数码管显示5和4,第四个数码管显示4和3,第五个数码管显示3和2,第六个数码管显示2和1,每个数码管会延时显示2个数字,然后跳到下一个数码管,依次循环;
请大神指出程序中存在问题,在此表示感谢
程序如下:

#include<reg52.h>
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
uchar a,num;//定义变量
sbit duan=P2^6;//数码管段选锁存器控制I/O口
sbit wei=P2^7;//数码管位选锁存器控制I/O口
uchar code table[]={//数码管段选ROM 存储区数据(6.5.4.3.2.1)
0x7d,0x6d,0x66,0x4f,0x5b,0x06};
uchar code tablewei[]={//数码管位选ROM存储区数据(1.2.3.4.5.6)
0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
void delay(uint z)//延时程序
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void main()
{
        while(1)
        {
                  wei=1;//选择第一个数码管
                P0=tablewei[num];
                wei=0;
                delay(5);
       
                duan=1;//第一个数码管发送数据
                P0=table[num];
                duan=0;
                delay(5);
                num++;
                if(num==6)
                        num=0;               
        }       
}

/*******************************************************************/
/* TX-1C单片机实验板实验例程                                                                   */
/* 2007年8月第二期培训班课后习题详解                                                           */
/* 作者:郭天祥                                                                                                 */
/* 邮箱:txmcu@163.com                                                                                              */
/* 网站:www.txmcu.com(天祥电子)                                                               */
/*【版权】Copyright(C)天祥电子 www.txmcu.com  All Rights Reserved  */
/*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!       */
/*                                                                 */
/*******************************************************************/
/*                                                         
利用动态扫描方法在六位数码管上显示出稳定的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--);
}

我感觉应该是位码问题,你这个是共阳极接法对吧?还应该通过了译码器,P2.6和P2.7都是控制译码器的控制IO口,这个你要看译码器,或者说是锁频器的数据手册,是在上升沿上是锁存状态还是下降沿是锁存状态,而且光看的见你有下降沿,没见上升沿,就是光看见wei=0,不见WEI=1啊。

这个我嫌麻烦,所以把程序改进了一下,就改成楼上的程序,但是却出了问题

下降沿锁存,采用共阴极接法,程序中有WEI=1

郭天祥的这个程序当然可以改进,但是要在充分理解原作的基础上改进,不然就会弄巧成拙。小编的挑战精神可嘉。

缺少电路图,很难分析问题

uchar code table[]={//数码管段选ROM 存储区数据(6.5.4.3.2.1)
0x7d,0x6d,0x66,0x4f,0x5b,0x06};
这是你中间的部分代码, 你确定是共阴极的么?如果是共阴极的,那么应该是只有两个不亮,剩下的全部都亮才对,阴极已经全部都在GUN了,拿你其中一个数值,0x7d来说,翻译二进制应该0B 0111,1101,电平对应的应该是,低高高高,高高低高,所以应该是 灭亮亮亮 亮亮灭亮才对,如果是共阳极就反过来了,就是 亮灭灭灭 灭灭亮灭,所以应该是共阳极接法,然后只见下降沿,所以只能锁存一次,段和位都只能锁存一次,而且应该是固定的,除非恢复上升沿,然后再次下降才能再次锁存。

不知道这样行不行
#include<reg52.h>
#define uint unsigned int//宏定义
#define uchar unsigned char//宏定义
sbit duan=P2^6;//数码管段选锁存器控制I/O口
sbit wei=P2^7;//数码管位选锁存器控制I/O口
uchar code table[]={0x7d,0x6d,0x66,0x4f,0x5b,0x06};
uchar code tablewei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
void delay(uint z)//延时程序
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void main()
{
   uchar num;
        while(1)
        {
               for(num=0;num>6;num++)
             {
                  wei=1;//选择第一个数码管
                P0=tablewei[num];
                wei=0;
                delay(5);
        
                duan=1;//第一个数码管发送数据
                P0=table[num];
                duan=0;
                delay(5);           
        }        
}
}

没有消隐

没有消隐

试试这样吧
                duan=1;//第一个数码管发送数据
                P0=table[num];
                duan=0;
                P0=tablewei[num];
                wei=1;//选择第一个数码管
                P0=tablewei[num];
                wei=0;
                delay(1);
        
                num++;
                if(num==6)
                        num=0;               

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top