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;
		}
	}
	
}
相关推荐
LabVIEW开发2 小时前
LabVIEW+Arduino实现温度自适应直流电机控制
单片机·labview知识·labview功能·labview程序
FrozenLove_G5 小时前
服务器的BMC内部有系统吗?
stm32·单片机·嵌入式硬件
SongYuLong的博客5 小时前
openwrt源码编译环境搭建-安装Luci
linux·嵌入式硬件
宇宙realman_9995 小时前
DSP中断工作原理
单片机·嵌入式硬件
hazy1k5 小时前
ESP32基础-UART_串口通信
stm32·单片机·嵌入式硬件·51单片机·esp32
d111111111d7 小时前
STM32通信协议学习--I2C通信(了解)
笔记·stm32·单片机·嵌入式硬件·学习
雾岛听风眠7 小时前
STM32通信接口----USART
stm32·单片机·嵌入式硬件
Rousson9 小时前
硬件学习笔记--89 MCU主频对Uart波特率影响及采样点
笔记·单片机·学习
呉師傅9 小时前
国产化操作系统---银河麒麟安装步骤(简单介绍)
运维·网络·windows·单片机·电脑
树欲静而风不止慢一点吧10 小时前
在STM32 HAL库中使用 WFI 实现低功耗准确延时
stm32·单片机·嵌入式硬件