发送部分硬件电路如下,需要调制。



上图为调制前和调制后的波形。
发送协议:NEC编码

Start

DATA

Repeat(遥控按键按下不放时的信号)

DATA = 遥控器地址 + 遥控地址反码 + 控制码(遥控键码)+ 控制码反码,共4个Byte.
下图为遥控键码值。

接受部分如下图,内部集成有滤波电路和解调电路,直接由OUT口输出


在检测并接收数据时,采用外部中断来检测下降沿,用定时器来计时判断,当中断下降沿来后,启动定时器,到下一次中断,记录时间,判断是开始信号还是重发信号,若为开始信号,则准备接受数据,下面32个下降沿就是数据信号,判断时间来确定是0还是1,读取数据,然后检查读取的数据是否正确(DATA = 遥控器地址 + 遥控地址反码 + 控制码(遥控键码)+ 控制码反码),正确后将DataFlag = 1,并回到空闲状态等待下一次的信号。
代码如下:
cpp
#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;
}
}
}