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

一、前言

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();        //初始化串口波特率为4800Infrared_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重装值为0TL0=0; //定时器0重装值为0TR0=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;//开启定时器0while(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.xdnf.cn/news/1489488.html

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

相关文章

WHAT - 屏幕 dpr 设备像素比率

目录 一、设备像素比率 (DPR)二、DPR 与每英寸点数 (DPI)三、dpr2 和 dpr1 有什么区别设备像素比率为 1 (DPR 1)设备像素比率为 2 (DPR 2)实际区别示例代码例子 一、设备像素比率 (DPR) DPR&#xff08;设备像素比率&#xff09;常常在讨论屏幕分辨率和显示质量时使用。 设…

RockyLinux 9 PXE Server bios+uefi 自动化部署 RockLinux 8 9

pxe server 前言 PXE&#xff08;Preboot eXecution Environment&#xff0c;预启动执行环境&#xff09;是一种网络启动协议&#xff0c;允许计算机通过网络启动而不是使用本地硬盘。PXE服务器是实现这一功能的服务器&#xff0c;它提供了启动镜像和引导加载程序&#xff0c;…

1.2 单链表定义及操作实现(链式结构)

1.单链表定义 链式存储&#xff1a;用一组任意的存储单元存储线性表中的数据元素。用这种方法存储的线性 表简称线性链表。 为了正确表示结点间的逻辑关系&#xff0c;在存储每个结点值的同时&#xff0c;还必须存储指示其直接 后继结点的地址&#xff08;或位置&#xff09;…

故障诊断 | 基于Transformer故障诊断分类预测(Matlab)

文章目录 预测效果文章概述程序设计参考资料预测效果 文章概述 Transformer故障诊断/分类预测 | 基于Transformer故障诊断分类预测(Matlab) Transformer 模型本质上都是预训练语言模型,大都采用自监督学习 (Self-supervised learning) 的方式在大量生语料上进行训练,也就是…

Java解析epub电子书文件实战demo

如何使用 Java、Spring Boot 和 Epublib 库解析存储在阿里云对象存储服务&#xff08;OSS&#xff09;上的 EPUB 文件。这里将指导您完成设置必要依赖项、配置 OSS 客户端以及编写服务以读取和提取 EPUB 文件章节的全过程。 步骤1&#xff1a;添加依赖项 首先&#xff0c;将 E…

微信小程序消息订阅处理实践

微信小程序提供订阅消息功能&#xff0c;分为一次性订阅消息、长期订阅消息。长期订阅消息目前只针对民生、金融、教育等有线下服务场景的类目开放。这些只是大类&#xff0c;并不表示所包含的所有二级类目都能申请长期订阅消息&#xff0c;具体看官方文档。 另一个长期订阅消…

RNN(一)——循环神经网络的实现

文章目录 一、循环神经网络RNN1.RNN是什么2.RNN的语言模型3.RNN的结构形式 二、完整代码三、代码解读1.参数return_sequences2.调参过程 一、循环神经网络RNN 1.RNN是什么 循环神经网络RNN主要体现在上下文对理解的重要性&#xff0c;他比传统的神经网络&#xff08;传统的神…

04 卷积神经网络

目录 1. 基本概念 1.1 卷积神经网络 1.2 卷积 1.3 汇聚&#xff08;池化&#xff09; 2. CNN网络架构及参数学习 2.1 网络架构 2.2 参数学习 3. 典型的卷积神经网络 3.1 LeNet-5 3.2 AlexNet 3.3 Inception网络 3.4 残差网络 4. 其他卷积方式 1. 基本概念 1.1 …

ReentrantReadWriteLock详解

目录 ReentrantReadWriteLock详解1、ReentrantReadWriteLock简介2、ReentrantReadWriteLock类继承结构和类属性3、ReentrantReadWriteLock的读写锁原理分析4、ReentrantReadWriteLock.WriteLock类的核心方法详解非公平写锁的获取非公平写锁的释放公平写锁的获取公平写锁的释放 …

全网最最实用--模型高效推理:量化基础

文章目录 一、量化基础--计算机中数的表示1. 原码&#xff08;Sign-Magnitude&#xff09;2. 反码&#xff08;Ones Complement&#xff09;3. 补码&#xff08;Twos Complement&#xff09;4. 浮点数&#xff08;Floating Point&#xff09;a.常用的浮点数标准--IEEE 754(FP32…

ElasticSearch核心之DSL查询语句实战

什么是DSL&#xff1f; Elasticsearch提供丰富且灵活的查询语言叫做DSL查询(Query DSL),它允许你构建更加复杂、强大的查询。 DSL(Domain Specific Language特定领域语言)以JSON请求体的形式出现。目前常用的框架查询方法什么的底层都是构建DSL语句实现的&#xff0c;所以你必…

跨境电商独立站:Shopify/Wordpress/店匠选哪个?

在面对不断增加的平台运营压力时&#xff0c;不少跨境电商的商家逐渐将注意力转向建立自己的独立站。据《中国跨境出口电商发展报告&#xff08;2022&#xff09;》所示&#xff0c;中国拥有的独立站数量在2022年已接近20万个&#xff0c;这表明独立站已成为卖家拓展海外市场的…

IndentationError:unindent does not match any outer indentation level

IndentationError:unindent does not match any outer indentation level 目录 IndentationError:unindent does not match any outer indentation level 【常见模块错误】 【解决方案】 原因分析&#xff1a; 解决方法&#xff1a; 示例&#xff1a; 欢迎来到我的主页&am…

正则采集器——前端搭建

前端使用有名的饿了么管理后台&#xff0c;vue3版本vue3-element-admin&#xff0c;首先从gitee中克隆一个vue3-element-admin模板代码vue3-element-admin: Vue3 Element Admin开箱即用的中后台管理系统前端解决方案&#xff0c;然后在此基础上进行开发。 1、修改vite.config.…

matlab仿真 数字信号载波传输(下)

&#xff08;内容源自详解MATLAB&#xff0f;SIMULINK 通信系统建模与仿真 刘学勇编著第七 章内容&#xff0c;有兴趣的读者请阅读原书&#xff09; clear all M8; msg[1 4 3 0 7 5 2 6]; ts0.01; T1; %t0:ts:T; t0:ts:T-ts; %x0:ts:length(msg); x0:ts:length(msg)-ts; f…

使用Dumpbin工具查看C++二进制文件的位数、时间戳及dll库的依赖关系

目录 1、Dumpbin简介 2、使用Dumpbin查看二进制文件的位数与时间戳 3、使用Dumpbin查看二进制文件依赖的dll库 4、最后 C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C/C++基础入…

几种数据库中保存树的常见存储结构

在数据库中存储树时&#xff0c;常见的存储结构有以下几种&#xff1a; 常见存储结构 邻接列表 每个节点都有一个指向其父节点(pid)的引用。这种方法简单直观&#xff0c;也是最容易理解和常用的&#xff0c;但在获取整棵树或子树时可能需要多次查询。 存储结构 一般表结构…

自动驾驶-机器人-slam-定位面经和面试知识系列05之常考公式推导(02)

这个博客系列会分为C STL-面经、常考公式推导和SLAM面经面试题等三个系列进行更新&#xff0c;基本涵盖了自己秋招历程被问过的面试内容&#xff08;除了实习和学校项目相关的具体细节&#xff09;。在知乎和牛客&#xff08;牛客上某些文章上会附上内推码&#xff09;也会同步…

Android APP 音视频(03)CameraX预览与MediaCodec编码

说明&#xff1a; 此CameraX预览和编码实操主要针对Android12.0系统。通过CameraX预览获取yuv格式数据&#xff0c;将yuv格式数据通过mediacodec编码输出H264码流&#xff08;使用ffmpeg播放&#xff09;&#xff0c;存储到sd卡上。 1 CameraX 和 MediaCodec简介 1.1 CameraX…

【CN】Argo 持续集成和交付(一)

1.简介 Argo 英 [ˈɑ:ɡəu] 美 [ˈɑrˌɡo] Kubernetes 原生工具&#xff0c;用于运行工作流程、管理集群以及正确执行 GitOps。 Argo 于 2020 年 3 月 26 日被 CNCF 接受为孵化成熟度级别&#xff0c;然后于 2022 年 12 月 6 日转移到毕业成熟度级别。 argoproj.github.i…