红外遥控实验

2023-05-16

红外线简介

          人眼所能看到的可见光,按波长从长到短排列,依次为红(660nm)、橙(610nm)、黄(585nm)、绿(555nm)、青(500nm)、蓝(460nm)、紫(405nm)。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线。如下所示:

          红外线遥控是利用波长为 0.76~1.5μm 之间的近红外线来传送控制信号的。

红外遥控的原理

          红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠, 功耗低,成本低,易实现等优点。

          红外遥控通信系统通常由红外发射装置和红外接收设备两大部分组成。

 红外发射装置

          红外发射装置,即红外遥控器,由键盘电路、红外编码电路、电源电路和红外发射电路组成。红外发射电路的主要元件为红外发光二极管,其内部材料不同于普通发光二极管,在红外发光二极管两端施加一定电压时,会发出红外线,而非可见光。通常使用的红外发光二极管发出的红外线波长为 940nm 左右。红外遥控器和红外发光二极管如下图所示:

            为了提高抗干扰性和降低能耗,通常红外遥控器使用载波的方式传送二进制编码,常用的载波频率为 38kHz,这是由发射端所使用的 455kHz 晶振来决定的(在发射端要对晶振进行整数分频,分频系数一般取 12,所以 455kHz÷12≈37.9kHz≈38kHz)。通常的红外遥控器是将遥控信号(二进制脉冲码)调制在 38KHz 的载波上,经缓冲放大后送至红外发光二极管,转化为红外信号发射出去。

          二进制脉冲码的形式有多种,最常用的是 NEC Protocol 的 PWM 码 (脉冲宽度调制)和 Philips RC-5 Protocol 的 PPM 码(脉冲位置调制)。开发红外接收设备,需要知道红外遥控器的编码方式和载波频率,才能选取一体化红外接收头和制定解码方案。本文使用红外遥控器使用的是 NEC 协议,特征如下:

  • 8 位地址和 8 位指令长度
  • 地址和命令 2 次传输
  • PWM 脉冲宽度调制,以发射红外载波的占空比代表“0”和“1”,占空比为1:3
  • 载波频率: 38Khz
  • 位时间为 1.125ms 或 2.25ms

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

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

            完整的NTC编码如下: 

            NEC 码还规定了连发码(由 9ms 低电平+2.5m 高电平+0.56ms 低电平 +97.94ms 高电平组成),如果在一帧数据发送完毕之后,红外遥控器按键仍然没有放开,则发射连发码,可以通过统计连发码的次数来标记按键按下的长短或次数。

红外接收设备

            红外接收设备由红外接收电路、红外解码、电源和应用电路组成。红外遥控接收器的主要作用是将遥控发射器发来的红外光信号转换成电信号,并且放大、 限幅、检波、整形,形成遥控指令脉冲,输出至遥控微处理器。如今通常采用成品红外接收头。成品红外接收头的封装大致有两种:一种采用铁皮屏蔽;一种是塑料封装。均有三只引脚,即电源正( VDD)、 电源负(GND)和数据输出(VOUT)。其外观实物图如下图所示:

            由于红外接收头在没有脉冲的时候为高电平,当收到脉冲的时候为低电平, 所以可以通过外部中断的下降沿触发中断,在中断内通过计算高电平时间来判断接收到的数据是 0 还是 1。

硬件部分

        使用到硬件资源如下:

  1. 动态数码管
  2. 红外接收头和遥控器

        动态数码管电路在前面文章动态数码管实验都介绍过,这里就不再重复。红外遥控器和接收 头是一体的,内部结构不用去管它。红外接收模块电路如下图所示:

        从上图可以看出,红外接收头的输出管脚接至 J11 端子 上,为了保证红外接收头输出管脚默认为高电平,需外接一个 10K 上拉电阻,因为单片机 IO 口都增加了 10K 上拉电阻,所以此处可省略。这里使用单片机的 P3.2 管脚(对应 P3.2 口的附加功能)与红外接收头输出管脚连接。

软件部分

         所要实现的功能是:数码管上显示红外解码遥控器键值。

         程序框架如下:

  1. 编写数码管显示功能
  2. 编写红外解码函数
  3. 编写主函数

红外初始化函数

         因为使用外部中断 0 来解码红外遥控数据,所以需初始化配置外部中断 0。

void ired_init(void)
{
    IT0=1; //下降沿触发
    EX0=1; //打开中断 0 允许
    EA=1; //打开总中断
    IRED=1; //初始化端口
}

红外解码函数

         初始化外部中断后,中断就已经开启了,当 P32 引脚出现下降沿,就会触发中断,在中断内计算高电平时间,通过高电平时间判断是否进入引导码IRED及数据 0 和 1。

         进入中断函数,表示产生了下降沿,然后判断IRED(P3^2)是否为低电平,如果为低电平则首先判断引导信号,如下所示,引导信号有 9ms 的低电平:

         根据前面 NEC 协议可知,引导信号有 9ms 的低电平和 4.5ms 的高电平,为了计算时间来判断是否有9ms,因此通过一个变量 time_cnt 赋值 1000,然后在 while 循环内判断, time_cnt 每递减一次约 10us,1000 次则为 10ms,10ms>9ms ,所以满足判断等待的时间。

         在解码时,这个时间(9ms)要适当放宽一点范围,因为不同传感器性能会有差异,所以此处以 10ms 的低电平为界限, 如果超过 10ms 则强制退出,防止系统死机,此部分代码如下:

time_cnt=1000;
while((!IRED)&&(time_cnt))//等待引导信号9ms低电平结束,若超过10ms强制退出
{
    delay_10us(1);//延时约10us
    time_cnt--;
    if(time_cnt==0)return;	//1000*10us=10ms,如果10ms之后还是低电平,则return退出	
}

         判断完引导信号的低电平,接着判断高电平,方法一样。当引导信号判断完成后进入地址码、地址反码、控制码及控制反码共 4 个字节的数据判断,也就是数据 0 和 1 的判断,实现方法也是和前面判断引导信号一样,这里是难点,判断是数据 0 还是 1 ,关键在于低电平时间来判断:一个逻辑 1 传输需要 2.25ms(560us 脉冲+1680us 低电平),一个逻辑 0 的传输需要 1.125ms(560us 脉冲+560us 低电平),通过判断1680us或者560us来实现,关键部分代码如下:

time_cnt=20;
while(IRED)//等待数据1或0后面的高电平结束,若超过2ms强制退出
{
    delay_10us(10);//约0.1ms
    ired_high_time++;
    if(ired_high_time>=20)return; //2000us(0.1*20ms=2000us,超出了逻辑1的最大高电平时间1680us ,则强制退出
}
gired_data[i]>>=1; //先读取的为低位,然后是高位
if(ired_high_time>=8) //逻辑1是560us低+1680us高,逻辑0是560us低+560us高,如果高电平时间大于0.8ms,数据则为1,否则为0
    gired_data[i]|=0x80;  //为高电平,所以为1,即1000 0000。因为先传输接收的是低位,所以下一次读取的时候要右移,即gired_data[i]>>=1; 
ired_high_time=0;	//重新清零,等待下一次读取字节数据,用来判断是0还是1

         注意,红外遥控解码数据是从低位开始传送,最后是高位。 最后将读取的 4 个字节数据存储在全局变量数组 gired_data 中,外部可直接使用这四个字节。

         红外解码函数具体代码如下:

#include "ired.h"
u8 gired_data[4];//存储4个字节接收码(地址码+地址反码+控制码+控制反码)

void ired_init(void)
{
 	IT0=1;	//外部中断下降沿触发
	EX0=1;	//打开中断0允许
	EA=1;	//打开总中断
	IRED=1;	//初始化端口
}

void ired() interrupt 0 //外部中断0服务函数
{
 	u8 ired_high_time=0;
	u16 time_cnt=0;
	u8 i=0,j=0;

	if(IRED==0)
	{
	 	time_cnt=1000;
		while((!IRED)&&(time_cnt)) //等待引导信号9ms低电平结束,若超过10ms强制退出
		{
		 	delay_10us(1);
			time_cnt--;		 //time_cntd递减1000次,一次10us,总共10ms
			if(time_cnt==0) return;	  //10ms之后如果还是低电平,则退出
		}
		if(IRED)   //引导信号9ms低电平已过,进入4.5ms高电平
		{
		 	time_cnt=500;
			while(IRED&&time_cnt) //等待引导信号4.5ms高电平结束,若超过5m还是低电平则强制退出
			{
			 	delay_10us(1);
				time_cnt--;
				if(time_cnt==0) return;	 //time_cntd递减500次,一次10us,总共5ms
			}
			for(i=0;i<4;i++) //循环四次,读取四个字节数据(代表地址码、地址反码、控制码及控制反码)
			{
			 	for(j=0;j<8;j++)  //循环八次,读取字节数据的每一位
				{
					time_cnt=600;
					while((IRED==0)&&time_cnt)//等待数据1或0前面的0.56ms结束,若超过6ms强制退出
					{
					 	delay_10us(1);
						time_cnt--;
						if(time_cnt==0)return;
					}
					time_cnt=20;
					while(IRED)//等待数据1或0后面的高电平结束,若超过2ms强制退出
					{
					 	delay_10us(10);//约0.1ms
						ired_high_time++;
						if(ired_high_time>=20)return; //2000us(0.1*20ms=2000us,超出了逻辑1的最大高电平时间1680us ,则强制退出
					}
					gired_data[i]>>=1; //先读取的为低位,然后是高位
					if(ired_high_time>=8) //逻辑1是560us低+1680us高,逻辑0是560us低+560us高,如果高电平时间大于0.8ms,数据则为1,否则为0
						gired_data[i]|=0x80;  //为高电平,所以为1,即1000 0000。因为先传输接收的是低位,所以下一次读取的时候要右移,即gired_data[i]>>=1; 
					ired_high_time=0;	//重新清零,等待下一次读取字节数据,用来判断是0还是1		 	
				}
			}
			if(gired_data[2]!=~gired_data[3]) //校验控制码与反码是否互反,如果不是,则说明接受的数据是错误的,则将gired_data全部清为0,并返回
			{
			 	for(i=0;i<4;i++)
					gired_data[i]=0;
				return;
			}
		}
	}
}

源代码:链接: https://pan.baidu.com/s/1NTxOkoPlCX8FFleA21i1ug?pwd=51yw 提取码: 51yw 

现象

        数码管上显示红外解码遥控器键值。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

红外遥控实验 的相关文章

  • 深入理解JVM虚拟机

    文章目录 深入理解JVM虚拟机JDK1 8新特性 xff1a JVM架构图 xff1a 类装载器知识点 xff1a 类装载器 xff1a 双亲委派机制 xff1a 沙箱安全机制 xff1a Execution Engine执行引擎负责解释命
  • Linux基础指令详解

    目录 前言 Linux基本指令 1 ls指令 1 1 ls 1 2 ls l 1 3 ls a 1 4 ls d 1 5 绝对路径和相对路径 2 pwd指令 3 cd指令 4 touch指令 5 mkdir指令 6 rmdir指令和rm指令
  • aruco识别,python实现

    需要配置anaconda xff0c 用spyder进行python语言编辑 xff0c 实现对aruco码的编写 代码比较垃圾 xff0c 不喜勿喷 配置过程如下 xff1a 视觉系统的运行需要搭建视觉环境 xff0c 包括 xff0c
  • 关于使用HTTP上传文件到hdfs文件系统

    String tenantName 61 System getenv 34 OPENPALETTE NAMESPACE 34 String dataIntegrationServiceName 61 34 dataintegration m
  • 详解 FTP、FTPS 与 SFTP 的原理

    FTP FTPS 与 SFTP 简介 FTP FTP 即 文件传输协议 xff08 英语 xff1a File Transfer Protocol 的缩写 xff09 是一个用于计算机网络上在客户端和服务器之间进行文件传输的应用层协议 完整
  • 用函数调用,把在一个函数的内部改变另一个函数的变量(这个变量相对于第一个函数就是一个外部变量)

    include lt stdio h gt void add int p 指针是整数 xff0c 所以其类型是int整型 这里 p外部变量num的地址 xff0c 即 p 61 num p 43 43 指针变量在单独使用时记得要加括号表示一
  • keil5 C51版本安装及MDK5合并,搭建STM32开发环境(详细教程)

    keil5安装及MDK5合并 资源说明 已将文章中涉及到的所有软件安装包及注册机2032版都放置到百度网盘 xff0c 链接 xff1a 百度云盘链接 提取码 xff1a 0109 1 C51安装 首先在keil官网里下载软件安装包 xff
  • Jmeter性能测试(22)--内存溢出原因及解决方法

    jmeter是一个java开发的开源性能测试工具 xff0c 在性能测试中可支持模拟并发压测 xff0c 但有时候当模拟并发请求较大或者脚本运行时间较长时 xff0c 压力机会出现卡顿甚至报异常 内存溢出 xff0c 这里就介绍下如何解决内
  • Ubuntu16.04的安装教程

    Ubuntu16 04的安装 这里我们会介绍Ubuntu16 04的史诗级保姆教程 开始了 xff0c 车速有点快 xff0c 系好安全带 xff0c 发车了 xff01 1 打开浏览器 xff0c 找到Ubuntu的官网 2 单击 系统桌
  • 电脑触摸板无法使用,I2C HID设备异常处理。

    本人电脑 戴尔 Vostro3400 xff0c win10系统 xff0c 触摸板突然失灵 xff0c 客服让我更新BIOS驱动 xff0c 关闭电源选项的快速启动等等 好了一阵 xff0c 再一重启又失灵 经过无限次百度 xff0c 终
  • 自我简介,对软件工程课程的希望及个人目标

    我是一名桂林理工大学信息科学与工程学院软件工程本科大二年纪的学生 xff0c 热爱学习 xff0c 努力上进 xff0c 对未来充满希望 xff0c 很高兴能学习软件工程这门课程 我对这门课程的希望 xff1a 1 我希望通过学习软件工程这
  • 用HTML、CSS写一个酷炫的动态搜索框

    用HTML CSS写一个酷炫的动态搜索框 可伸展的动态搜索框 xff01 复制粘贴即可用 xff01 HTML部分 xff1a span class token doctype lt DOCTYPE html gt span span cl
  • 使用 curl/git 命令时出现 Failed to connect to XXX port 443: 拒绝连接

    文章目录 原因与过程解决办法 原因与过程 今天在linux下安装docker compose出现Failed connect to github com 443 拒绝连接 网上查了下说是DNS被污染 xff0c 改下host文件 解决办法
  • 【C++】30h速成C++从入门到精通(STL介绍、string类)

    STL简介 什么是STL STL standard template libaray 标准模板库 xff1a 是C 43 43 标准库的重要组成部分 xff0c 不仅是一个可复用的组件库 xff0c 而且是一个包罗数据结构与算法的软件框架
  • redis分布式锁

    1 Redis分布式锁最简单的实现 想要实现分布式锁 xff0c 必须要求 Redis 有 互斥 的能力 xff0c 我们可以使用 SETNX 命令 xff0c 这个命令表示SET if Not Exists xff0c 即如果 key 不
  • 网络边界安全

    防火墙 防火墙的分类 按物理特性划分 软件防火墙硬件防火墙 按性能划分 百兆级防火墙千兆级防火墙 按防火墙结构划分 单一主机防火墙路由集成防火墙分布式防火墙 按防火墙技术划分 包过滤防火墙应用代理防火墙状态检测防火墙 防火墙的功能 访问控制
  • 控制台报错--Module not found: Error: Can‘t resolve ‘core-js/fn/promise‘

    报错信息 xff1a 解决方法 xff1a 原因是vscode会自动导入 import resolve from 39 core js fn promise 39 这一行代码
  • 如何测量无人机电机和螺旋桨的效率?

    为什么要测试电机和螺旋桨 xff1f 首先要确认我们和最终用户的需求是什么 xff1f 因为它将帮助我们发现哪些内容需要优化 xff1a 是否希望增加无人机不间断航拍的续航时长 xff1f 是否希望增加无人机的净载荷 xff1f 是否需要加
  • Jmeter性能测试(23)--分布式测试

    关于jmeter的介绍和元件作用 xff0c 之前的博客介绍过 xff0c 很多其他同行的博客也够详细的 xff0c 这里不做介绍 xff0c 对jmeter不甚了解的可以参考之前的博客 xff1a jmeter xff1a 菜鸟入门到进阶
  • 无人机的电调及其工作原理是什么?

    电子速度控制器 ESC 是电力推进系统的重要硬件组成部分 它就像系统的大脑一样 xff0c 根据从油门控制器接收到的数据信号告诉电机以多快的转速运行 对于无人机和遥控车辆等小型场景应用 xff0c 该控制器的名称为 ESC xff0c 而对

随机推荐

  • 三自由度无人机飞手培训、PID调试、飞行教学、飞控算法验证、故障仿真平台

    无人机在研制过程中需要不断地进行飞行测试 xff0c 而测试的过程不是万无一失的 xff0c 飞行过程中发生任何错误都有可能会导致无人机的损毁或破坏 xff0c 更严重地甚至会造成外界伤害 基于此我们推出了无人机的三旋转自由度 3 DOF
  • shell脚本的执行

    标题 shell脚本的执行 概述 当shell脚本运行时 xff0c 首先会查找系统环境变量ENV xff0c 环境变量指定了环境文件 xff08 加载顺序 etc profile bash profile bashrc etc bashr
  • prometheus(普罗米修斯)

    prometheus 什么是普罗米修斯 xff1f Prometheus是一个开源系统监控和警报工具包 xff0c 最初是在 SoundCloud 上构建的 自2012年成立以来 xff0c 许多公司和组织都采用了Prometheus xf
  • 装机环境配置笔记

    装机过程中需要修改系统中的环境参数以及配置 xff01 xff01 xff01 http t csdn cn Ste4n xff08 记录在这里 xff09 运行环境配置文档 xff08 参考使用非必须 xff09 Notion The a
  • SDN系统方法 | 8. 网络虚拟化

    第8章 网络虚拟化 如第2章所述 xff0c 网络虚拟化和本书介绍的其他部分有所不同 xff0c 这是SDN第一个成功的商业用例 网络虚拟化可以在服务器上实现 xff0c 通常不需要物理网络中的交换机提供任何帮助 网络虚拟化可以实现为现有网
  • 算法设计与分析

    两个例子 调度问题与投资问题 例1 xff1a 调度问题 问题 有 n 项任务 xff0c 每项任务加工时间已知 从 0时刻开始陆续安排到一台机器上加工 每个任务的完成时间是从 0 时刻到任务加工截止的时间 求 总完成时间 xff08 所有
  • 偏航角、俯仰角、横滚角的理解

    最近研究IMU陀螺仪 xff0c 经过一早上的调试 xff0c 最后发现根本看不懂xyz三个角度的度数是怎么来的 xff0c 看了一些教程 xff0c 也觉得不够直观 xff0c 去了b站找了个视频 xff0c 发现讲解的还不错 xff0c
  • ubuntu20.04版本 安装ros1与px4、mavros、QGroundControl

    基于个人安装时的操作以及所浏览的链接 xff0c 仅供参考 文章目录 前言一 pandas是什么 xff1f 二 使用步骤 1 引入库2 读入数据总结 前言 使用ubuntu下载ros px4似乎是一件十分繁琐以及困难的事情 xff0c 但
  • ros中无人机基于话题<geographic_msgs/GeoPoseStamped.h>的指点飞行控制

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 前言一 话题认识二 完整代码总结 前言 本篇文章是作者在学习ros时根据自己的认识所写的代码 xff0c 主要是基于话题 lt
  • Jmeter性能测试(24)--dubbo接口测试

    一 Dubbo简介 dubbo是一个分布式服务框架 xff0c 致力于提供高性能和透明化的RPC远程服务调用方案 xff0c 以及SOA服务治理方案 其核心部分包含如下几点 xff1a 1 远程通讯 xff1a 提供对多种基于长连接的NIO
  • 自定义mavlink及收发测试(px4固件V1.11.0,QGC源码4.0)

    一 实现收 1 先定义uORB消息 a01 GPS msg uint64 timestamp time since system start microseconds uint64 lat Latitude uint64 lon Longi
  • 自定义mavlink及收发测试2(px4固件V1.11.0,QGC源码V4.0)

    一 1 下载安装一个mavlink文件或者在原文件上修改 安装步骤 xff08 包含mavlink generator xff09 可参照文章 PX4自定义Mavlink消息 xff08 一 xff09 px4发送 Sense97的博客 C
  • Ubuntu20.04 | 更新软件源 sudo apt-get update 出现错误

    之前使用了清华的官方源 清华大学开源软件镜像站 Tsinghua Open Source Mirror 错误提示 xff1a 忽略 1 https mirrors tuna tsinghua edu cn ubuntu focal InRe
  • PCB封装库的制作

    以下几个元件制作为例 xff1a 元件SMA封装 步骤 xff1a 1 创建PCB库文件 xff1a 单击 File 菜单 xff0c 选择 New 选项中的 Library 选项 xff0c 再选择 PCB Library xff0c 进
  • PCB板自动布线

    自动布线 步骤 xff1a 1 整体删除同层的走线 xff1a 打开PCB文件 xff0c 在层的选项卡中选择顶层 Top Layer xff0c 在 Edit 菜单下选择 Select 选项 xff0c 选择 All on Layer 选
  • 独立按键实验

    按键简介 按键是一种电子开关 xff0c 使用时 xff0c 按下按钮 xff0c 则开关接通 xff0c 松开手时 开关断开 开发板上使用的按键及内部简易图如下图所示 xff1a 按键管脚两端距离长的表示默认是导通状态 xff08 1 2
  • IO 扩展(串转并)-74HC595-16*16LED点阵实验

    51 单片机的IO 口非常有限 xff0c 有时候若想要连接更多外围设备 xff0c 需要通过 IO 扩展来实现 本文介绍一种 IO 口扩展方式 串转并 xff0c 使用的芯片是 74HC595 若有4个 74HC595 芯片 xff0c
  • LED 点阵实验~点亮一个点、数字、汉字、图

    LED 点阵简介 LED 点阵是由发光二极管排列组成的显示器件 xff0c 如下所示为8 8LED 点阵 xff1a 以 16 16LED 点阵为例 xff0c 其内部结构图如下所示 xff1a 16 16 点阵共由 256 个发光二极管组
  • 定时器中断

    定时器简介 介绍定时器之前 xff0c 先说明几个CPU 时序的有关知识 振荡周期 xff1a 为单片机提供定时信号的振荡源的周期状态周期 xff1a 1 个状态周期 61 2 个振荡周期机器周期 xff1a 1 个机器周期 61 6 个状
  • 红外遥控实验

    红外线简介 人眼所能看到的可见光 xff0c 按波长从长到短排列 xff0c 依次为红 xff08 660nm xff09 橙 xff08 610nm xff09 黄 xff08 585nm xff09 绿 xff08 555nm xff0