3486|5

10

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

请高手进来看看,我不明白这是为什么 [复制链接]

写了一个简单的倒计时程序,源码如下:
#include<reg51.h>
#define uchar unsigned char
#define uint  unsigned int
 code uchar tab[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint second=15;
uint shiW,geW;
static char count=0;

sbit P20=P2^0;
sbit P21=P2^1;

void delay()
{
 uchar i;
 for(i=0;i<15;i++);
}

void Delay(unsigned int i)   //延时程序  i=1  就延时1ms
{
 unsigned int j;
 for(;i>0;i--)
 for(j=0;j<125;j++)
 {;}
}

void int1()interrupt 1 using 2 //定时中断响应定为 50ms
{
 TH0=0x3c;   //通过对TMOD的赋值,让定时/计数器0工作,从而可以算的THO TL0的值
 TL0=0xb0;
 count++;
}

main()
{
 TMOD=0x01;
 TH0=0x3c;
 TL0=0xb0;
 EA=1;
 ET0=1;       //   定时器/计数器T0中断  允许
 TR0=1;         //   定时器运行状态   启动
 P1=0xff;
 while(1)
 {
 
  shiW=second/10;
  geW=second%10;
  P0=tab[geW];       //   这里是定义时的个位的输出端
  P21=1;
  delay();
  P21=0;
  P0=tab[shiW];       //   这里是定义时的十位的输出端
  P20=1;
  delay();
  P20=0;


  if(count==20)
     {
  count=0;
  second--;
  if(second==0)
  {
   Delay(2000);
second=15;
  }

}
 }
}
预计运行结果是:从15开始倒数,到0时停两秒,接着继续从15倒数。
但实际运行结果是:从15开始倒数,到0停两秒,然后显示15并且显示15这个数大概5~7秒,然后再开始倒数。
大虾们能给我解释解释吗?小弟刚玩51,很多不懂,希望能说详细点
谢谢~~
Ps:如果把红色代码里的数字改成1000,运行结果是:从15开始倒数,数完后不停,接着从14开始倒数
此帖出自51单片机论坛

最新回复

哈哈,原来如此,我刚开始也不知道为什么会重新开始倒计数,原来是count的值溢出了!! 真的学到了不少。 强悍!!!  详情 回复 发表于 2010-10-16 12:35
点赞 关注
 

回复
举报

33

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

我也是个新手

出现这个问题肯定是在延时的时候发生了定时器中断,所以造成时间延迟。

至于说你将延迟时间改为1秒,但不停,也是因为定时的时间和延迟时间重合都是1s。

你要将延迟和定时器都用上,就要严格区分各自的用时,不能交叉。

我建议你用一个一个变量来控制你的延时。

[ 本帖最后由 inintrovert 于 2010-10-15 23:47 编辑 ]
此帖出自51单片机论坛
 
个人签名小草眼中的世界!
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
上面沙发正解。详细解释如下:
现象:Delay(2000)导致倒计时一次后15显示的时间较长,之后又继续倒计时。
     原因:延时两秒期间,定时器T0继续计时,两秒后count = 40,无法再进入
     if(count == 20),所以只显示15了。看起来好像不会继续倒计时,不会再进入if,因为 count 变量的值好像一直都在增加。看起来好像过了一段时间系统复位了,但51单片机的看门狗默认是关闭了的。但是可见count被定义为char型,即count只能增加到255,然后再增加时就变成 0 了,于是又可以正常倒计时了。

解决办法:在调用延时子程序时,为免定时器影响,应暂时关闭,延时完后再打开定时器。
                在Delay(2000)前应加TR0 = 0;在其后添加TR0 = 1;
此帖出自51单片机论坛
 
个人签名勇往直前,协作共进,开创未来。
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

4
 
另外指出改程序的一些瑕疵:
1.static一般用来定义局部静态变量,没必要用来定义全局变量,另外静态变量会一直占用内存空间直到程序结束或者其他遇到释放指令,这样就增加系统开销了。
2.短暂延时子函数delay()中,最好有输入参数,这样才能适用于多处的短延时调用,另外该函数体中i < 15条件也不太适合,因为为了让数码管的显示稳定(若其8个引脚都是由P0口输出电平控制的话),所以该函数可修改如下:
void delay( int i )
{
    while( i-- );
}
而main函数中相应的短延时就改为delay( 200 ),实际参数一般为200左右即可。
此帖出自51单片机论坛
 
个人签名勇往直前,协作共进,开创未来。
 
 

回复

33

帖子

0

TA的资源

一粒金砂(初级)

5
 

回复 板凳 piggyfeng 的帖子

哈哈,原来如此,我刚开始也不知道为什么会重新开始倒计数,原来是count的值溢出了!!
真的学到了不少。
强悍!!!
此帖出自51单片机论坛
 
个人签名小草眼中的世界!
 
 

回复

10

帖子

0

TA的资源

一粒金砂(初级)

6
 

回复 4楼 piggyfeng 的帖子

谢谢~~
我会试试的
此帖出自51单片机论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表