#include<reg52.h>
#include<intrins.h>
sbit IR_Out=P3^2; //红外信号输入口
sbit IR_Flag=P3^1;//主程序运行标志位,运行主程序时LED灭,运行中断程序时LED亮
sbit a1=P1^0;//车轮1
sbit a2=P1^1;
sbit a3=P1^2;//车轮3
sbit a4=P1^3;
sbit b1=P1^4;//车轮2
sbit b2=P1^5;
sbit b3=P1^6;//车轮4
sbit b4=P1^7;
#define led P1
#define uchar unsigned char
#define uint unsigned int
uint dat[4]={0,0,0,0},z;
uchar num=3,count=0,pd_ys1=0,pd_ys2=0;
void Int0() interrupt 0
{
uchar i,j;
EX0=0;//关闭外部中断0
IR_Flag=0;//执行中断程序时,LED灯亮
i=10;//0.793ms延时,运行10次
while(--i)
{
//定时0.793ms,延时0.793ms*10=7.93ms
TH0=0xfc;
TL0=0xe7;
TR0=1;
while(!TF0);
TF0=0;
TR0=0;
//这7.93ms期间只要IR_Out变高电平,就非合法的红外信号,跳出
if(IR_Out)
{
EX0=1;//准许中断
return;
}
}
//程序进行到这里,表明是合法的红外信号(利用9ms判断)
while(!IR_Out);//等待9ms低电平过去
//程序进行到这里,表明经过9ms低电平
TH0=0xf6;
TL0=0xff;
TR0=1; //时器T0开始计数
while(!TF0); //TF0:其值位1时,表示定时器T0计满溢出
TF0=0;
TR0=0;//延时2.305ms
//IR_Out为低表明是连发码,不予理睬,跳出
if(!IR_Out)
{
EX0=1;//允许外部中断
return;
}
//程序进行到这里,表明是引导码,等待4.5ms高电平的过去
while(IR_Out);
//开始接收用户码
for(i=0;i<4;i++)
{
for(j=0;j<8;j++)
{
while(!IR_Out);//等待低电平过去
dat[i]>>=1;//把上次的数据位右移一位
TH0=0xfc;
TL0=0xe7;
TR0=1;
while(!TF0);
TR0=0;
TF0=0;//延时0.793ms
//若为数据"1",则延时后IR_Out为高电平
if(IR_Out)
{
dat[i]|=0x80;//所有数据位1放最高位
while(IR_Out);//等待高电平过去
}
}
}
// led=dat[2];
if(dat[2]!=0x09&&dat[2]!=0x15)
z=dat[2];
EX0=1;//开中断
return;
}
void Inf_Dispose(void) //红外接收处理函数
{
switch(dat[2])
{
case 0x1c: //停止
P1=0XFF;
a1=1; b1=1;
break;
case 0x18: //前进
TH1=(65536-30000)/256;
TL1=(65536-30000)%256;
TR1=1;//开timer1
a1=0;
a3=0;
b1=0;
b3=0;
while(!pd_ys1);
pd_ys1=0;
a1=1;
a3=1;
b1=1;
b3=1;
while(!pd_ys2);
TR1=0;
pd_ys2=0;
break;
case 0x52: //后退
TH1=(65536-30000)/256;
TL1=(65536-30000)%256;
TR1=1;//开timer1
a2=0;
a4=0;
b2=0;
b4=0;
while(!pd_ys1);
pd_ys1=0;
a2=1;
a4=1;
b2=1;
b4=1;
while(!pd_ys2);
TR1=0;
pd_ys2=0;
break;
case 0x5a: //右转
TH1=(65536-30000)/256;
TL1=(65536-30000)%256;
TR1=1;//开timer1
a1=0;
a3=0;
while(!pd_ys1);
pd_ys1=0;
a1=1;
a3=1;
while(!pd_ys2);
TR1=0;
pd_ys2=0;
break;
case 0x08: //左转
TH1=(65536-30000)/256;
TL1=(65536-30000)%256;
TR1=1;//开timer1
b1=0;
b3=0;
while(!pd_ys1);
pd_ys1=0;
b1=1;
b3=1;
while(!pd_ys2);
TR1=0;
pd_ys2=0;
break;
case 0x09: //pwm++
dat[2]=z;
num+=3;
if(num==12)
num=9;
break;
case 0x15:; //pwm--
dat[2]=z;
num-=3;
if(num==0)
num=3;
break;
default:
break;
}
}
void timer1() interrupt 3 using 1
{
TH1=(65536-30000)/256;
TL1=(65536-30000)%256;
count++;
if(count==num)
{
pd_ys1=1;
}
if(count==10)
{
count=0;
pd_ys2=1;
}
}
void main()
{
IR_Out=1; //此口为MCU输入口,故需要置1
IR_Flag=1; //灭LED灯
TMOD=0x01; //定时器0,方式1
IT0=1; //外部中断0,下降沿触发
EX0=1; //准许外部中断
EA=1; //CPU准许中断
TMOD=0x01;
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
ET1=1;
while(1)
{
Inf_Dispose();
}
}
|