当前位置: 代码迷 >> 单片机 >> 定时关闭蜂鸣器的有关问题————定时无用
  详细解决方案

定时关闭蜂鸣器的有关问题————定时无用

热度:139   发布时间:2016-04-28 14:49:47.0
定时关闭蜂鸣器的问题————定时无用
最近做了个红外线报警器,用开关S来代替红外传感器。要求用数码管记录报警次数,若没有外部中断,则10s后自动关闭蜂鸣器,但是中断可以关闭,但定时不管用为什么呢,这是我的程序

#include <reg51.h>

sbit    INTO_1=P3^2;                //外部中断
sbit    LED_1  =  P3^0;
sbit LED_2  = P1^2; 
sbit BEEP= P1^7;                 //蜂鸣器
sbit BaoJing = P1^0;              //报警器,低电平有效
//sbit Disdata = P2;


#define uint  unsigned int
#define uchar unsigned char       
#define Disdata P2                //数码管输入

uchar code dis_7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//共阴LED段码表 "0"   "1"   "2"   "3"   "4"   "5"   "6"   "7"   "8"   "9" 

uchar flag=0;               //外中断跳出循环标志
uchar t=0;                 //延时的辅助循环次数
uchar i=0;                //记录报警次数的

/***********************************************************************/          
void DelayMs()                  //蜂鸣器延时
{

uchar n=10;
while(n--);

}

 void Delay(uint t)
{
uint n=500;
for(;t>0;t--)
{
for(;n>0;n--);

}
}
/********************************************************/
void play()                         //蜂鸣器运行,10s自动返回,靠定时器中断
{
flag=1;
t=0;
TMOD=0X01;
TH0=0X3c;
TL0=0XB0;
TR0=1;
BEEP=0;
while((flag==1)&&(t<200))
{


BEEP=~BEEP;

}

TR0=0;




}


void INT_TMR (void) interrupt 1  //定时器中断服务子程xu
{
TH0=0X3c;
TL0=0XB0;
t++;
if(200==t)
{
LED_1=1;
LED_2=1;
}
}

void INT_EXT(void) interrupt 0   //外中断服务子程序,管蜂鸣器,关LED 灯
{

LED_1=1;
LED_2=1;
flag=0;

}
void main()
{
EA=1;
ET0=1;
EX0=1;
Disdata = dis_7[0];   //初始化数码管

while(1)
{
//BaoJing = 0;
while(!BaoJing)
{

i++;
Disdata=dis_7[i];
LED_1=0;
LED_2=0;
play();
BaoJing=1;
}


Delay(10);
}

}


------解决思路----------------------
定时器只初始化一次,你怎么把定时器的初始化放到while循环里了,一直初始化定时器。。。
------解决思路----------------------
我没有用过这款单片机,具体timer的设置我不清楚。但是我还是有三个疑问?第一,为什么你的play函数都要初始化一次timer,这是必须的么?能不能将timer的初始化放到main开始处?第二, 定时中断的t++。要知道你并没有对t做判断,t会一直增加,到了255后又会从0开始增加,如此循环。所以,你的while((flag==1)&&(t<200))隔一段时间(你这里估计是2.5s)又会满足条件了;第三,就算程序其他地方能满足你的设想,BEEP在play退出后的电平是未知的啊!
------解决思路----------------------
你逻辑确实很混乱。通常的做法是,条件满足(你这里是有按键按下)就设置标志位(你的flag);条件不满足了(你这里10s已经满了,)清除标志位。main的主循环根据这个标志位来决定是否执行你的play函数。如果系统负荷比较重,在设置标记的时候打开定时器,清除标记的时候关闭定时器。
  相关解决方案