//本人剛自學11天的單片機,寫成一個程序,發出來旨在交流和學習;
//按照自己的理解加以注釋,算是復習一遍;如有需要者,可以作為參考;
#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit moto=P1^0; //電機控制端口
sbit IRIN=P3^2; //紅外接收端口
u8 IrValue[6];
u8 Time;
u8 flag=100;
u8 num=0;
u8 pwm=0;
void delay(u8 i) //延時函數
{ while(i--);
}
void IrInit() //外部中斷0的初始化
{
IT0=1;
EX0=1;
EA=1;
IRIN=1;
}
void IrInit2() //定時器0的初始化
{TMOD = 0x01;
TH0 = 0x0FF;
TL0 = 0x9C;
EA = 1;
ET0 = 1;
TR0=1;}
void key() //檢測紅外用戶碼來確定風速檔位
{if(IrValue[2]==0x45) //0x45 0x46 0x47 是我的紅外遙控的三個用戶碼,可自調
{
pwm=30; //pwm調速,分為三檔
}
if(IrValue[2]==0x46)
{
pwm=60;
}
if(IrValue[2]==0x47)
{
pwm=90;
}
}
void main()
{moto=0; //電機關閉
IrInit2();
IrInit();
while(1)
{ key();
if(num==flag) num=0;
if(num<pwm) moto=1;
else moto=0;
}
}
void T0_time() interrupt 1 //定時器0服務程序
{ TH0 = 0x0FF;
TL0 = 0x9C;
num++;
}
void ReadIr() interrupt 0 //外部中斷0服務程序
{
u8 j,k;
u16 err;
Time=0;
delay(700);
if(IRIN==0) //檢測是否接收到紅外信號
{
err=1000;
while((IRIN==0)&&(err>0)) //等待起始碼的前9ms低電平過去
{
delay(1);
err--;
}
if(IRIN==1) //開始收到高電平
{
err=500; //等待起始碼的4.5ms高電平過去
while((IRIN==1)&&(err>0))
{
delay(1);
err--;
}
for(k=0;k<4;k++) //開始接收四組數據
{
for(j=0;j<8;j++) //每組數據有八位
{
err=60;
while((IRIN==0)&&(err>0)) //等待每一位的前0.56ms低電平過去(位0和位1的區別在于高電平的時間)
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //開始計時高電平時間
{
delay(10);
Time++;
err--;
if(Time>30) //若time大于30,說明接受數據錯誤,強制返回
{
return;
}
}
IrValue[k]>>=1; //數據移位
if(Time>=8) //大概以0.8ms為界區別位0和位1
{
IrValue[k]|=0x80; //1000 0000
}
Time=0; //Time置0
}
}
}
if(IrValue[2]!=~IrValue[3]) //檢驗,若不相等則強制返回
{
return;
}
}
}
|