51单片机用定时器编的流水灯,出了些问题,请高手看一下!

老师给我们的参考程序是软件延时,所以我编了定时器延时。如下:#include"reg51.h"unsignedchars=0,a=128,count=0;voidmain... 老师给我们的参考程序是软件延时,所以我编了定时器延时。如下:
#include"reg51.h"
unsigned char s=0,a=128,count=0;
void main()
{
TMOD=0x01;
TH0=0x3c;
TL0=0xb0;
TR0=1;
P1=~a;
ET0=1;
EA=1;
while(1);
}
void T0_srv() interrupt 1 using 1
{
TH0=0x3c;
TL0=0xb0;
s++;
if(s==20)
{
count++;
s=0;
if(count<8) a=a>>1;
else a=a<<1;
if(count==15)
{
count=0;
a=128;
}
P1=~a;
}
}
本应该实现的功能是将LED灯从P17到P10再到P17逐个点亮,间隔为1秒,不断循环。我编的代码也能实现上述要求,但一次循环后再从P17到P16的间隔明显超过了1秒,请问有什么改进的办法吗?(不要用软件延时)。初学单片机,请各位多指教!
展开
 我来答
好嘞啊啊啊啊
2013-11-23 · TA获得超过2612个赞
知道大有可为答主
回答量:1860
采纳率:66%
帮助的人:1206万
展开全部
#include"reg51.h"
unsigned char s=0,a=128,count=0;
void main()
{
 TMOD=0x01;
 TH0=0x3c;
 TL0=0xb0;
 TR0=1;
 P1=~a;
 ET0=1;
 EA=1;
 while(1);
 }
 void T0_srv() interrupt 1 using 1
 {
    TH0=0x3c;
     TL0=0xb0;
s++;
if(s==20)
{
 count++;
 s=0;
 if(count<8) a=a>>1;
 else a=a<<1;
 if(count==16) //难道不是该到16才清0吗 0到7 8个  8到15 8个 
 {
  count=0;
  a=128;
  }
 P1=~a;
}
 }
 
 
 或者直接用循环左移或循环右移
 #include<intrins.h>
 a=_cror_(a,1); //循环右移
更多追问追答
追问
P17的LED灯亮到P16的LED灯亮之间隔了约3秒,所以还是没有解决。
追答
#include"reg51.h"
unsigned char s=0,a=128,count=0;
void main()
{
 TMOD=0x01;
 TH0=0x3c;
 TL0=0xb0;
 TR0=1;
 P1=~a;
 ET0=1;
 EA=1;
 while(1)
 {
      if(s==20)
{
 count++;
 s=0;
 if(count<8) a=a>>1;
 else a=a<<1;
 if(count==15) 
 {
  count=0;
  a=128;
  }
 P1=~a;
}
 }
 
 }
 void T0_srv() interrupt 1 using 1
 {
    TH0=0x3c;
     TL0=0xb0;
s++;
}
那这样呢
一般中断函数中不怎么处理程序
宿兴电子
2024-11-28 广告
联系我们蜂鸣器的种类规格繁多,需先知道几个参数 ( 电压,电流,驱动方式,尺寸,连接/固定方式),当然更重要的是,想要获的声音 (音压大小,频率高低).工作电压:电磁式蜂鸣器,从1.5到24V, 压电式的从3V到220V都是可行的,但一般压... 点击进入详情页
本回答由宿兴电子提供
做而论道
高能答主

2013-11-23 · 把复杂的事情简单说给你听
知道大有可为答主
回答量:3万
采纳率:80%
帮助的人:8330万
展开全部
void T0_srv() interrupt 1 using 1
{
TH0 = 0x3c;
TL0 = 0xb0;
s++;
if(s == 20){
P1 = ~a;
s = 0;
count++;
if(count == 14) { count = 0; a = 128; }
if(count < 7) a = a >> 1; else a = a << 1;
}
}

试试看。
更多追问追答
追问

追答
#include"reg51.h"
unsigned char s=0,a=128,count=0;
void main()
{
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
TR0 = 1;
ET0 = 1;
EA = 1;
P1 = ~a;
a = a >> 1; //加上这行,其它不变
while(1);
}
void T0_srv() interrupt 1 using 1
{
TH0 = 0x3c;
TL0 = 0xb0;
s++;
if(s == 20){
P1 = ~a;
s = 0;
count++;
if(count == 14) { count = 0; a = 128; }

P3 = count;//可在P3看当前的计数值

if(count > 1; else a = a << 1;
}
}

已经试过,可以了。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
落落的树荫326
2013-11-23
知道答主
回答量:52
采纳率:0%
帮助的人:17.6万
展开全部
骚年 试试这样写吧
#define th0(65536-5000)/256
#define tl0 (65536-5000)/256
TH0=th0;
TL0=tlo;中断函数执行也是需要时间的,所以要适当减少TH0的初始值,还有,要记得给悬赏,觉得可以就采纳吧
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2013-11-23
展开全部
哥们,我大致看了下。你把中断里的
if (count == 15)
改成
if (count == 14)
试试。
试一下,应该是这样。
追问
这个我试过,还是有明显延迟!
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

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

类别

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

说明

0/200

提交
取消

辅 助

模 式