最佳回答:人眼的视觉暂留时间大概在二十四分之一秒左右(所以一般电视电影至少是24帧以上,才会看起来是连续的动作),延时的时间设置小于40ms...
给你简单的修改了一下,如果你的数码管编码没错,应该可以显示 0~99的
没添加百位显示,所以只有 0~99
//数码管动态显示+1,显示范围0-100,定时时间1s
#includereg52.h
sbit dula=P2^6; //定义段选信号
sbit wela=P2^7; //定义位选信号
char aa,temp,bai,shi,ge;
char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void delay(int z); //延迟函数声明
void display(char d); //显示函数声明
void init(); //初始化函数声明
/*******************************************************************************/
/*******************************************************************************/
void main()
{
init(); //调用初始化子函数
while(1)
{
display(temp); //调用显示子函数
}
}
/*******************************************************************************/
/*******************************************************************************/
void delay(int z) //延迟子函数
{
int x,y;
for(x=z;x0;x--)
for(y=110;y0;y--);
}
/*******************************************************************************/
/*******************************************************************************/
void display(char d) //显示子函数
{
char d1,d2;
d2=d%10; //取个位 %求余
d1=(d/10)%10; //取十位
P0=table[d2]; dula=0; delay(10); dula=1;//个位显示
P0=table[d1]; wela=0; delay(10); wela=1;//十位显示
}
/*******************************************************************************/
/*******************************************************************************/
void init() //初始化子函数
{
dula=0;
wela=0;
temp=0;
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
/*******************************************************************************/
/*******************************************************************************/
void timer0() interrupt 1 //中断处理子函数
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256; //重载初值
aa++;
if(aa==20) //判断定时是否到达1s
{ aa=0; temp++ ; }
if(temp==100) //限制temp变化的范围,使之不超过100
{ temp=0; }
}
/*******************************************************************************/
/*******************************************************************************/
/*/////////////////////////////////////////////////////////////////////////////*/
1.数码管显示,是利用人眼的视觉暂留效应。不足余辉,白炽灯断电后还亮一会,才是余辉,这可是有区别的,不可混淆。
2.这是利用定时器T0定时1ms来实现数码管动态显示的。用查询法,1ms到显示一位,实现你说的间隔1ms显示。
3.数码管的位控是用译码器74LS138的。
4.虽然是书上的程序,但现在的有关单片机的书,真是良莠不齐,这也只是叫一段代码吧,是最烂的程序。电影每年都评最烂片吗,这可评上最烂程序啦!
请你明确你的程序具体出什么问题,别让我们再去读整个程序啊!你可以这样描述:不显示、计数不正确、时间间隔不正确等等……
大致看了一下,感觉有几个思路问题,给你些提示吧:
1. 你的程序会不断的执行display(),原因是超级循环体里面没有对display的执行条件予以限制,我想着一定是你不希望的吧,而且通常这样会带来问题!解决:增加一个标志变量,你的限定条件是1秒刷新一次显示,在定时器中断中计数到达1秒时置位这一个标志,在超级循环体中的部分使用:
if(标识变量) {
……
display();
标识变量 = 0; //清零标志,很重要!
}
你上面的程序 if(a==20) {} 也可以有类似的效果,不过你没有把display包括进去就有问题了。
2. 从优化的角度讲TH0=(65536-50000)/256这样的语句是垃圾代码,你应该把具体的值算出来填写上去才对,否则单片机运行的时候还需要计算这个太浪费。如果你想程序便于理解又便于维护你可以这样:
#define THVALUE (65536-50000)/256
TH0 = THVALUE;
这样在编译的时候编译器会帮你完成计算。同样是优化,temp计数再转换成个十百位也不理想,其实本例中你的temp没有其它用处,你完全可以这样:
ge++;
if (ge == 10) {
shi++;
ge = 0;
}
if (shi == 10) {
bai++;
shi = 0;
}
if(bai == 10) {
bai = 0;
}
直接得到个十百位的数值,而且完全不使用除法何求余(要知道这可是单片机的软肋)。
3. 为什么要在定时器中断服务程序中重置定时器初值?不能自动重计数吗?要知道重置定时器初值也是需要指令周期的,直接的结果就是定时不准,累积误差不可小看。仔细查查单片机的手册看如何配置定时器。
4. 已经启用了定时器为什么还要使用阻塞式的延时函数?就算是动态扫描,合理的确定定时器中断的时长,结合前面提到的标志变量使用应该也容易完成的。
上面的供你参考,希望对你有帮助。
数码管动态显示就是按顺序分配给每一个数码管显示一定时间(如10ms等),如此循环;
对于时间间隔的设定,常采用定时器中断方式来得到,可以首先让定时器1ms中断,然后在中断函数里对全局变量m计数,即10次中断就是10ms,同理,计数800次就是8秒了;
要想让显示变成静态显示,那么就只有一位数码管在显示了;
这个可以在想显示的位中,停止定时器计数,或者在 m 未达到设定值前清0 即可;
另外,不要再采用delay()这样的代码延时函数;
单片机数码管动态显示定时的介绍就聊到这里吧,感谢您花时间阅读,谢谢。
本文标签:单片机数码管动态显示定时