定时器延时问题(51单片机,c语言)

while(1){while(num!=20){display(thou,hun,ten,one);//数码管显示四个数字}num=0;}thou,hun,ten,one... while(1)
{while(num!=20)
{
display(thou,hun,ten,one);//数码管显示四个数字
}
num=0;
}
thou,hun,ten,one是变化的(不用管吧).num由定时器0控制,每50微秒+1
运行时没什么反应
奉上函数
#define uint unsigned int
sbit N1=P2^0;
sbit N2=P2^1;
sbit N3=P2^2;
sbit N4=P2^3;
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9
void delayms(uint);
void display(uchar,uchar,uchar,uchar);
uchar thou,hun,ten,one,num;
void main()
{
TMOD=0x01; //定时器0,,01工作方式
TH0=(65536-45872)/256; //装初值 11.0592hz下延时50微秒
TL0=(65536-45872)%256;
EA=1; //开总中断
ET0=1; //开定时器0
TR0=1; //启动定时器0
while(1)
for(thou=0;thou<=5;thou++) //千位
for(hun=0;hun<=9;hun++) //百位
for(ten=0;ten<=5;ten++) //十位
for(one=0;one<=9;one++) //个位
{
while(num!=20) //循环一秒
{
display(thou,hun,ten,one);//数码管显示四个数字
}
num=0;
}
}
展开
 我来答
little4_su
2012-11-05 · TA获得超过123个赞
知道答主
回答量:16
采纳率:100%
帮助的人:2.8万
展开全部
你的这两个函数void delayms(uint)和void display(uchar,uchar,uchar,uchar)我可以肯定的告诉你,没有问题。你的这个程序其实就是想显示0000~5959之间的数,而且这个数是每20秒+1顺序递增的。之所以没有任何反应,那是你的主程序没有挂起,也就是在while(1)里没有没有大括号,程序执行一次就结束了,所以你什么都看不到。应该这样
while(1)
{//加入的成对大括号

for(thou=0;thou<=5;thou++) //千位
for(hun=0;hun<=9;hun++) //百位
for(ten=0;ten<=5;ten++) //十位
for(one=0;one<=9;one++) //个位
{
while(num!=20) //循环一秒
{
display(thou,hun,ten,one);//数码管显示四个数字
}
num=0;
}
}
这样你就可以看到程序运行的结果了,但结果是这样的:四个LED显示管闪得很严重,计划是一亮一灭的,而且0000~5959这个数字几乎显示得不成样子。主要是delayms(5),这个延迟程序你应该尽量控制在20ms之内(主要是人眼残辉的时间极限),短了感觉就全亮,长了就一闪一灭。
不过我很看不惯你的这个程序,我给你一个CPU负担更小,而显示又非常好的程序供你参考:
#include<AT89X52.H>
#define uint unsigned int
#define uchar unsigned char

sbit LED4=P2^0; //数码管千分位
sbit LED3=P2^1; //数码管百分位
sbit LED2=P2^2; //数码管十分位
sbit LED1=P2^3; //数码管个分位

uchar ms20,s1;//20毫秒和1s变量定义(声明)

//定时器T0初始化,10ms秒初值
void InitTimer0(void)
{
TMOD=0x01;
TH0=0x0D8;
TL0=0x0F0;
EA=1;
ET0=1;
TR0=1;
}

void Display(uchar dat4,uchar dat3,uchar dat2,uchar dat1)
{
static uchar k;
P2=P2|0xf0;
switch(k++)
{
case 0:
P0=dat4;
LED4=1;
break;

case 1:
P0=dat3;
LED3=1;
break;

case 2:
P0=dat2;
LED2=1;
break;

case 3:
P0=dat1;
LED1=1;
break;

default:k=0;return;
}
}

void Timer0(void) interrupt 1//1ms中断
{
TH0=0x0D8;
TL0=0x0F0;
ms20++;
s1++;
}

void Main(void)
{
uchar thou,hun,ten,one;
InitTimer0();
while(1)
{
if(s1>=100)//每1秒钟one+1
{
s1=0;
if(one++>=9)
{
one=0;
if(ten++>=5)
{
ten=0;
if(hun++>=9)
{
hun=0;
if(thou++>=5) thou=0
}
}
}
}
if(ms20==2)//每20毫秒调用一次显示函数
{
Display(thou,hun,ten,one);
ms20=0;
}
}
}
bjemt
2012-11-05
知道答主
回答量:21
采纳率:0%
帮助的人:8.1万
展开全部
首先在程序开始时初始化一下num。
另外while中的num=0;就会将定时器0中num的增加值又设置成0,这样每循环一次,num就会被设置成0,所以程序程序就退不出while循环。
另外,还要看你的display程序是不是有问题,最好先把显示调试好再去做这个程序。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
做而论道
高能答主

2012-11-05 · 把复杂的事情简单说给你听
知道大有可为答主
回答量:3万
采纳率:80%
帮助的人:1.2亿
展开全部
while(num!=20) //循环一秒

改为:
while(num < 20) //循环一秒

即可。
更多追问追答
追问
不行啊。
追答
怎么不行啊?

刚才,按照此网页,把程序完全的敲了一遍;
然后用PROTEUS仿真,没有出现任何异常。

楼主的程序中,《while(num!=20) //循环一秒》,这个条件有些宽松了;
做而论道建议改成《while(num < 20)》,这就更严谨一些。
其实,不改,也可以。

楼主选择的最佳,所说的,其实都是多余的。
楼主的原程序,没有丝毫错误。是可以正常执行出来效果的。

楼主原来的程序,以及PROTEUS仿真文件,已经上传到做而论道的百度网盘。
但是,在这里写不上链接,写上就不显示了。
可以到做而论道的百度空间看看,网盘链接,写在百度空间了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
笑谈我不言9514
2012-11-05 · TA获得超过622个赞
知道小有建树答主
回答量:522
采纳率:0%
帮助的人:317万
展开全部
动态扫描函数,需要不停地执行。display(); 放错地方了。
追问
为什么说放错位置了?应该放哪?
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式