机友帮忙看看这个程序 8位数码管显示时分秒 51的片子
#define uint unsigned int
#define uchar unsigned char
uint h=0,m=0,s=0,t0=0,i=0,t1=0;
uchar d[8]; //段显示
uchar code n[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; //数码管码段
uchar code w[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //位扫描
/*************************端口初始化*************************/
void init()
{
TMOD=0X11; //选择定时器1和0,工作方式1,内部控制定时器开关
TH0=47104/256; //定时器0初值高8位 定时10ms
TL0=47104%256; // 初值低8位
TH1=65036/256; //定时器1初值
TL1=65036%256; //
EA=1; //打开总中断
ET0=1; //允许定时器0中断
ET1=1;
TR1=1;
TR0=1; //打开定时器
}
/*************************处理显示数据*************************/
void led_display()
{
d[0]=n[s%10]; //显示秒
d[1]=n[s/10];
d[2]=n[10]; //显示"-"
d[3]=n[m%10]; //显示分钟
d[4]=n[m/10];
d[5]=n[10]; //显示"-"
d[6]=n[h%10]; //显示小时
d[7]=n[h/10];
}
/*************************数码管扫描*************************/
void scan()
{
if(t1>10) //数码管扫描 1ms多一次
{
t1=0;
for (i=0;i<8;i++)
{
P2=w[i];
P0=d[i];
}
}
}
/*************************定时器0中断*************************/
void time0() interrupt 1
{
TH0=47104/256; //初值高8位 定时10ms
TL0=47104%256; //初值低8位
t0++;
}
/*************************定时器1中断*************************/
void time1() interrupt 3
{
TH1=65036/256;
TL1=65036%256;
t1++;
}
/*************************时间处理*************************/
void time()
{
if(t0==100) //时间进制处理
{
t0=0;
s++;
if(s==60)
{
s=0;
if(m<60)
m++;
else
{
m=0;
if(h==24)
h=0;
else
h++;
}
}
}
}
/*************************主程序*************************/
void main()
{
init();
while(1)
{
time();
led_display();
scan();
}
}
/********************************************************/
这个程序本身思路倒是没什么问题,有一点需要测试的就是 led_display(); scan();这两个函数的运行时间,假设大于20毫秒的话就会出错了,如果定时器0中断了两次还没有进入time() 那么假设上一次检测时99,然后执行显示函数了,20毫秒内没完事儿的话 t0就等于101了 整个程序就出错了
晶振22.1184的,定时整数的话最少应该是5ms吧?
我不知道你现在是什么情况呢 也没说 光说看看
程序有问题 ,调试时 t0 t1 从数值上没问题 ,至于时间 准不准除了下载到片子上 不知道还有什么方法能看。i的值是有问题的 持续是8 偶尔会变化 ,到了片子上估计就是 第8位常亮 其他位微亮了吧
下载到单片机,结果确实是我说的那样 ,为什么呢
数码管发暗 应该是延时不够 如果我不定义一个延时函数 怎么延时呢 在P0=d;P2=w;之后
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint h=0,m=0,s=0,i=0,t1=0,t0=0;
uchar d[8]; //段选
uchar code n[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xbf}; //共阳码段:0-9, "-"
uchar code w[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位选
/*************************端口初始化*************************/
void init()
{
TMOD=0X11; //选择定时器1和0,工作方式1,内部控制定时器开关
TH0=15536/256; //定时器0 50ms 12mhz
TL0=15536%256;
TH1=65526/256; //定时器1 10us 12mhz
TL1=65526%256;
EA=1; //打开总中断
ET0=1; //允许定时器0中断
ET1=1;
TR1=1;
TR0=1; //打开定时器0
}
/*************************定时器0中断*************************/
void time0() interrupt 1
{
TH0=15536/256; //定时50ms 12mhz
TL0=15536%256;
t0++;
}
/*************************定时器1中断*************************/
void time1() interrupt 3
{
TH1=65526/256; //定时10us 12mhz
TL1=65526%256;
t1++;
}
/*************************时间处理*************************/
void time()
{
if(t0==20) //时间进制处理
{
t0=0;
s++;
if(s==60)
{
s=0;
if(m<60)
m++;
else
{
m=0;
if(h==24)
h=0;
else
h++;
}
}
}
}
/**************************显示处理***************************/
void led_display()
{
d[0]=n[s%10]; //显示秒
d[1]=n[s/10];
d[2]=n[10]; //显示"-"
d[3]=n[m%10]; //显示分钟
d[4]=n[m/10];
d[5]=n[10]; //显示"-"
d[6]=n[h%10]; //显示小时
d[7]=n[h/10];
}
/*************************数码管扫描*************************/
void scan()
{
if(t1>200) //2ms扫描一次
{
for (i=0;i<8;i++)
{
t1=0;
P0=d[i];
P2=w[i];
while (t1<100); //送显一位后延时2ms
P2=0xff; //关闭显示
while (t1<100); //关闭位选后延时2ms
}
t1=0;
}
}
/*************************主程序*************************/
void main()
{
init();
while(1)
{
time();
led_display();
scan();
}
}
/********************************************************/
已经搞定了,你说的地方确实也挺重要的,后来调试的时候遇到过,感觉数码管还是稍微有那么一点的阴影,不明显,不知道能不能完全消除。