#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();
}
}
|