IRLINK(红外遥控器)

news2024/11/15 10:24:37

工具

1.Proteus 8 仿真器

2.keil 5 编辑器

原理图

讲解

简介

红外遥控:是利用红外线进行通信的设备,由红外LED调制后的信号发出,由专用的红外接头进行解调;

通信方式:单工、异步;

红外LED波长:940nm;

通信协议标准:NEC标准;

通信双方需要完成的内容:调制与解调(防止干扰);

        对于无线通信来说,通信双方中间空气中可能夹杂着许多其他的红外波(例如太阳的辐射),这样就对有用的信号产生了一定的干扰;为了抗除这种干扰,我们对发送的信号在发送前进行调制,在接收后进行解调,这样就可以很大程度上防止其他的干扰。

        调制的原理就是将发送的信号电平,搭载在频率为38Khz的方波(称为载波)上,经过调制的信号经过发送设备进行发送;接收设备接收到信号后,先将38Khz信号进行解调,再按照协议进行读取;

NEC编码

发送

正常结构(单次信号

整段信号由起始码,地址码,地址反码,命令码,命令反码组成

起始码:高电平---9ms---低电平---4.5ms

数据0:高电平---560us---低电平---560us

数据1:高电平---560us---低电平---1680us

连发结构(长按某个键发送信号

除正常信号外,需每隔110ms发送一段重复码(命令码只在刚开始发一次)

重复码:高电平---9ms---低电平---2.25ms

注意:发送结束后必须要有结束码(构造下降沿供接收检测)

接收

注意:接收端的波形正好是相反的(根据两个下降沿之间的时间差得到数据0或数据1)

代码

发送端

#include <reg52.h>
#include "Delay.h"	//延时函数头文件
#include "KEY.h"
#include "LCD1602.h"

sbit red_IO = P1^0;
int keynum=0;
void red_start(void);
void send_0(void);
void send_1(void);
void send_bit(int num);
void command_code(int num);
void reverse_code(int num);
void end_cod(void);
/**
  * @brief 中断初始化
  * @param  触发方式(下降沿)
  * @retval 
  */
void Int0Init()    
{
    //设置 INT0
    IT0=1;//触发方式(下降沿)
    EX0=0;//INT0 的中断允许。 0关闭  //P3.2被矩阵键盘占用 键盘按下抬起时EX0=1; P3.2矩阵扫描时会存在下降沿 此时中断产生   
    EA=1;//打开总中断
}

/**
  * @brief  外部中断 0 的中断函数
  * @param  
  * @retval 
  */
void Int0() interrupt 0 
{
    //执行所需的功能
	  //引导码
		red_start();
		//命令码
		command_code(7);
		//数据码
		send_bit(keynum);
		//结束码
		end_cod();
		EX0=0; //中断完成后 恢复允许位关闭状态
}

/**
  * @brief  引导码
  * @retval 
  */

void red_start(void)
{
	red_IO=1; //拉高 通过与门 方波出入红外
	delay_ms(9);
	red_IO=0;
	delay_ms(4);
}

/**
  * @brief 命令码
  * @retval 
  */
void command_code(int num)
{
	unsigned int i=0;
	for(i;i<8;i++)
	{
		if(num>>i&0x01)
		{
			send_1();
		}else{
			send_0();
		}
	}
	reverse_code(num);
}

/**
  * @brief 反码
  * @retval 
  */

void reverse_code(int num)
{
	unsigned int i=0;
	for(i;i<8;i++)
	{
		if(~num>>i&0x01)
		{
			send_1();
		}else{
			send_0();
		}
	}
}

/**
  * @brief  结束码
  * @param  使电平跳跃一次 否则接收时最后一帧数据会丢失
  * @retval 
  */

void end_cod(void)
{
	red_IO=1;
	delay_10us(56);
	red_IO=0;
}

//数据0
void send_0(void)
{
	red_IO=1;
	delay_10us(56);
	red_IO=0;
	delay_10us(56);
}
//数据1
void send_1(void)
{
	red_IO=1;
	delay_10us(56);
	red_IO=0;
	delay_10us(168);
}
//发送一字节
void send_bit(int num)
{
	unsigned int i=0;
	for(i;i<8;i++)
	{
		if(num>>i&0x01)
		{
			send_1();
		}else{
			send_0();
		}
	}
	reverse_code(num);
}

main(void) 
{ 
	Int0Init();
	LCD_Init();
	red_IO=0; //初始化时给低电平 保证与门不通
	LCD_ShowNum(1,1,keynum,4);
	while(1)
	{
		keynum=KEY();
		if(keynum>=0)
		{
			LCD_ShowNum(1,1,keynum,4);
			//进入中断
			EX0=1;
		}
	}
}

接收端

#include <reg52.h>  
#include "Delay.h"
#include "intrins.h"
#include "LCD1602.h"
#include "DS18B20.h"

sbit INT0_IO=P3^2;
unsigned char INT_flag=0;  //中断
unsigned char getdata_flag=0;  //数据接受完成标志
unsigned int time=0,pstate=0;	//time用来表示 两个下降沿之间的时间差 us  pstate 数据指针
unsigned char IRdata[4]; //数据缓存
unsigned int get_Time(void); 
unsigned int get_address(void);
unsigned int get_data(void);
/**
  * @brief  定时器初始化 
  * @param  用来计算时间差
  * @retval 
  */
void timer0Init() 
{
		TMOD=0x01;//定时器0工作方式1,
  	TH0=0;
  	TL0=0;
  	ET0=0;//禁止中断
  	TR0=0;
}
/**
  * @brief  开启定时器
  * @retval 
  */
void start_time(void)
{
		//清空定时器初始值
		TH0=0;
		TL0=0;
		//开启定时器
		TR0=1;
}
/**
  * @brief  获取定时器计数值
  * @retval 
  */
unsigned int get_Time(void)
{
		//关闭定时器
		TR0=0;
		return TH0<<8|TL0;
}
/**
  * @brief  外部中断0初始化
  * @param   捕捉下降沿
  * @retval 
  */
void Int0Init()    
{
    //设置 INT0
    IT0=1;//触发方式(下降沿)
		IE0=0;//清空标志位
    EX0=1;//INT0 的中断允许。 0关闭    
    EA=1;//打开总中断
}
/**
  * @brief  中断响应函数
  * @retval 
  */
void Int0() interrupt 0 
{
		//中断进入
		if(INT_flag==0) //第一次下降沿触发
		{
			//开始定时
			start_time();
			getdata_flag=0;
			INT_flag=1;
			return;
		}
		if(INT_flag==1) //第二次下降沿触发
		{
			//结束定时  获取记录的时间值
			time=get_Time();
			//符合 引导码的两次下降沿时间差 
			if(13000-500<time&&time<13000+500)
			{
				start_time();
				INT_flag=2;
				return;
			}
		}
		//接受数据
		if(INT_flag==2)
		{
			time=get_Time();
			//符合数据 0 两次下降沿时间差
			if(1120-500<time&&time<1120+500)
			{
				IRdata[pstate/8]&=~(0x01<<(pstate%8));	//数据对应位清0
				pstate++;
				if(pstate==32)
				{
					//数据接受完成
					getdata_flag=1;
					pstate=0;
					INT_flag=0;
					return;
				}
				start_time();
				return;
			}
			//符合数据 1 两次下降沿时间差
			if(2240-500<time&&time<2240+500)
			{
				IRdata[pstate/8]|=0x01<<pstate%8;
				pstate++;
				if(pstate==32)
				{
					//数据接受完成
					getdata_flag=1;
					pstate=0;
					INT_flag=0;
					return;
				}
				start_time();
				return;
			}
		}
} 
/**
  * @brief  获取命令地址码
  * @param  反馈地址
  * @param 
  * @param 
  * @retval 
  */
unsigned int get_address(void)
{
	if(IRdata[0]==~IRdata[1])
	{
		return IRdata[0];
	}
	
}
/**
  * @brief  获取数据
  * @param 	反馈数据 
  * @param 
  * @param 
  * @retval 
  */
unsigned int get_data(void)
{
	if(IRdata[2]==~IRdata[3])
	{
		return IRdata[2];
	}
}
	

void main(void)
{
	//初始化定时器
	timer0Init(); 
	//中断初始化
	Int0Init();
  //初始化液晶
	LCD_Init();
	LCD_ShowString(1,1,"Old_man");
	while(1)
	{
		if(getdata_flag)
		{
			LCD_ShowNum(2,1,get_address(),2);
			LCD_ShowNum(2,9,get_data(),2);
			getdata_flag=0;
		}
	}
}

实现

🚀本欧也处于学习阶段,所学所识将以笔记发布。

笔记会根据相关知识的接触而随时更新! 

 如果文章对你有帮助,请留下你宝贵的点赞吧👍

V:Werluo  本欧也很喜欢交朋友的哦! 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1503042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaEE进阶】 @Transactional详解

文章目录 &#x1f343;前言&#x1f332;rollbackFor&#xff08;异常回滚属性&#xff09;&#x1f384;事务隔离级别&#x1f6a9;MySQL事务隔离级别&#x1f6a9;Spring事务隔离级别 &#x1f38b;Spring事务传播机制&#x1f6a9;什么是事务传播机制&#x1f6a9;事务有哪…

一大波你可能不知道的 Linux 网络工具

如果要在你的系统上监控网络&#xff0c;那么使用命令行工具是非常实用的&#xff0c;并且对于 Linux 用户来说&#xff0c;有着许许多多现成的工具可以使用&#xff0c;如&#xff1a;nethogs, ntopng, nload, iftop, iptraf, bmon, slurm, tcptrack, cbm, netwatch, collectl…

SMT32 TIM1 PWM(发送固定脉冲数)步进电机梯形图加速

&#xff08;因为电机的启停惯性和步进电机越慢扭力越大的原因&#xff09;&#xff1b;所以步进电机使用梯形加速&#xff0c;可以实现更小的丢步 思路&#xff1a;在PWM中断中做计数&#xff0c;前20个脉冲和后20个脉冲频率设置一样低&#xff0c;中间的脉冲频率设置快一点

【Docker】了解Docker Desktop桌面应用程序,TA是如何管理和运行Docker容器(3)

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

java-新手笔记(线程篇)

线程 线程是操作系统能进行算法调度的最小单位&#xff0c;它被包含在进程中&#xff0c;是进程中的实际操作单位。程序员可以通过线程进行多处理器编程&#xff0c;使用多线程对运算密集型任务提速. 线程的生命周期与状态&#xff1a;线程具有新建&#xff08;New&#xff0…

“轻松入门Electron:一步步构建梦想中的桌面软件

在数字化的浪潮中&#xff0c;桌面应用依旧占据着其独特而重要的位置&#xff0c;不论是在企业解决方案、专业工具软件还是个性化应用领域中都是如此。随着技术的演进&#xff0c;创建这些应用的过程已经变得更为简单和可行&#xff0c;尤其是随着Electron等框架的出现。Electr…

Android14之禁止vbmeta.img签名校验(一百九十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

动态规划(带你了解 原理 实践)

目录 引言 一、动态规划的基本概念 二、动态规划的应用 1. 背包问题 2. 最短路径问题 3. 0-1背包问题的变种 4. 字符串匹配与编辑距离 5. 金融投资组合优化 6. 生产调度问题 7. 项目管理中的资源分配 三、动态规划算法的优缺点 优点 1 效率高 2 通用性强 缺点&a…

Java实现归并排序算法

Java实现归并排序算法 以下是Java中的归并排序算法实现示例&#xff1a; public class MergeSort {// 归并排序入口函数public static void sort(int[] array) {if (array null || array.length < 1)return;mergeSort(array, 0, array.length - 1);}// 归并排序递归函数pr…

配置oh-my-posh

在windows上的powershell上配置oh-my-posh&#xff0c;使其更像在linux用oh-my-zsh。 首先打开powershell&#xff0c;输入&#xff1a; winget install JanDeDobbeleer.OhMyPosh -s winget安装on-my-posh.exe和oh-my-posh上最新的主题。 之后重启powershell。 打开配置文件…

华为ce12800交换机m-lag(V-STP模式)配置举例

配置## 标题思路 采用如下的思路配置M-LAG双归接入IP网络&#xff1a; 1.在Switch上配置上行接口绑定在一个Eth-Trunk中。 2.分别在SwitchA和SwitchB上配置V-STP、DFS Group、peer-link和M-LAG接口。 3.分别在SwitchA和SwitchB上配置LACP M-LAG的系统优先级、系统ID。 4.分别在…

【粉丝福利第四期】:《低代码平台开发实践:基于React》(文末送书)

文章目录 前言一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望《低代码平台开发实践&#xff1a;基于React》五、粉丝福利 前言 随着数字化转型的深入&#xff0c;企业对应用开发的效率和灵活性要求越来越高…

scrapy的基本使用介绍

创建项目 ### 1. 创建虚拟环境 conda create -n spiderScrapy python3.9 ### 2. 安装scrapy pip install scrapy2.8.0 -i https://pypi.tuna.tsinghua.edu.cn/simple### 3. 生成一个框架 scrapy startproject my_spider### 4. 生成项目 scrapy genspider baidu https://www.b…

高电平复位电路工作原理详解

单片机复位电路的作用是&#xff1a;使单片机恢复到起始状态&#xff0c;让单片机的程序从头开始执行&#xff0c;运行时钟处于稳定状态、各种寄存器、端口处于初始化状态等等。目的是让单片机能够稳定、正确的从头开始执行程序。一共分为&#xff1a;高电平复位&#xff0c;低…

考研复习c语言初阶(1)

本人准备考研&#xff0c;现在开始每天更新408的内容&#xff0c;目标这个月结束C语言和数据结构&#xff0c;每天更新~ 一.再次认识c语言 C语言是一门通用计算机编程语言&#xff0c;广泛应用于底层开发。C语言的设计目标是提供一种能以简易 的方式编译、处理低级存储器、产生…

2024AI在医疗领域中的辅助趋势与现有进展

2024 年 AI 辅助研发趋势随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&am…

Halcon深度学习,异常值缺陷检测

前言 halcon深度学习分为常见的4大类。分类&#xff0c;语义分割&#xff0c;异常值检测&#xff0c;深度OCR。本篇主要针对halcon的异常值检测&#xff0c;如何训练和部署&#xff0c;并通过图像预处理的方式实现对异常值缺陷检测的精准实现。 异常值检测不同于语义分割的项目…

股票价格预测项目

项目介绍 背景 股票价格预测一直是金融领域的热点问题。准确的预测可以帮助投资者作出更明智的决策。本项目旨在使用机器学习技术&#xff0c;特别是长短期记忆网络&#xff08;LSTM&#xff09;&#xff0c;来预测股票价格。 目标 开发一个基于LSTM的股票价格预测模型。使…

FreeRtos Queue(五)

本篇主要分析在中断中向队列里发消息xQueueGenericSendFromISR和在中断里从队列中读取消息xQueueReceiveFromISR。 前言: xQueueGenericSendFromISR 和 xQueueReceiveFromISR都是在中断里调用的而不是任务里调用的&#xff0c;所以队列满了或者是队列为空的时候自然就没有把当…

51 软中断的实现

前言 呵呵 中断机制 也是内核中很常见的机制了 中断机制是现代计算机系统中的基本机制之一&#xff0c;它在系统中起着通信网络的作用&#xff0c;以协调系统对各种外部事件的响应和处理&#xff0c;中断是实现多道程序设计的必要条件&#xff0c;中断是CPU 对系统发生的某个…