资讯详情

51单片机入门——红外通信

文章目录

  • 红外光的基本原理
  • 红外遥控通信原理
  • NEC协议

红外光的基本原理

红外线是微波和可见光之间的电磁波,波长在 760 纳米到 1 毫米之间,是波形比红光长的非可见光。只要自然界中的所有物体的温度高于绝对零度(-273),就会有分子和原子的不规则运动,其表面就会继续辐射红外线。当然,虽然它们都辐射红外线,但不同物体的辐射强度是不同的,我们利用这一点将红外技术应用到我们的实际开发中。

红外发射管非常常用,在我们的遥控器上可以看到,它类似于发光二极管,但它发红外线,肉眼看不见。我们了解到,发光二极管的亮度会随着电流的增加而增加。同样,红外发射管的强度也会随着电流的增加而增加,如图所示:在这里插入图片描述 红外接收管是一种具有红外光敏特性的 PN 节属于光敏二极管,但只对红外光有反应。当没有红外光时,光敏管不会导致。当有红外光时,光敏管导致形成光电流,随着红外光强度的增加,电流在一定范围内增加。典型的红外接收管如图所示:在这里插入图片描述 如图所示: 在这里插入图片描述 在上图中,发射控制和接收检测接收单片机 IO 口上的。

发射部分:当发射控制输出高电时,三极管 Q1 不导通,红外发射管 L1 不会发射红外信号;当发射控制输出低电平时,通过三极管 Q1 导通让 L1 发出红外光。接收部分:R4 是一个电位器,我们通过调整电位器给 LM 2 脚提供阈值电压,可根据实际情况调试确定。红外光敏二极管 L2 收到红外光时,会产生电流,随着红外光从弱变强,电流从小变大。当没有红外光或红外光很弱时,3 脚的电压会接近 VCC,如果 3 脚的电压高于 2 脚,通过 LM393 比较器后,接收检测引脚输出高电平。当光强增大,电流增大时,3 脚的电压值等于 VCC-I*R3.电压会越来越小。当电压在一定程度上小于 2 脚时,接收检测引脚会变成低电平。

当该电路用于避障时,发射管首先发送红外信号。随着传输距离的增加,红外信号会逐渐衰减。如果遇到障碍物,会形成红外反射。当反射信号较弱时,光敏二极管 L2接收的红外光较弱,比较器 LM393 3 脚电压高于 2 脚电压,检测引脚输出高电平表明障碍物较远;当反射信号强时,检测引脚输出低电平表明障碍物较近。

当汽车跟踪时,必须有黑色和白色的轨道。当红外信号发送到黑色轨道时,由于吸光能力强,红外信号会被吸收,反射部分非常弱。白色轨道会反射大部分的红外信号。通常,跟踪汽车需要同时使用多个红外模块进行检测,从多个角度判断轨道,并根据判断结果调整汽车,使其按照正常跟踪前进。

红外遥控通信原理

在实际通信领域,发出的信号通常有较宽的频谱,大量的能量分布在较低的频率段,因此称为基带信号,不适合直接在信道中传输。为了便于传输,提高抗干扰能力,有效利用带宽,通常需要将信号调制到适合通道和噪声特性的频率,称为信号调制。在通信系统的接收端,应调整接收到的信号,并恢复原始基带信号。您可以了解这部分通信原理的内容。我们通常使用的红外遥控器中的红外通信通常使用 38K 左右负载波调制,下面我将向您介绍原理,首先查看发送部分原理。调制:用于传输信号来控制高频信号的范围、相位、频率等参数变化的过程,即用一个信号来装载另一个信号。例如,当我们的红外遥控信号需要发送时,它首先通过 38K 调制,如图所示:在这里插入图片描述 原始信号是我们要发送的数据0位或数据1位,而所谓的 38位K 载波频率为 38K 方波信号,调制后的信号是我们最终发出的波形。我们使用原始信号控制 38K 载波,当信号为数据0时,38K 毫无保留地发送所有载波,当信号为数据1时,不发送任何载波信号。

原则上,我们如何从电路的角度实现这一功能? 如下图所示:在这里插入图片描述 38K 载波,我们可以使用 455K 晶振通过 12 分频获得 37.91K,时基电路 也可以使用NE555生产,或使用单片机 PWM 产生。当信号输出引脚输出高电时,Q无论38,2 截止日期K 如何控制载波信号 Q1.右侧的垂直支路不会导通,红外管 L1 不会发送任何信息。当信号输出低电平时, 38K 载波会通过 Q1 释放,在 L1 上产生 38K 载波信号K 占空比为 1/3,也有 1/2 ,但相对较少。

在正常通信方面,接收端应首先通过监控、放大、滤波、解调等一系列电路处理信号,然后输出基带信号。但红外通信的集成接收头 HS0038B,所有这些电路都集成在一起了。我们只需要连接这个电路,就可以直接输出我们想要的基带信号,如图所示:在这里插入图片描述 由于红外接收头内放大器增益大,容易造成干扰,因此必须在接收头供电引脚上添加滤波电容器,官方手册给出的值为 4.7uF, 10,我们直接在这里使用uF,该手册还要求将 100 欧的电阻串联到电源引脚和电源之间,以进一步减少干扰。

当 HS0038B 监测到 38K的红外信号时,就会在 OUT 当没有 38时,引脚输出低电平K 的时候,OUT 引脚会输出高电平。然后我们把 OUT 引脚接到单片机 IO 口上,红外通信发送的数据可以通过编程获得。

大家想想,OUT 引脚输出的数据是否恢复为基带信号数据?当我们单片机接收基带信号数据时,如何判断接收到什么数据,应遵循什么协议?就像我们以前学到的 一样UART、I2C、SPI 等通信协议是基带通信协议,红外 38K 只调制基带信号,使信号更适合在信道中传输。

由于我们的红外调制信号是半双工的,同时空间只能允许一个信号源,所以红外基带信号不适合 I2C 或者 SPI 在通信协议中,我们前面提到过 UART 虽然是 2 线,但通信时其实是一条线,所以红外线可以在 UART 通信。当然,这种通信也不是没有限制的,比如HS0038B 的数据手册中标明,要想让 HS0038B 识别到 38K红外信号,那么这个 38K 载波必须大于 10 周期,这限制了红外通信基带信号的比例不得高于 3800。如果直接使用 38K 如果调制,波特率不应高于 3800。当然,还有许多其他基带协议可以通过红外调制。让我们介绍一遥控器的红外通信协议——NEC 协议。

NEC协议

家用电器遥控器的通信距离往往不高,红外线的成本远低于其他无线设备,因此红外线在家用电器遥控器的应用中一直占有一席之地。遥控器的基带通信协议有很多,大约有几十种,通常是 ITT 协议、NEC 协议、Sharp 协议、Philips RC-5 协议、Sony SIRC 协议等。最常用的是 NEC 协议了。

NEC 协议的数据格式包括了引导码、用户码、用户码(或者用户码反码)、按键键码和键码反码,最后一个停止位。停止位主要起隔离作用,一般不进行判断,编程时我们也不予理会。其中数据编码总共是 4 个字节 32 位,如图下所示。第一个字节是用户码,第二个字节可能也是用户码,或者是用户码的反码,具体由生产商决定,第三个字节就是当前按键的键数据码,而第四个字节是键数据码的反码,可用于对数据的纠错。

在这里插入图片描述 这个 NEC 协议表味着数据的方式不像我们以前学过的那样,比如 UART 如此直观,但每个数据本身也需要编码,然后编码载波调制。

  • :9ms 的载波 4.5ms 的空闲。
  • :560us 的载波 560us 的空闲。
  • :560us 的载波 1.68ms 的空闲。

结合上图,我们可以看到前面的黑色段落是引导码 9ms 载波,其次是引导码 4.5ms 的空闲,后面的数据码,是众多载波和空闲交叉,它们的长短就由其要传递的具体数据来决定。HS0038B 这个红外一体化接收头,当收到有载波的信号的时候,会输出一个低电平,空闲的时候会输出高电平,我们用逻辑分析仪抓出来一个红外按键通过HS0038B 解码后的图形来了解一下。 在这里插入图片描述 从图上可以看出,先是 9ms 载波加 4.5ms 空闲的起始码,数据码是低位在前,高位在后,数据码第一个字节是 8 组 560us 的载波加 560us 的空闲,也就是 0x00,第二个字节是 8 组 560us的载波加 1.68ms 的空闲,可以看出来是 0xFF,这两个字节就是用户码和用户码的反码。按键的键码二进制是 0x0C,反码就是 0xF3,最后跟了一个 560us 载波停止位。对于我们的遥控器来说,不同的按键,就是键码和键码反码的区分,用户码是一样的。这样我们就可以通过单片机的程序,把当前的按键的键码给解析出来。

我们前边学习中断的时候,学到 51 单片机有外部中断 0 和外部中断 1 这两个外部中断。我们的红外接收引脚接到了 P3.3 引脚上,这个引脚的第二功能就是外部中断 1。在寄存器TCON 中的 bit3 和 bit2 这两位,是和外部中断 1 相关的两位。其中 IE1 是外部中断标志位,当外部中断发生后,这一位被自动置 1,和定时器中断标志位 TF 相似,进入中断后会自动清零,也可以软件清零。bit2 是设置外部中断类型的,如果 bit2 为 0,那么只要 P3.3 为低电平就可以触发中断,如果 bit2 为 1,那么 P3.3 从高电平到低电平的下降沿发生才可以触发中断。此外,外部中断 1 使能位是 EX1。那下面我们就把程序写出来,使用数码管把遥控器的用户码和键码显示出来。

Infrared.c 文件主要是用来检测红外通信的,当发生外部中断后,进入外部中断,通过定时器 1 定时,首先对引导码判断,而后对数据码的每个位逐位获取高低电平的时间,从而得知每一位是 0 还是 1,最终把数据码解出来。虽然最终实现的功能很简单,但因为编码本身的复杂性,使得红外接收的中断程序在逻辑上显得就比较复杂,那么我们首先提供出中断函数的程序流程图,大家可以对照流程图来理解程序代码。 在这里插入图片描述

  • infrared.c
/* 本例程使用晶振为24MHz */#include "infrared.h"#include <reg52.h>bit irflag = 0; //红外接收标志,收到一帧正确数据后置 1unsigned char ircode[4]; //红外代码接收缓冲区/* 初始化红外接收功能 */void InitInfrared(){
     	IR_INPUT = 1; //确保红外接收引脚被释放	TMOD &= 0xf0; //清零 T0 的控制位	TMOD |= 0x01; //配置 T0 为模式 1	TR0 = 0; //停止 T0 计数	ET0 = 0; //禁止 T0 中断	IT0 = 1; //设置 INT0 为负边沿触发	EX0 = 1; //使能 INT0 中断}/* 获取当前高电平的持续时间 */unsigned int GetHighTime(){
     	TH0 = 0; //清零 T0 计数初值	TL0 = 0;	TR0 = 1; //启动 T0 计数	while (IR_INPUT) //红外输入引脚为 1 时循环检测等待,变为 0 时则结束本循环	{
     		if (TH0 >= 0x8c) //当 T0 计数值大于 0x8c00,即高电平持续时间超过约 18ms 时		{
      			break; //强制退出循环,是为了避免信号异常时,程序假死在这里。		}	}	TR0 = 0; //停止 T0 计数	return (TH0 * 256 + TL0); //T0 计数值合成为 16bit 整型数,并返回该数}/* 获取当前低电平的持续时间 */unsigned int GetLowTime(){
     	TH0 = 0; //清零 T0 计数初值	TL0 = 0;	TR0 = 1; //启动 T0 计数	while (!IR_INPUT) //红外输入引脚为 0 时循环检测等待,变为 1 时则结束本循环	{
     		if (TH0 >= 0x8c) //当 T0 计数值大于 0x8c00,即低电平持续时间超过约 18ms 时		{
      			break; //强制退出循环,是为了避免信号异常时,程序假死在这里。		}	}	TR0 = 0; //停止 T1 计数	return (TH0 * 256 + TL0); //T0 计数值合成为 16bit 整型数,并返回该数}/* INT1 中断服务函数,执行红外接收及解码 */void EXINT1_ISR() interrupt 0{
     	unsigned char i, j;	unsigned char byt;	unsigned int time;	 	//接收并判定引导码的 9ms 低电平	time = GetLowTime();	if ((time < (8500 * 2)) || (time > (9500 * 2))) //时间判定范围为 8.5~9.5ms,	{
      //超过此范围则说明为误码,直接退出		IE0 = 0; //退出前清零 INT1 中断标志		return;	}	//接收并判定引导码的 4.5ms 高电平	time = GetHighTime();	if ((time < (4000 * 2)) || (time > (5000 * 2))) //时间判定范围为 4.0~5.0ms,	{
      //超过此范围则说明为误码,直接退出		IE0 = 0;		return;	}	//接收并判定后续的 4 字节数据	for (i = 0; i < 4; i ++) //循环接收 4 个字节	{
     		for (j = 0; j < 8; j ++) //循环接收判定每字节的 8 个 bit		{
     			//接收判定每 bit 的 560us 低电平			time = GetLowTime();			if ((time < (340 * 2)) || (time > (780 * 2))) //时间判定范围为 340~780us,			{
      //超过此范围则说明为误码,直接退出				IE0 = 0;				return;			}			//接收每 bit 高电平时间,判定该 bit 的值			time = GetHighTime();			if ((time > (340 * 2)) && (time < (780 * 2))) //时间判定范围为 340~780us,			{
      //在此范围内说明该 bit 值为 0				byt >>= 1; //因低位在先,所以数据右移,高位为 0			}			else if ((time > (1460 * 2)) && (time < (1900 * 2))) //时间判定范围为 1460~1900us,			{
      //在此范围内说明该 bit 值为 1				byt >>= 1; //因低位在先,所以数据右移,				byt |= 0x80; //高位置 1			}			else //不在上述范围内则说明为误码,直接退出			{
     				IE0 = 0;				return;			}		}		ircode[i] = byt; //接收完一个字节后保存到缓冲区	}	irflag = 1; //接收完毕后设置标志	IE0 = 0; //退出前清零 INT1 中断标志}
  • infrared.h
#ifndef _INFRARED_H#define _INFRARED_H#include <reg52.h>sbit IR_INPUT = P3^2; //红外接收引脚extern void InitInfrared();extern bit irflag; //红外接收标志,收到一帧正确数据后置 1extern unsigned char ircode[4]; //红外代码接收缓冲区#endif
  • mian.c
#include <reg52.h>#include "infrared.h"unsigned char ledChar[18] = {
      //共阴极数码管显示字符转换表	0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 	0x7F, 0x6F, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71, 	0x40, 0x00 };unsigned char ledBuff[8] = {
      //数码管显示缓冲区 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};unsigned char T1RH = 0; //T1 重载值的高字节unsigned char T1RL = 0; //T1 重载值的低字节void ConfigTimer1(unsigned int ms);void main(){
     	EA = 1; //开总中断	InitInfrared(); //初始化红外功能	ConfigTimer1(1); //配置 T1 定时 1ms	PT1 = 1; //配置 T1 中断为高优先级,启用本行可消除接收时的闪烁	while (1)	{
     		if (irflag) //接收到红外数据时刷新显示		{
     			irflag = 0;			ledBuff[5] = ledChar[ircode[0] >> 4]; //用户码显示			ledBuff[4] = ledChar[ircode[0]&0x0F];			ledBuff[1] = ledChar[ircode[2] >> 4]; //键码显示			ledBuff[0] = ledChar[ircode[2]&0x0F];		}	} }/* 配置并启动 T1,ms-T0 定时时间 */void ConfigTimer1(unsigned int ms){
     	unsigned long tmp; //临时变量 	tmp = 24000000 / 12; //定时器计数频率	tmp = (tmp * ms) / 1000; //计算所需的计数值	tmp = 65536 - tmp; //计算定时器重载值	tmp = tmp + 13; //补偿中断响应延时造成的误差	T1RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节	T1RL = (unsigned char)tmp;	TMOD &= 0x0f; //清零 T1 的控制位	TMOD |= 0x10; //配置 T1 为模式 1	TH1 = T1RH; //加载 T1 重载值	TL1 = T1RL;	ET1 = 1; //使能 T1 中断	TR1 = 1; //启动 T1}/* 数码管动态扫描刷新函数,需在定时中断中调用 */void LedScan(){
     	static unsigned char i = 0; //动态扫描的索引 	P0 = ledChar[11]; //显示消隐	P2 = ~(0x80 >> i);	P0 = ledBuff[i];	i ++;	i &= 0x07;}/* T0 中断服务函数,执行数码管扫描显示 */void InterruptTimer0() interrupt 3{
     	TH1 = T1RH; //重新加载重载值	TL1 = T1RL;	LedScan(); //数码管扫描显示}

main.c 文件的主要功能就是把获取到的红外遥控器的用户码和键码信息,传送到数码管上显示出来,并且通过定时器 T0 的 1ms 中断进行数码管的动态刷新。

标签: 红外发光二极管的特性

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台