红外遥控是我们现实生活中必不可少的一员。遥控,顾名思义即在迢遥的地方进行掌握,实在也便是说远程通信。红外遥控便是以红外线为传输介质的遥控。
红外遥控器是怎么事情的?实在它内部便是有一个单片机,单片机的I/O口掌握一个红外LED灯(当然一样平常会加外部放大电路以增大传输间隔),在内部编码后发送出去,然后电视或者空调之类的可以用红外遥控掌握的电器在吸收到红外旗子暗记后就会进行解码,并根据制订好的协议实行特定动作,比如电视可能换台、调节音量等。现在有的手机就带有红外遥控功能,实在也是用单片机的功能实现的。

红外遥控解码

有的时候,我们希望仿照一些遥控器的功能,这时候就要对这些遥控器的数据进行解码。
在进行解码前,我们先来理解一下红外编码。红外编码有很多种,最常用的编码是NEC编码。NEC格式的编码如下:
NEC格式的红外编码是连续的32位二进制码组。32位二进制码组之前的勾引码,用于区分每次的传输;在起始码之后的才是32位二进制码组,个中8位用户识别码和8位反码(反码紧张用于)校验,用户识别码的浸染紧张是区分不同品牌的遥控器;接着便是8位操作码和反码,用于表示哪个按键被按下。
NEC格式的编码除勾引码和起始码外,用于交互数据的信息采取脉宽调制的串行码,在38kHz的载波下,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如下所示:
理解了红外编码,就可以进行红外解码了。
实现方法
一样平常,进行红外解码我们须要先将接管到的有效旗子暗记与外界环境的滋扰旗子暗记分离开,这便是载波的浸染。现在市情上有很多一体化红外吸收头,内部是红外吸收二极管 +放大电路 +解调器。当吸收到红外旗子暗记后,先将其放大,然后把38kHz的旗子暗记保留下来。须要把稳的是一样平常一体化红外吸收头吸收到旗子暗记时输出是低电平,没有吸收旗子暗记时是高电平。
上面是常用红外吸收头的引脚,“OUT”脚接单片机的I/O口,“-”脚接电源负极,“+”脚接电源正极。
接好电路,就要进行解码事情了.实在解码事情紧张是识别勾引码,还有数据“0”“1”。我们看波形图,只要识别红外吸收头“OUT”引脚高低电平持续的韶光就可以了。这个可以用定时器中断完成,也可以用延时来判断。由于只完成解码事情,我们就用延时的方法更方便。
首先,红外吸收头没有接到旗子暗记时是高电平,等待其变低。之后,每隔900us丈量一次,若在10次内电平变高,解释这不是勾引码,退出重新开始;若10次内并没有变高,解释这便是勾引码,连续下一步。接着可以赓续定起始码,便是直接等待引脚电平变高再变低,就可以吸收数据了。
吸收数据,便是进行判断“0”和“1”。从位的定义我们可以创造“0”、“1”均以0.56ms的低电平开始,不同的是高电平的宽度不同,“0”为0.56ms,“1”为1.68ms,以是必须根据高电平的宽度差异“0”和“1”。
每一位“0”或者“1”在吸收头吸收旗子暗记即低电平的韶光都是一样的,直接等待低电平过去,在高电平时延时600us,如果600us时还是高电平,解释是“1”;如果是低电平即高电平过去了,解释是“0”。将这些数据结合到一起,便是吸收到的编码了。
将单片机的串口与电脑接好,就可以在串口显示我们读到的红外遥控数据了。
实当代码:
#include <reg52.h>
// --- 红外吸收一体化输出口 ----------------------------------
sbit IR_Out = P3^2;
bit START_Flag = 0;
bit BOOT_REPEATING_CODE_Flag = 0;
unsigned char DATA[4] = {0};
bdata unsigned char TEMP_BIT;
sbit B0 = TEMP_BIT^0;
sbit B1 = TEMP_BIT^1;
sbit B2 = TEMP_BIT^2;
sbit B3 = TEMP_BIT^3;
sbit B4 = TEMP_BIT^4;
sbit B5 = TEMP_BIT^5;
sbit B6 = TEMP_BIT^6;
sbit B7 = TEMP_BIT^7;
// --- 有无遥控旗子暗记判断函数 ----------------------------------
bit START_Judge();
// --- 连发码判断函数 ----------------------------------------
bit BOOT_REPEATING_CODE_Judge();
// --- \"大众0\"大众和\"大众1\"大众识别 ------------------------------------------
bit H_L_LEVEL_Judge();
bit START_Judge()
{
bit TEMP_Flag = 1;
unsigned char i = 0;
//在正常无遥控旗子暗记时,一体化红外吸收头输出是高电平,程序一贯在循环。
while ( IR_Out == 1);
//重复10次,目的是检测在6876~8352微秒内如果涌现高电平就退出解码程序
for(i =0;i <9; i++)
{
DELAY_Us(800); // 测试实际延时约为764~928us
if ( IR_Out == 1 )
{
TEMP_Flag = 0;
break;
}
}
return TEMP_Flag;
}
bit BOOT_REPEATING_CODE_Judge()
{
bit TEMP_Flag = 1;
while( IR_Out == 0 ) ; // 等待高电平避开9毫秒低电平勾引脉冲
DELAY_Ms(1); // 测试实际延时约为1.007ms
DELAY_Ms(1); // 测试实际延时约为1.007ms
DELAY_Us(200); // 0.086ms
DELAY_Us(200); // 0.086ms
DELAY_Us(200); // 0.086ms
// 共计2.272ms
if( IR_Out == 0 )
{
TEMP_Flag = 1; // 是连发码
}
else
{
TEMP_Flag = 0; // 不是连发码,而是勾引码
}
return TEMP_Flag;
}
bit H_L_LEVEL_Judge()
{
while( IR_Out == 0 ); // 等待地址码第一位的高电平旗子暗记
DELAY_Us(800); // 测试实际延时约为764~928us
if ( IR_Out == 1)
{
DELAY_Ms(1); // 测试实际延时约为1.007ms
return 1;
}
else
{
return 0;
}
// --- 串口初始化 --------------------------------------------
void UART_Initial();
void DELAY_Us(unsigned int Us)
{
unsigned int x;
for(x = 0; x <= (Us/200-1); x++);
}
void DELAY_Ms(unsigned int Ms)
{
unsigned int x,y;
for(x = 0; x <= (Ms-1); x++)
{
for(y = 0; y <= 120; y++);
}
}
void main()
{
unsigned char i;
UART_Initial();
IR_Out = 1;
while(1)
{
START_Flag = START_Judge();
BOOT_REPEATING_CODE_Flag = BOOT_REPEATING_CODE_Judge();
if ( START_Flag && !BOOT_REPEATING_CODE_Flag )
{
for(i =0;i <4; i++)
{
B0 = H_L_LEVEL_Judge();
B1 = H_L_LEVEL_Judge();
B2 = H_L_LEVEL_Judge();
B3 = H_L_LEVEL_Judge();
B4 = H_L_LEVEL_Judge();
B5 = H_L_LEVEL_Judge();
B6 = H_L_LEVEL_Judge();
B7 = H_L_LEVEL_Judge();
DATA[i] = TEMP_BIT;
}
for(i =0;i <4; i++)
{
SBUF = DATA[i];
while( TI == 0 );
TI = 0;
}
}
}
}
void UART_Initial()
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能吸收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1 = 0xFD; // TH1: reload value for 9600 baud @
// 11.0592MHz
TR1 = 1; // TR1: timer 1 run
EA = 0; // 关闭总中断
ES = 0; // 关闭串口中断
}
}
注
1、红外遥控的编码不但NEC,还有很多也有广泛运用如RC-5,RC-6等。
2、上面的代码所用指令是STC 89C52单片机,如需用其它芯片请另行变动。
以上所有信息仅作为学习互换利用,不作为任何学习和商业标准。若您对文中任何信息有异议,欢迎随时提出,感激!








