51单片机—红外遥控器和NEC协议

一、红外遥控器

1.1.红外线的介绍

人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为 0.62~0.76μm;紫光的波长范围为 0.38~0.46μm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线。红外线遥 控就是利用波长为 0.76~1.5μm 之间的近红外线来传送控制信号的。

1.2.红外遥控的介绍

红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出。

  • 通信方式:单工,异步
  • 红外LED波长:940nm
  • 通信协议标准:NEC标准

图一二是红外发射器,图三是红外接收器:
在这里插入图片描述

1.3.硬件电路

  • 空闲状态:红外LED不亮,接收头输出高电平
  • 发送低电平:红外LED以38KHz频率闪烁发光,接收头输出低电平
  • 发送高电平:红外LED不亮,接收头输出高电平

上图是发射器发射的信号,下图是经过接收器处理所接收到的信号:
在这里插入图片描述

1.3.1.红外发射器的硬件电路

下图是红外发射器的硬件电路,Q1和Q2两个三极管是PNP三极管,只有低电平导通,LED1才能亮,当IN输入低电平,Q2导通并结合38kHZ的信号传输到LED1,因此,LED1是高速的闪烁。
在这里插入图片描述

1.3.2.红外接收器的引脚图

在这里插入图片描述

1.4.遥控器键码

在这里插入图片描述

1.5.软件设计

下面是红外接收器的初始化IR.c代码:

#include <REGX52.H>
#include "INT0.h"
#include "Time0.h"

 
unsigned int IR_Time;
unsigned char IR_State;
 
unsigned char IR_Data[4];
unsigned char IR_pData;
 
unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command; 
 
 
void IR_Init(void)
{
	Timer0_Init();
	INT0_Init();
}

unsigned char IR_GetDataFlag(void)
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}

unsigned char IR_GetRepeatFlag(void)
{
	if(IR_RepeatFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

unsigned char IR_GetAddress(void)
{
	return IR_Address;
}

unsigned char IR_GetCommand(void)
{
	return IR_Command;
}


void Int0_Routine(void)  interrupt 0
{
	if(IR_State==0)
	{

		Timer0_SetCounter(0);
		Timer0_Run(1);
		IR_State=1;
	}
	else if(IR_State==1)
	{		
	
		IR_Time=Timer0_GetCounter();
		Timer0_SetCounter(0);
		//检测到开始
		if(IR_Time>13500-500 && IR_Time<13500+500)
		{		
			P2=0;		
			IR_State=2;
		}
		//检测到重复
		else if(IR_Time>11250-500 && IR_Time<11250+500) 
		{
			IR_RepeatFlag=1;
			Timer0_Run(0);
			IR_State=0;
		}
		else
		{
			IR_State=1;
		}
	}
	else if(IR_State==2)
	{
		IR_Time=Timer0_GetCounter();
		Timer0_SetCounter(0);
		if(IR_Time>1120-500 && IR_Time<1120+500) //如果为0
		{
			IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8)); 
			IR_pData++;
		}
		else if(IR_Time>2250-500 && IR_Time<2250+500) //如果为1
		{
			IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));	
			IR_pData++;
		}
		else
		{
			IR_pData=0;
			IR_State=1;
		}
		if(IR_pData>=32)
		{
			IR_pData=0;
			if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))   //地址码+地址反码 + 数据码+数据反码
			{
				IR_Address=IR_Data[0];
				IR_Command=IR_Data[2];
				IR_DataFlag=1;
			}
			Timer0_Run(0);
			IR_State=0;
		}
	}
}

下面是IR.h头文件代码,定义各个按键的名字:

#ifndef __IR_H__
#define __IR_H__

#define IR_POWER  			0x45
#define IR_MODE 			0x46
#define IR_MUTE  			0x47
#define IR_START_STOP 		0x44
#define IR_PREVIOUS 		0x40
#define IR_NEXT 			0x43
#define IR_EQ  				0x07
#define IR_VOL_MINUS 		0x15
#define IR_VOL_ADD 			0x09
#define IR_RPT 				0x19
#define IR_USD 			    0x0D
#define IR_1    		    0x0C
#define IR_2       			0x18
#define IR_3         	    0x5E
#define IR_4  	  	    	0x08
#define IR_5  				0x1C
#define IR_6  				0x5A
#define IR_7  		   	    0x42
#define IR_8  			    0x52
#define IR_9  			    0x4A
#define IR_0  				0x16

void IR_Init(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);

#endif

二、NEC协议

2.1.NEC码的位定义

2.1.1.逻辑0和逻辑1

一个脉冲对应 560us 的连续载波,一个逻辑 1 传输需要2.25ms(560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us脉冲+560us 低电平)。而红外接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。所以可以通过计算高电平时间判断接收到的数据是 0 还是 1。NEC 码位定义时序图如下图所示:
在这里插入图片描述

2.1.2.起始信号

先拉低9ms,再拉高4.5ms意为开始:
在这里插入图片描述

2.1.3.重复信号

当长按按键时,信号会重复上一次的操作,重复操作信号为,先拉低9ms,再拉高2.25ms:
在这里插入图片描述

2.1.4.一个数据帧

110ms为一个数据帧:
在这里插入图片描述

2.1.5.DATA的格式

在这里插入图片描述

三、外部中断

3.1.C51单片机内的外部中断

STC89C5X 系列单片机提供了 4 个外部中断:外部中断 O(INTO)、外部中断1(INT1)、外部中断 2(INT2)、外部中断 3(INT3)。

3.2.外部中断结构图及中断号

把红外接收器的OUT引脚接到INT0或INT1:
在这里插入图片描述

在这里插入图片描述
中断号:
在这里插入图片描述

3.3.外部中断寄存器

3.3.1.中断允许控制

CPU 对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE 控制的。
在这里插入图片描述

  • EX0(IE.0),外部中断 0 允许位;
  • ET0(IE.1),定时/计数器 T0 中断允许位;
  • EX1(IE.2),外部中断 0 允许位;
  • ET1(IE.3),定时/计数器 T1 中断允许位;
  • ES(IE.4),串行口中断允许位;
  • EA (IE.7), CPU 中断允许(总允许)位。

3.3.2.中断请求标志 TCON

在这里插入图片描述

  • IT0(TCON.0),外部中断 0 触发方式控制位。
    当 IT0=0 时,为电平触发方式。
    当 IT0=1 时,为边沿触发方式(下降沿有效)。
  • IE0(TCON.1),外部中断 0 中断请求标志位。
  • IT1(TCON.2),外部中断 1 触发方式控制位。
  • IE1(TCON.3),外部中断 1 中断请求标志位。
  • TF0(TCON.5),定时/计数器 T0 溢出中断请求标志位。
  • TF1(TCON.7),定时/计数器 T1 溢出中断请求标志位。

3.4.软件设计

下面是外部中断初始化的代码:

#include <REGX52.H>

void INT0_Init()
{
	IT0=1;
	IE0=0;
	EX0=1;
	EA=1;
	PX0=1;
}

下面是main.c代码,实现按下遥控,LCD屏幕显示按键号码:

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "IR.h"

unsigned char Num;
unsigned char Address;
unsigned char Command;


void main()  
{
	LCD_Init();
	IR_Init();
	LCD_ShowString(1,1,"ADDR  CMD  NUM");
	LCD_ShowString(2,1,"00    00   00 ");
	while(1)
	{
		if(IR_GetDataFlag() || IR_GetRepeatFlag())
		{
			Address=IR_GetAddress();
			Command=IR_GetCommand();
			
			LCD_ShowHexNum(2,1,Address,2);
			LCD_ShowHexNum(2,7,Command,2);
			
			if(Command==IR_VOL_MINUS)
			{
				Num--;
			}
			if(Command==IR_VOL_ADD)
			{
				Num++;
			}
			LCD_ShowNum(2,12,Num,3);			
			
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值