前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >51单片机之红外通信原理图_单片机红外通信原理

51单片机之红外通信原理图_单片机红外通信原理

作者头像
全栈程序员站长
发布2022-11-02 09:15:31
7400
发布2022-11-02 09:15:31
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

1.红外遥控简介

红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点。 由于红外线为不可见光,因此对环境影响很小,再由红外光波动波长远小于无线电波的波长,所以红外线遥控不会影响其他家用电器,也不会影 响临近的无线电设备。

红外线是波长在760nm~1mm之间的非可见光。红外通信装置由红外发射管和红外接受管组成,红外发射管是能发射出红外线的发光二极管,发射强度随着电流的增大而增大;红外接受管是一个具有红外光敏感特征的PN节的光敏二极管,只对红外线有反应,产生光电流。

2.信号调制原理

基带信号:从信号源发出没有经过调制的原始信号,特点是频率较低,信号频率从0开始,频谱较宽。 调制:就是用待传送信号去控制某个高频信号的幅度、相位、频率等参量变化的过程,即用一个信号去装载另一个信号。

红外遥控器使用38KB的载波对原始信号进行解调,原理如下:

51单片机之红外通信原理图_单片机红外通信原理
51单片机之红外通信原理图_单片机红外通信原理

调制后产生一定频段的高低电平,但红外接收头接受到的信号和调制后的信号电平相反。

3.NEC协议

  • 8 位地址和 8 位指令长度;
  • 地址和命令 2 次传输(确保可靠性)
  • PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;
  • 载波频率为 38Khz;
  • 位时间为 1.125ms 或 2.25ms;
51单片机之红外通信原理图_单片机红外通信原理
51单片机之红外通信原理图_单片机红外通信原理

(1)NEC 码的位定义:一个脉冲对应 560us 的连续载波;逻辑“1”:560us脉冲+1.68ms低电平; 逻辑“0”:560us脉冲+560us低电平。而遥控接收头在收到脉冲的时候为低电平,在没有脉冲的时候为高电平,这样,我们在接收头端收到 的信号为:逻辑 1 应该是 560us 低+1680us 高,逻辑 0 应该是 560us 低+560us 高。

(2)NEC 遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。 接收端的同步码由一个 9ms 的低电平和一个 4.5ms 的高电平组成 ,地址码、地址反码、控制码、控制反码均是 8 位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可 用于校验)。

比如接收到0100 1000的数据,因为低位在前,高位在后,所以要转化成0001 0010

我们遥控器的按键“▽”按下时,从红外接收头端收到的波形如图:

51单片机之红外通信原理图_单片机红外通信原理
51单片机之红外通信原理图_单片机红外通信原理

从上图可以看到,其地址码为 0 ,地址反码为255,控制码为 168,控制反码为87 。

可以看到在 100ms 之后,我们还收到了几个脉冲,这是 NEC 码规定的连发码 ( 由 9ms 低电平 +2.5m 高电平 +0.56ms 低电平 +97.94ms 高电平组成 )。如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,即发送的是以110ms为周期的重复码 ,可以通过统计连发码的次数来标记按键按下的长短/次数。

(3)发射端的重复码由9ms高电平和2.25ms的低电平以及560us的高电平组成。

51单片机之红外通信原理图_单片机红外通信原理
51单片机之红外通信原理图_单片机红外通信原理

二.实验例程 1.实验原理

产生下降沿,进入外部中断0的中断函数,延时一下之后检IO口是否还是低电平,是就等待9ms的低电平过去。等待完9ms低电平过去,再去等待4.5ms的高电平过去。接着开始接收传送的4组数据先等待560us的低电平过去检测高电平的持续时间,如果超过1.12ms那么是高电平(高电平的的持续时间为1680us,低电平的持续时间为565us。)检测接收到的数据和数据的反码进行比较,是否等到的数据是一样的。

红外遥控键值表:

51单片机之红外通信原理图_单片机红外通信原理
51单片机之红外通信原理图_单片机红外通信原理

2.实验程序

方法1:使用外部中断(普中科技代码)

代码语言:javascript
复制
/**************************************************************************************
*		              红外通信实验												  *
实现现象:下载程序后,数码管显示红外遥控键值数据
注意事项:	红外遥控器内的电池绝缘片一定要抽掉																			  
***************************************************************************************/
#include "reg52.h"			 //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16;	  //对数据类型进行声明定义
typedef unsigned char u8;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit IRIN=P3^2;
u8 IrValue[6];
u8 Time;
u8 DisplayData[8];
u8 code smgduan[17]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、H的显示码
/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);	
}
/*******************************************************************************
* 函数名         :DigDisplay()
* 函数功能		 :数码管显示函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void DigDisplay()
{
u8 i;
for(i=0;i<3;i++)
{
switch(i)	 //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位	
}
P0=DisplayData[2-i];//发送数据
delay(100); //间隔一段时间扫描	
P0=0x00;//消隐
}		
}
/*******************************************************************************
* 函数名         : IrInit()
* 函数功能		   : 初始化红外线接收
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void IrInit()
{
EA=1;	//打开总中断
EX0=1;//打开中断0允许
IT0=1;//下降沿触发
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	
IrInit();
while(1)
{	
DisplayData[0] = smgduan[IrValue[2]/16];
DisplayData[1] = smgduan[IrValue[2]%16];
DisplayData[2] = smgduan[16];
DigDisplay();		
}		
}
/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能		   : 读取红外数值的中断函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void ReadIr() interrupt 0
{
u8 j,k;
u16 err;
Time=0;					 
delay(700);	//7ms
if(IRIN==0)		//确认是否真的接收到正确的信号
{	 
err=1000;				//1000*10us=10ms,超过说明接收到错误的信号
/*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时
侯,程序死在这里*/	
while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去  		
{			
delay(1);
err--;
} 
if(IRIN==1)			//如果正确等到9ms低电平
{
err=500;
while((IRIN==1)&&(err>0))		 //等待4.5ms的起始高电平过去
{
delay(1);
err--;
}
for(k=0;k<4;k++)		//共有4组数据
{				
for(j=0;j<8;j++)	//接收一组数据
{
err=60;		
while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
{
delay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0))	 //计算高电平的时间长度。
{
delay(10);	 //0.1ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1;	 //k表示第几组数据
if(Time>=8)			//如果高电平出现大于565us,那么是1
{
IrValue[k]|=0x80;     //接收的第1个数为高电平;在第二个for循环中,数据会向右移8次
}
Time=0;		//用完时间要重新赋值							
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}			
}

方法2:不使用外部中断,直接用定时中断

代码语言:javascript
复制
#include "IR.h"
#include "extern.h"
#define  P_IR  	 (PT2_DIN&0x08)		//红外
//-------10ms----------------------
void SBR_IR_PRO()
{
if(bfirstover_NUM>=C_IR_up_time)
{
bfirstover_NUM=0;
f_ir_keyupping=0;
IR_DEAL_INIT();
}
else
{
IR_DEAL_PRO1();
}
}
//----------10ms-------------
void IR_DEAL_PRO1()
{
if(P_IR)		//高电平
{
if(!f_ir_old)
{
f_ir_old=1;
//-------------上升沿 0-1--------------------
bfirstover_NUM=0;
if(f_ir_head)		  //地址码的第一个低电平后f_ir_head为1
{
bIrCnt=0;		  //定时器125us加1
}
else
{
if(bIrCnt<C_IR_head_min||bIrCnt>C_IR_head_max)	//低电平时间
{
IR_DEAL_INIT();	  //错误信号
}
else
{
bIrCnt=0;
f_ir_head_one=1;
}
}
}
}
else			//低电平
{
if(f_ir_old)			//f_ir_old初始时为1;经过高电平为1
{
f_ir_old=0;
//-------------下降沿 1-0------------------
bfirstover_NUM=0;
if(f_ir_head)		 //初始时为0;地址码的第一个低电平后为1
{
IR_DATA_COM_PRO1();
}
else
{
//---------引导码----0--------------
if(f_ir_head_one)	 //初始时为0;经过开始信号后为1
{
if((bIrCnt>=16)&&(bIrCnt<=20))	//重复码
{
IR_REPEAT_CNT++;	   //记录重组码次数
}
else
{
f_ir_head=1;
}
}
bIrCnt=0;
}
}
}
}
//-------10ms--------初始状态-----------
void  IR_DEAL_INIT()
{
birread_num=0;
f_ir_head=0;
f_ir_old=1;
F_IRfrist_over=0;
f_ir_head_one=0;
IR_REPEAT_CNT=0;
}
//--------下降沿--用所得的高电平时间决定逻辑“1”和“0”------------------
void  IR_DATA_COM_PRO1()
{
if(!f_ir_keyupping)	//初始值为0
{
if((bIrCnt<=1)||(bIrCnt>=20))	//这时的bIrCnt是高电平时间
{
IR_DEAL_INIT();	  //错误信号
}
else
{
birread_num++;				//记录7次移位
if(birread_num>=250)
birread_num=250;   //设置一个值 防止按键一直按着  变量溢出
if(birread_num==1)
{
IR_CODE_VALUE1=0;   //控制反码
IR_CODE_VALUE2=0;   //控制码
IR_CODE_VALUE3=0;  //地址反码
IR_CODE_VALUE4=0;  //地址码
}
else
{
IR_DATA_COM_PRO2();
}
}
}
}
void  IR_DATA_COM_PRO2()
{	
if(birread_num<=C_readover)
{    
if(birread_num<=8)
IR_CODE_VALUE4>>=1;		//移位7次	
else if(birread_num<=16)
IR_CODE_VALUE3>>=1;		
else if(birread_num<=24)
IR_CODE_VALUE2>>=1;				
else						
IR_CODE_VALUE1>>=1;	
if(bIrCnt>=C_l_length)	//大于9*125us 就判断为逻辑“1”
{
if(birread_num<=8)
IR_CODE_VALUE4|=0x80;	
else if(birread_num<=16)
IR_CODE_VALUE3|=0x80;			
else if(birread_num<=24)
IR_CODE_VALUE2|=0x80;							
else						
IR_CODE_VALUE1|=0x80;
}
}						
bIrCnt=0;
if(birread_num==C_readover)
{
//*************接收完毕后*********
f_ir_keyupping=1;
if(!F_IRfrist_over)
{
F_IRfrist_over=1;
SBR_IR_DATA_OUT();
//----------------------
f_ir_head=0;
f_ir_head_one=0;		
}
}
}
//--------------数据输出---------------------
void  SBR_IR_DATA_OUT()
{
if((IR_CODE_VALUE4==C_user_value)&&(IR_CODE_VALUE3==C_user_value_1))
{}
else
return;  //退出
//-----------------
if((IR_CODE_VALUE2==C_IRDATA_KEY1)&&(IR_CODE_VALUE1==(~C_IRDATA_KEY1)))
{
//-------ON
PT24DO=1;
}
if((IR_CODE_VALUE2==C_IRDATA_KEY2)&&(IR_CODE_VALUE1==(~C_IRDATA_KEY2)))
{
//-------OFF
PT24DO=0;
}
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/203649.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 二.实验例程 1.实验原理
  • 2.实验程序
  • 方法2:不使用外部中断,直接用定时中断
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档