51单片机红外遥控

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

上图为调制前和调制后的波形。

发送协议: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;
		}
	}
	
}
相关推荐
charlie1145141915 小时前
嵌入式C++工程实践第16篇:第四次重构 —— LED模板,从通用GPIO到专用抽象
c语言·开发语言·c++·驱动开发·嵌入式硬件·重构
深圳市九鼎创展科技8 小时前
MT8883 vs RK3588 开发板全面对比:选型与场景落地指南
大数据·linux·人工智能·嵌入式硬件·ubuntu
三品吉他手会点灯10 小时前
STM32 VSCode 开发-C/C++的环境配置中,找不到C/C++: Edit Configurations选项
c语言·c++·vscode·stm32·单片机·嵌入式硬件·编辑器
yu859395812 小时前
STM32 智能红外循迹小车(含码盘测速 + 避障)
stm32·单片机·嵌入式硬件
三品吉他手会点灯12 小时前
STM32 DAP 烧录报错-最终解决方法的原理和操作逻辑
stm32·单片机·嵌入式硬件
fengfuyao98513 小时前
TFT 彩屏 GUI 开发
stm32·嵌入式硬件
长安第一美人13 小时前
算能 BM1688 低延迟推流:Qt+WebSocket 直出 H5/HDMI
开发语言·网络·嵌入式硬件·websocket·交互
yongui4783414 小时前
STM32 三相电机FOC驱动方案(三电阻单电阻双模式)
stm32·单片机·嵌入式硬件
WeeJot嵌入式14 小时前
【串口】初始串口-轮询模式
stm32·单片机·嵌入式
yong999015 小时前
基于 51 单片机配合霍尔传感器实现计数 + 转速测量
单片机·嵌入式硬件