51单片机红外遥控
发送部分硬件电路如下,需要调制。
上图为调制前和调制后的波形。
发送协议:NEC编码
Start
DATA
Repeat(遥控按键按下不放时的信号)
DATA = 遥控器地址 + 遥控地址反码 + 控制码(遥控键码)+ 控制码反码,共4个Byte.
下图为遥控键码值。
接受部分如下图,内部集成有滤波电路和解调电路,直接由OUT口输出
在检测并接收数据时,采用外部中断来检测下降沿,用定时器来计时判断,当中断下降沿来后,启动定时器,到下一次中断,记录时间,判断是开始信号还是重发信号,若为开始信号,则准备接受数据,下面32个下降沿就是数据信号,判断时间来确定是0还是1,读取数据,然后检查读取的数据是否正确(DATA = 遥控器地址 + 遥控地址反码 + 控制码(遥控键码)+ 控制码反码),正确后将DataFlag = 1,并回到空闲状态等待下一次的信号。
代码如下:
#include <REGX52.H>
unsigned char IR_State;
unsigned int IR_Time;
unsigned char IR_RepeatFlag;
unsigned char IR_DataFlag;
unsigned char IR_Data[4];
unsigned char IR_LData;
unsigned char IR_Address;
unsigned char IR_Command;unsigned char get_IR_DataFlag()
{if(IR_DataFlag){IR_DataFlag = 0;return 1;}return 0;
}unsigned char get_IR_RepeatFlag()
{if(IR_RepeatFlag){IR_RepeatFlag = 0;return 1;}return 0;
}unsigned char get_IR_Address()
{return IR_Address;
}unsigned char get_IR_Command()
{return IR_Command;
}void Timer0_Init(void)
{TMOD &= 0xF0; TMOD |= 0x01; TL0 = 0; TH0 = 0; TF0 = 0; TR0 = 0;
}void INT0_Init()
{IT0 = 1;IE0 = 0;EA = 1;EX0 = 1;PT0 = 1;
}void IR_Init()
{Timer0_Init();INT0_Init();
}void Timer_Start()
{TR0 = 1;
}void Time_counter(unsigned int count)
{TH0 = count/256;TL0 = count%256;
}void Timer_Stop()
{TR0 = 0;
}unsigned int GetTime()
{return (TH0<<8) | TL0;
}void INT0_Routine() interrupt 0
{if(IR_State == 0){Time_counter(0);Timer_Start();IR_State = 1;}else if(IR_State == 1){IR_Time = GetTime();Time_counter(0);if(IR_Time >= 13500-1000 && IR_Time <= 13500+1000){IR_State = 2;}else if(IR_Time >= 11250-400 && IR_Time <= 11250+400){IR_RepeatFlag = 1;IR_State = 0;}else{IR_State = 1;}}else if(IR_State == 2){IR_Time = GetTime();Time_counter(0);if(IR_Time >= 1120-500 && IR_Time <= 1120+500){IR_Data[IR_LData/8] &= ~(0x01<<(IR_LData%8));IR_LData++;}else if(IR_Time >= 2250-500 && IR_Time <= 2250+500){IR_Data[IR_LData/8] |= (0x01<<(IR_LData%8));IR_LData++;}else{IR_LData = 0;IR_State = 1;}if(IR_LData>=32){IR_LData = 0;if(IR_Data[0] == ~IR_Data[1] && IR_Data[2] == ~IR_Data[3]){IR_DataFlag = 1;IR_Address = IR_Data[0];IR_Command = IR_Data[2];}Timer_Stop();IR_State = 0;}}}