定时器+外部中断实现NEC红外线协议解码

news2024/11/15 15:53:31

一、前言

1.1 功能介绍

随着科技的进步和人们生活水平的提高,红外遥控器已经成为了日常生活中不可或缺的电子设备之一,广泛应用于电视、空调、音响等多种家电产品中。 传统的红外遥控器通常只能实现预设的有限功能,无法满足用户对设备更加智能化、个性化的控制需求。

STC90C51作为一款功能强大的8位微控制器,具备高性能、低功耗和丰富的I/O端口资源,非常适合用于实现红外遥控信号的解码和控制。本项目利用STC90C51微控制器,结合定时器和外部中断机制,实现NEC红外线协议的解码,从而实现对红外遥控器的控制功能。

NEC红外线协议是一种常见的红外遥控通信协议,具有传输速度快、编码简单、可靠性高等特点。通过解码NEC红外线协议,可以获取遥控器发送的按键信息,进而实现对设备的远程控制。在本项目中,我们将利用STC90C51的定时器功能,设置合适的定时参数,以检测红外信号的脉冲宽度和间隔。同时,利用外部中断机制,实时监测红外接收管的状态变化,捕捉红外信号的起始和结束时刻。

通过解码NEC红外线协议,我们可以获取遥控器发送的按键编码,并将其转换为对应的控制指令。在本项目中,我们将以开关控制为例,实现对目标设备的远程控制。具体而言,当遥控器发送“开”或“关”的按键编码时,STC90C51将解码该编码,并发送相应的控制指令给目标设备,以实现设备的开关控制。

本项目的开发背景不仅体现了现代家居和电子设备对远程控制技术的需求,也展示了STC90C51微控制器在嵌入式系统设计和开发中的强大功能。通过实现NEC红外线协议的解码和控制,本项目将为用户带来更加便捷、智能的远程控制体验,推动智能家居和物联网技术的发展。

image-20240612131713957

image-20240612131727095

image-20240612131746139

image-20240612131757396

1.2 NEC协议介绍

NEC协议是一种红外线通信协议,广泛应用于家电遥控器和其他红外线设备之间的通信。该协议具有简单、易于实现和广泛兼容的特点,使得不同品牌和型号的红外设备能够互相通信和控制。

NEC协议的工作原理基于38kHz的红外线载波频率,通过发送特定格式的数据包来传输信息。每个数据包由连续的脉冲和间隔组成,其中脉冲表示逻辑1,间隔表示逻辑0。数据包的结构包括同步码(Sync Header)、地址码、地址码的反码、命令码以及命令码的反码。

同步码是数据包开始的标识,通常是一个持续约9ms的高电平脉冲(Mark),用于同步接收器和发送器之间的通信。地址码和命令码是每个按键特定的标识,用于识别按下的是哪个按键。地址码和地址码的反码用于验证遥控器发送的数据是否正确,而命令码和命令码的反码则用于执行相应的操作。

在NEC协议中,数据以二进制格式进行传输,确保了信息的准确性和高效性。此外,NEC协议还定义了一个重复码,当用户长按遥控器上的某个按键时,遥控器会发送该按键的重复码,以避免连续发送相同的命令。

NEC协议是一种基于红外线通信的协议,通过发送特定格式的数据包来实现不同设备之间的通信和控制。它具有简单、易于实现和广泛兼容的特点,被广泛应用于家电遥控器等红外设备中。

二、代码实现

2.1 main.c

#include <reg51.h>
#include "delay.h"
#include "key.h"
#include "type.h"
#include "led.h"
#include "uart.h"
#include "timer.h"
#include "exti.h"
#include "infrared.h"
int main()
{
    UART_Init();        //初始化串口波特率为4800
    Infrared_Init();    //初始化红外功能
    while(1)
    {
        if(Infrared_RX_Flag)          //接收到红外数据
        {
            Infrared_RX_Flag=0;     //清楚标志
            printf("user1:%d,user2:%d\r\n",(int)Infrared_RX_Buff[0],(int)((u8)(~Infrared_RX_Buff[1])));
			printf("key1:%d,key2:%d\r\n",(int)Infrared_RX_Buff[2],(int)((u8)(~Infrared_RX_Buff[3])));
        } 
    }
}

2.2 INFRARED.c

#include "Infrared.h"
u8 Infrared_RX_Flag=0; //红外接收标志,收到一帧正确数据后置1
u8 Infrared_RX_Buff[4];//红外代码接收缓冲区

/*
函数功能: 开始红外线解码之前的相关初始化
实验板的晶振频率是12MHZ
51单片机标准架构下一个机器周期是12个时钟周期,如果晶振频率是12MHZ,那一个机器周期的时间就是12/12微秒。
也就是说定时器的计数器+1的时间就是12/12=1us。
*/
void Infrared_Init(void)
{	
	Infrared_GPIO=1;//红外接收引脚默认保持高电平输出
	TMOD&=0xF0; //清除配置  
	TMOD|=0x01; //配置定时器0,工作在16位计数模式
	TR0=0;      //停止定时器0计数
	ET0=0; 	    //禁止定时器0中断
	IT0=1;      //开启外部中断0,下降沿触发
	EX0=1;      //允许外部中断0中断
}

/*
函数功能: 检测高电平持续的时间
*/
u16 Infrared_GetTimeH(void)
{
	TH0=0; //定时器0重装值为0
	TL0=0; //定时器0重装值为0
	TR0=1; //启动定时器0开始计数
	while(Infrared_GPIO)//等待高电平结束
	{
		if(TH0>0x40)//防止超时   
		{
			break;
		}
	}
	TR0=0;//停止定时器0计数
	return TH0<<8|TL0;//T0计数值合成为16位整数返回
}

/*
检测低电平持续的时间
*/
u16 Infrared_GetTimeL(void)
{
	TH0=0;//定时器0的高8位重装值
	TL0=0;//定时器0的低8位重装值  
	TR0=1;//开启定时器0
	while(Infrared_GPIO==0)//等待低电平结束
	{
		if(TH0>0x40)//防止超时   
		{
			break;
		}
	}
	TR0=0;//停止定时器0计数
	return TH0<<8|TL0;//T0计数值合成为16位整数返回
}

/*
外部中断0中断服务函数
*/
void EXTI0_IRQHandler() interrupt 0
{
	u8 i, j;
	u16 time;
	u8 byte;
	time=Infrared_GetTimeL();   //获取出现低电平的时间
	if((time<7800)||(time>9300))//判断低电平时间是否符合9ms范围
	{                           //超过此范围则说明为误码,直接退出
		IE0=0;                  //清除外部中断0中断标志
		return;	
	}
	time=Infrared_GetTimeH();   //获取出现高电平的时间
	if((time<3500)||(time>4700))//高电平是否符合4.5ms范围
	{                           //超过此范围则说明为误码,直接退出
		IE0=0; 				    //清除外部中断0中断标志
		return;
	}
	//接收32位数据位
	for(i=0;i<4;i++)
	{
		for(j=0;j<8;j++)
		{
			time=Infrared_GetTimeL();   //获取低电平持续时间,标准的间隔时间为560us范围		    				
			if((time<300)||(time>700))  //判断范围是否合理
			{
				IE0=0;//清除外部中断0中断标志
				return;
			}
            //1和0是靠高电平持续的长短来区分的
			time=Infrared_GetTimeH();  //获取高电平持续时间
			if(time>300&&time<700)    //0的标准时间为560us
			{
				byte>>=1;
			}
            else if(time>1400&&time<1800) //1的标准时间是1680us
			{
				byte>>=1;
				byte|=0x80;
			}
			else //不在上面的判断范围内说明是错误码,直接退出
			{
				IE0=0;//清除外部中断0中标
				return;
			}
		}
		Infrared_RX_Buff[i]=byte;//接收完一个字节后保存到缓冲区
	}
	Infrared_RX_Flag=1;//接收完毕后设置标志
	IE0=0;//退出前清除外部中断0中断标志
}

2.3 INFRARED.h

#ifndef _INFRAREAD_H
#define _INFRAREAD_H
#include <reg51.h>
#include "type.h"
sbit Infrared_GPIO=P3^2;//红外接收引脚--外部中断0
void Infrared_Init();//红外线接收初始化
u16 Time_H();//检测高电平
u16 Time_L();//检测低电平
extern u8 Infrared_RX_Flag; //红外接收标志,收到一帧正确数据后置1
extern u8 Infrared_RX_Buff[4];   //红外代码接收缓冲区
#endif

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

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

相关文章

Mac 下华为鸿蒙 :DevEco Studio 开发工具下载

1.登录&#xff1a;华为开发者中心--开发--下载工具DevEco Studio 2.下载完成后 &#xff0c;安装&#xff0c;并创建一个新项目。 3.Tools --点击SDK Manager 下载SDK: 如果报&#xff1a;淘宝镜像源错误&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_H…

Threejs——辅助视图的旋转轴

官网的代码&#xff1a;link 实现这个效果 import {CylinderGeometry,CanvasTexture,Color,Euler,Mesh,MeshBasicMaterial,Object3D,OrthographicCamera,Quaternion,Raycaster,Sprite,SpriteMaterial,SRGBColorSpace,Vector2,Vector3,Vector4 } from three;class ViewHelper …

FP5207+音频功率放大器的组合解决方案-适用于便携式音频播放器、无线耳机、智能音箱和车载音响系统等高质量音频输出需求的产品,以提高电池供电的效率和输出功率

随着消费者对智能家居的需求增长&#xff0c;智能音响市场成为重要增长点。同时&#xff0c;音响技术也在不断发展&#xff0c;音响及扬声器的功能和性能不断提升。 蓝牙音箱&#xff0c;这类音箱供电是以锂电池为主&#xff0c;一般选用内置升压的音频功放芯片&#xff0c;音响…

Java聚合快递系统对接云洋系统快递小程序系统源码

&#x1f680; "聚合快递系统"无缝对接云洋系统&#xff0c;快递小程序新体验&#xff01;&#x1f4e6; &#x1f69a; 开篇&#xff1a;快递管理新纪元&#xff0c;一键接入云洋系统&#xff01; 你是否还在为繁琐的快递管理而头疼&#xff1f;多个快递公司账号切…

构建一个具有深色模式的简单React Web应用

在当今的Web开发世界里,创建一个既美观又功能丰富的用户界面是至关重要的。在本文中,我们将探讨如何使用React构建一个简单但功能强大的Web应用,它包含导航栏、内容展示区域和深色模式切换功能。 项目概述 我们的目标是创建一个具有以下特性的Web应用: 左侧导航栏,包含四个链…

JavaScript(12)——内置对象

JavaScript内部提供的对象&#xff0c;包含各种属性和方法给开发者调用。 Math Math对象是JavaScript提供的一个“数学”对象 包含的方法有&#xff1a; random:生成0-1之间的随机数 ceil&#xff1a;向上取整 floor&#xff1a;向下取整 max&#xff1a;找最大数 min&#…

Leetcode 721.账户合并(hash+dfs)☆

思路&#xff1a; 最核心的地方在于如何合并&#xff1f;这里是通过具有相同的email进行账户的合并&#xff0c;这个相同的email类似于图中的共同节点将两个账户连接起来&#xff0c;所以将原来 账户名 -> 邮件1 邮件2.。。变成hash 邮件1 ->账户id1&#xff0c;账户id2…

2024年jupyter notebook如何复制单元格cell输出的图片

背景 之前使用jupyter notebook复制图片一直是正常&#xff0c;右键就行&#xff0c;可以找到复制图片或者另存为的选项。 但是最近重新安装了anaconda&#xff0c;发现jupyter notebook升级了&#xff0c;和原来的界面不一样了。 如果有一个图片&#xff0c;我们右键&#x…

Concat() Function-SQL-字符串拼接函数

Concat() Function-SQL 在SQL中&#xff0c;CONCAT() 函数用于将两个或多个字符串连接在一起。 不同数据库管理系统可能有些许差异&#xff0c;但基本用法和语法通常是相似的。 语法 CONCAT(string1, string2, ...)string1, string2, …: 这些是需要连接的字符串参数。可以…

快速排序【示例】

冒泡排序可以说是我们学习的第一个真正的排序算法&#xff0c;并且解决了桶排序浪费 空间的问题&#xff0c;但在算法的执行效率上却牺牲了很多&#xff0c;它的时间复杂度达到了 O(N^2)。假如我 们的计算机每秒钟可以运行 10 亿次&#xff0c;那么对 1 亿个数进行排序&#xf…

弹性布局 flex layout HTML CSS

文章目录 效果图参考文档代码 效果图 其实弹性布局的好处是&#xff1a;当网页大小变化&#xff08;如窗口resize&#xff09;时&#xff0c;处于弹性容器(flex container)中的弹性元素(flex item) 之间的距离也会变化。 需要特别注意的是&#xff1a; 弹性布局的主要CSS如下。…

缺省路由学习笔记

1.缺省路由 缺省路由是一种特殊的路由&#xff0c;当报文没有在路由表中找到匹配的具体路由表项时才使用的路由。如果报文的目的地址不能与路由表的任何目的地址相匹配&#xff0c;那么该报文将选取缺省路由进行转发。缺省路由是“替补”。 缺省路由在路由表中的形式为0.0.0.…

汽车长翅膀:GPU 是如何加速深度学习模型的训练和推理过程的?

编者按&#xff1a;深度学习的飞速发展离不开硬件技术的突破&#xff0c;而 GPU 的崛起无疑是其中最大的推力之一。但你是否曾好奇过&#xff0c;为何一行简单的“.to(‘cuda’)”代码就能让模型的训练速度突飞猛进&#xff1f;本文正是为解答这个疑问而作。 作者以独特的视角&…

【ffmpeg命令入门】实现画中画

文章目录 前言画中画是什么画中画的外观描述效果展示为什么要用画中画应用场景示例 使用FFmpeg添加画中画示例命令参数解释调整嵌入视频的位置调整嵌入视频的大小处理音频 总结 前言 FFmpeg 是一款强大的多媒体处理工具&#xff0c;广泛用于音视频的录制、转换和流处理。它不仅…

Unity ShaderLab基础

[原文1] [参考2] 一 基础知识 1. 1 着色器语言分类: 语言说明HLSL基于 OpenGL 的 OpenGL Shading LanguageGLSL基于 DirectX 的 High Level Shading LanguageCGNVIDIA 公司的 C for GraphicShader LabUnity封装了CG,HLSL,GLSL的Unity专用着色器语言,具有跨平台,图形化编程,便…

你的手机照片,我的使命,3个方法恢复删除的照片

照片不仅仅是记录生活瞬间的方式&#xff0c;它们是时间的印记&#xff0c;也是记忆的碎片。但当我们不小心删除&#xff0c;那些画面就如同盛夏的风&#xff0c;消失在秋天的旷野里。别担心&#xff0c;小编带着3个秘密武器来啦&#xff01;让我们一起开展一场与时间的赛跑&am…

【vluhub】log4j注入漏洞 CVE-2021-44228

LOG4介绍 是一个用Java编写的可靠&#xff0c;快速和灵活的日志框架&#xff08;API&#xff09;&#xff0c;它在Apache软件许可下发布 log4j存在远程代码执行漏洞、受影响版本2.x 部署环境 攻击机环境&#xff1a;192.168.3.180 kail环境&#xff1a;192.168.203.12【NAT…

如何切换网络IP地址?IP切换的应用与方法

随着互联网的发展和普及&#xff0c;我们日常生活中的各种操作和通讯越来越依赖互联网。互联网上存在的一些问题和限制使得更换IP地址成为必要的步骤。下面我们将探讨在互联网业务中&#xff0c;需要更换IP地址的原因与方法。 一、IP轮换的应用 解决访问限制&#xff1a;解决访…

人工智能驾驶技术:引领未来道路

随着科技的不断进步&#xff0c;人工智能驾驶技术正以惊人的速度改变着我们的交通方式和生活方式。这项技术不仅令人兴奋&#xff0c;还引发了许多关于安全性、道德和法律等方面的深思。本文将探讨人工智能自动驾驶技术的发展现状、应用前景以及对社会的影响。 技术背景与发展…