求助 关于80C51 单片机数码管动态扫描
题:利用动态扫描方法在六位数码管上显示出稳定的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;