2831|3

70

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

对51单片机中断 的一点疑问 [复制链接]

程序如下
#include  

unsigned int  count=0;
unsigned int  count1=0;

sbit  P15=P1^5 ;//蜂鸣器
main()
{

TMOD=0X01;//选择定时器0方式1
TH0=(65536-50000)/256;//定时器置初值,定时50ms
TL0=(65536-50000)%256;
TR0=1;//启动定时器T0
  ET0=1;//开定时器TO中断
  TH1=(65536-50000)/256;//定时器置初值,定时50ms
TL1=(65536-50000)%256;
TR1=1;//启动定时器T1
ET1=1;//开定时器T1中断
EA=1;//开CPU中断
while(1)
{
  if(count%40>5){
          P0=0xff;//LED灯关
  }else{
        P0=0x00;//LED灯开
  }
}

}     



void t0(void)interrupt 1 using 0

{
count++;  //次数加一
TH0=(65536-50000)/256;//定时器初值重载
TL0=(65536-50000)%256;
  if(count==200)//10秒到否
   {  
   count=0;         //中断一直进行,屏蔽后COUNT将不再会回到200,所以P15一直为高
   
   P15 = 0xff;//蜂鸣器开
  }
}

void t1(void)interrupt 3 using 2

{
count1++;  //次数加一
TH1=(65536-50000)/256;//定时器初值重载
TL1=(65536-50000)%256;
  if(count1==600)//30秒到否
   {  
   count1=0;           //中断一直进行,屏蔽后COUNT1将不再会回到600,所以P15第一次为底后一直为高

   P15 = 0x00;//蜂鸣器关
  }
}

我写了两个中断.发现蜂鸣器一开始是开着的,响10秒后就被关闭,然后5秒响一次,持续3秒钟左右又被关闭,然后5秒响再响持续时间还是3秒左右,一直循环下去.由此觉得一开始的10秒是定时器没有到触发时间.然后关闭了,是因为T1启动关闭了,然后5秒后又响是T0启动.我不明白的是,是否中断程序就是这样不停循环的.如果我想关闭中断让T0再执行别的任务如何处理?另外,我屏蔽 T0和T1里面的TH1=(65536-50000)/256;//定时器初值重载
TL1=(65536-50000)%256;似乎没有什么影响,我开很多人写中断都写这句,但是我认为MAIN里面写了是不是在T0和T1里可以不用写?

最新回复

谢谢这位兄弟的解释,我相当相当满意,非常非常有收获,谢谢你,希望能加你QQ   详情 回复 发表于 2009-5-21 11:06
点赞 关注

回复
举报

64

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
楼主的定时器似乎没有工作在方式1而是方式0哦
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
实现你上述程序功能,可以简化很多,仅仅用一个定时器即可,见下面代码(我已经运行OK)。

关于你提的问题,以下建议供参考:

1 初始化问题:为了不让上电开机后蜂鸣器就响,可以初始化“P1=0x00”;
              另外,在中断里当“count<=200”时,蜂鸣器也是关的,这样保证了P1的电平先维持低。
  以上处理可以解决你所说“发现蜂鸣器一开始是开着的,响10秒后就被关闭”的问题。

2 你所说“是否中断程序就是这样不停循环”的问题
  可以这样理解,也许你能明白一些:
  T0、T1和main是三个任务,它们看上去就像在同时运行(实际上它们是分时运行的,只是切换的速度很快,我们感觉像是在同时运行——以后若有机会学习实时操作系统的话,你一定能理解更加透彻),所以你可以认为是“中断程序就是这样不停循环的”。

3 你所说“如果我想关闭中断让T0再执行别的任务如何处理”的问题
  要关闭中断?你其实是想说关闭T0中断吧?否则关闭总中断“EA=0”的话,那么T1也不能发生中断罗。
  仅仅关闭T0中断,将“ET0=0”即可,之后T0中断里的代码不会再次进入运行。你想“让T0再执行别的任务如何处理”,不太明白你的意思。补充说说:你可以在main中“ET0=0”,再重新初始化T0,让T0“再执行别的任务”。

4 你所说“另外,我屏蔽T0和T1里面的TH1=(65536-50000)/256;TL1=(65536-50000)%256;似乎没有什么影响”的问题
  当T0、T1工作于方式1作为16位定时器/计数器时,需要在中断重装TH0、TH1和TL0、TL1,否则定时为:
  65536*12/Fosc(这里Fosc取12MHz)=65.536ms
  这与你想要的50ms相差不大,是不是就是你“似乎没有什么影响”的原因吧。

  更深一步分析:就算在中断里对TH0、TH1和TL0、TL1重装了,那么就是定时50ms吗?也不是!!!
  原因是,T0、T1产生中断后,在“重装TH0、TH1和TL0、TL1”之前还有代码运行(看看汇编代码就明白,如把ACC、PSW等压入堆栈),而在此期间T0、T1还在继续运行,所以我们在“重装TH0、TH1和TL0、TL1”时,实际上是忽略了之前运行代码的一点点时间。
  
  祝大家在讨论中共同学习和进步!


#include  

unsigned int count=0;
//unsigned int  count1=0;

sbit  P15=P1^5 ;//蜂鸣器

void main(void)
{
        P1 = 0x00; //初始化P1

        TMOD=0X01;//选择定时器0方式1
        TH0=(65536-50000)/256;//定时器置初值,定时50ms
        TL0=(65536-50000)%256;
        TR0=1;//启动定时器T0
          ET0=1;//开定时器TO中断
          //TH1=(65536-50000)/256;//定时器置初值,定时50ms
        //TL1=(65536-50000)%256;
        //TR1=1;//启动定时器T1
        //ET1=1;//开定时器T1中断
        EA=1;//开CPU中断

        while(1)
        {
                if(count%40>5)
                {
                          P0=0xff;//LED灯关
                  }else
                {
                        P0=0x00;//LED灯开
                  }
        }

}   


void t0(void) interrupt 1 using 0
{
        TL0=(65536-50000)%256;
        TH0=(65536-50000)/256; //定时器初值重载

        count++;  //次数加一

          if(count<=200)//10秒到否
          {  
                  //count=0; //中断一直进行,屏蔽后COUNT将不再会回到200,所以P15一直为高
                  //P15 = 0xff;//蜂鸣器开
                P15 = 0; //蜂鸣器关
          }
        else if(count<=400)
        {
                P15 = 1;//蜂鸣器开
        }
        else
        {
                count = 0;
        }
}

/*
void t1(void) interrupt 3 using 2
{
        count1++;  //次数加一
        //TH1=(65536-50000)/256;//定时器初值重载
        //TL1=(65536-50000)%256;
          if(count1>=600)//30秒到否
          {  
                  count1=0;   //中断一直进行,屏蔽后COUNT1将不再会回到600,所以P15第一次为底后一直为高
                  P15 = 0x00;//蜂鸣器关
          }
}
*/
 
 
 

回复

80

帖子

0

TA的资源

一粒金砂(初级)

4
 
引用 2 楼 zhkflying 的回复:
实现你上述程序功能,可以简化很多,仅仅用一个定时器即可,见下面代码(我已经运行OK)。

关于你提的问题,以下建议供参考:

1 初始化问题:为了不让上电开机后蜂鸣器就响,可以初始化“P1=0x00”;
              另外,在中断里当“count <=200”时,蜂鸣器也是关的,这样保证了P1的电平先维持低。
  以上处理可以解决你所说“发现蜂鸣器一开始是开着的,响10秒后就被关闭”的问题。

2 你所说“是否中断程序就…

谢谢这位兄弟的解释,我相当相当满意,非常非常有收获,谢谢你,希望能加你QQ
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表