发表于:2014/7/16 15:20:08
#0楼
各位高手,小弟正在基于STC51单片机开发程序,分配了2个中断,外部中断0和定时器1中断。主循环实时的计算并显示距离参数。系统开始运行后,主循环可以正常的计算并显示距离数据,但是进入外部中断0并且外部中断0成功返回后,主循环就停止了,不再计算并显示距离参数了,请教其中的原因,谢谢!部分代码如下:
/************************************************************
函数功能:主函数
*************************************************************/
void main()
{
LCD_init(); //调用LCD初始化函数
LCD_write_string(0,0,dis1);/*从第0列第0行起显示"机器人"*/
LCD_write_string(0,1,dis2);/*从第0列第1行起显示距离*/
Pwm_Init();/*脉宽调制初始化*/
EA=1; //开启总中断
EX0=1; //开外中断0 ,接收红外模块信号中断
ET0=1; //定时器T0中断允许
IT0=1; //外中断的下降沿触发
TMOD=0x01; //使用定时器T0的模式1,使用16位定时器
TR0=0; //定时器T0关闭,停止定时器
T1_Init();/*定时器1初始化*/
/*初始化占空比*/
CCAP0H=CCAP0L=0x2C;
CCAP1H=CCAP1L=0x2C;
while(1) //等待红外信号产生的中断
{
//LCD_write_char(10,1,'0');
//delay_nms(1000);
//LCD_write_char(10,1,'1');
//delay_nms(1000);
StartModule();/*启动超声波测距模块*/
while(!RX); //当RX为零时等待
TR1 = 1;/*启动定时器1*/
while(RX); //当RX为1计数并等待
TR1 = 0;/*关闭定时器1*/
Count();/*计算距离*/
/*在LCD屏幕上显示距离*/
LCD_write_char(7,1,bai);
LCD_write_char(8,1,shi);
LCD_write_char(9,1,ge);
//LCD_write_char(10,1,'0');
//delay_nms(1000);
//LCD_write_char(10,1,'1');
delay_nms(200);
}
}
/************************************************************
函数功能:红外线触发的外中断处理函数
*************************************************************/
void Int0(void) interrupt 0
{
EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
TH0=0; //定时器T0的高8位清0
TL0=0; //定时器T0的低8位清0
TR0=1; //开启定时器T0
while(IR==0); //如果是低电平就等待,给引导码低电平计时
TR0=0; //关闭定时器T0
LowTime=TH0*256+TL0; //保存低电平时间
TH0=0; //定时器T0的高8位清0
TL0=0; //定时器T0的低8位清0
TR0=1; //开启定时器T0
while(IR==1); //如果是高电平就等待,给引导码高电平计时
TR0=0; //关闭定时器T0
HighTime=TH0*256+TL0; //保存引导码的高电平长度
if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
{
//根据电平长度确定是否为引导码,如果是引导码,就开始解码,否则放弃,引导码的低电平计时
//次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.
if(DeCode()==1) // 执行遥控解码功能
{
switch(IRcode[2])
{
case 0x46:
/*恢复原始速度*/
CCAP0H=CCAP0L=0x2C;
CCAP1H=CCAP1L=0x2C;
forward();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"forward");
break;
case 0x15:
back();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"back");
break;
case 0x44:
left();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"left");
break;
case 0x43:
right();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"right");
break;
case 0x40:
stop();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"stop");
break;
default:
/*调整PWM占空比*/
CCAP0H=CCAP0L=0x4C;
CCAP1H=CCAP1L=0x2C;
forward();/*调速后前进*/
//stop();
//LCD_write_string(0,1," ");
//LCD_write_string(0,1,"speed changed");
break;
}
}
}
EX0=1; //开启外中断EX0
}
/************************************************************
函数功能:主函数
*************************************************************/
void main()
{
LCD_init(); //调用LCD初始化函数
LCD_write_string(0,0,dis1);/*从第0列第0行起显示"机器人"*/
LCD_write_string(0,1,dis2);/*从第0列第1行起显示距离*/
Pwm_Init();/*脉宽调制初始化*/
EA=1; //开启总中断
EX0=1; //开外中断0 ,接收红外模块信号中断
ET0=1; //定时器T0中断允许
IT0=1; //外中断的下降沿触发
TMOD=0x01; //使用定时器T0的模式1,使用16位定时器
TR0=0; //定时器T0关闭,停止定时器
T1_Init();/*定时器1初始化*/
/*初始化占空比*/
CCAP0H=CCAP0L=0x2C;
CCAP1H=CCAP1L=0x2C;
while(1) //等待红外信号产生的中断
{
//LCD_write_char(10,1,'0');
//delay_nms(1000);
//LCD_write_char(10,1,'1');
//delay_nms(1000);
StartModule();/*启动超声波测距模块*/
while(!RX); //当RX为零时等待
TR1 = 1;/*启动定时器1*/
while(RX); //当RX为1计数并等待
TR1 = 0;/*关闭定时器1*/
Count();/*计算距离*/
/*在LCD屏幕上显示距离*/
LCD_write_char(7,1,bai);
LCD_write_char(8,1,shi);
LCD_write_char(9,1,ge);
//LCD_write_char(10,1,'0');
//delay_nms(1000);
//LCD_write_char(10,1,'1');
delay_nms(200);
}
}
/************************************************************
函数功能:红外线触发的外中断处理函数
*************************************************************/
void Int0(void) interrupt 0
{
EX0=0; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
TH0=0; //定时器T0的高8位清0
TL0=0; //定时器T0的低8位清0
TR0=1; //开启定时器T0
while(IR==0); //如果是低电平就等待,给引导码低电平计时
TR0=0; //关闭定时器T0
LowTime=TH0*256+TL0; //保存低电平时间
TH0=0; //定时器T0的高8位清0
TL0=0; //定时器T0的低8位清0
TR0=1; //开启定时器T0
while(IR==1); //如果是高电平就等待,给引导码高电平计时
TR0=0; //关闭定时器T0
HighTime=TH0*256+TL0; //保存引导码的高电平长度
if((LowTime>7800)&&(LowTime<8800)&&(HighTime>3600)&&(HighTime<4700))
{
//根据电平长度确定是否为引导码,如果是引导码,就开始解码,否则放弃,引导码的低电平计时
//次数=9000us/1.085=8294, 判断区间:8300-500=7800,8300+500=8800.
if(DeCode()==1) // 执行遥控解码功能
{
switch(IRcode[2])
{
case 0x46:
/*恢复原始速度*/
CCAP0H=CCAP0L=0x2C;
CCAP1H=CCAP1L=0x2C;
forward();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"forward");
break;
case 0x15:
back();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"back");
break;
case 0x44:
left();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"left");
break;
case 0x43:
right();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"right");
break;
case 0x40:
stop();
//LCD_write_string(7,1," ");
//LCD_write_string(7,1,"stop");
break;
default:
/*调整PWM占空比*/
CCAP0H=CCAP0L=0x4C;
CCAP1H=CCAP1L=0x2C;
forward();/*调速后前进*/
//stop();
//LCD_write_string(0,1," ");
//LCD_write_string(0,1,"speed changed");
break;
}
}
}
EX0=1; //开启外中断EX0
}
5分悬赏