红外NEC通信协议
一、NEC简介
红外(Infrared,IR)遥控是一种无线、非接触控制技术,常用于遥控器、无线键盘、鼠标等设备之间的通信。IR协议的工作原理是,发送方通过红外线发送一个特定的编码,接收方通过识别该编码来执行相应的操作。
IR协议是指红外线通信协议的总称,而NEC协议是IR协议中的一种具体实现。红外遥控系统分为发射和接收两部分,发射部分的发射元件为红外发光二极管,它发出的是红外线而不是可见光;接收电路的红外接收管是一种光敏二极管。
二、NEC传输格式
NEC协议采用PPM(Pulse Position Modulation,脉冲位置调制)的形式进行编码,数据的每一位(Bit)脉冲长度为560us,由38KHz的载波脉冲 (carrier burst) 进行调制,推荐的载波占空比为 1/3至 1/4。有载波脉冲的地方,其宽度都为 560us,而载波脉冲的间隔时间是不同的。
逻辑“1”的载波脉冲+载波脉冲间隔时间为2.25ms;逻辑“0”的载波脉冲+载波脉冲间隔时间为逻辑“1”的一半,即1.125ms.
每次信息都是按照引导码 (9ms载波脉冲+4.5ms 空闲信号)地址码、地址反码、控制码和控制反码的格式进行传输,因此,单次信息传输的时间是固定不变的。
当红外遥控器上的按键被一直按下时,红外遥控器只会发送一次完整的信息,其后会每隔 110ms 发送一次重复码(连发码)。重复码的数据格式比较简单,同样是由 9ms的载波脉冲开始,紧接着是2.25ms的空闲信号,随后是560us的载波脉冲。
红外接收头通常被厂家集成在一个元件中,成为一体化红外接收头。红外接收头内部的三极管电路具有信号反向的功能,也就是将1变为0,0变为1,即数据0是0.56ms的低电平和0.56ms的高电平,数据1是0.5ms的低电平和1.69ms的高电平,9ms是高电平变为低电平。
三、FPGA实现
通过三段式状态机实现红外驱动模块
module ir_rcv(input clk , //系统时钟input rst_n , //系统复位信号,低电平有效input remote_in , //红外接收信号output reg repeat_en , //重复码有效信号output reg data_en , //数据有效信号output reg [7:0] data //红外控制码);//parameter define
parameter idle = 5'b0_0001; //空闲状态
parameter start_low_9ms = 5'b0_0010; //监测同步码低电平
parameter start_judge = 5'b0_0100; //判断重复码和同步码高电平(空闲信号)
parameter rec_data = 5'b0_1000; //接收数据
parameter repeat_code = 5'b1_0000; //重复码//reg define
reg [4:0] cur_state ; //当前状态
reg [4:0] next_state ; //下一状态reg [11:0] div_cnt ; //分频计数器
reg div_clk ; //分频时钟
reg remote_in_d0 ; //对输入的红外信号延时打拍
reg remote_in_d1 ;
reg [7:0] time_cnt ; //对红外的各个状态进行计数reg time_cnt_clr ; //计数器清零信号
reg time_done ; //计时完成信号
reg error_en ; //错误信号
reg judge_flag ; //检测出的标志信号 0:同步码高电平(空闲信号) 1:重复码
reg [15:0] data_temp ; //暂存收到的控制码和控制反码
reg [5:0] data_cnt ; //对接收的数据进行计数 //wire define
wire ir_pos ; //输入红外信号的上升沿
wire ir_neg ; //输入红外信号的下降沿//*****************************************************
//** main code
//*****************************************************assign ir_pos = (~remote_in_d1) & remote_in_d0;
assign ir_neg = remote_in_d1 & (~remote_in_d0);//对50MHz时钟进行分频,50Mhz/(2*(3124+1))=8khz,T=0.125ms,得到一个周期为0.125ms(8KHz)的时钟
//对时钟进行分频,是因为红外信号接收的过程用时较长,如果使用50Mhz的时钟采样,内部定义的计数器位宽会比较大,也可以分频成其它频率的时钟
always @(posedge clk or negedge rst_n ) beginif (!rst_n) begindiv_cnt <= 12'd0;div_clk <= 1'b0;end else if(div_cnt == 12'd3124) begindiv_cnt <= 12'd0;div_clk <= ~div_clk;end elsediv_cnt <= div_cnt + 12'b1;
end//对红外的各个状态进行计数,例如监测同步码低电平、判断重复码和同步码高电平等
always @(posedge div_clk or negedge rst_n) beginif(!rst_n)time_cnt <= 8'b0;else if(time_cnt_clr)time_cnt <= 8'b0;else time_cnt <= time_cnt + 8'b1;
end //对输入的remote_in信号延时打拍,即在一个时钟周期内,获取两个不同的红外信号采样值,以便后续的上升沿和下降沿检测
always @(posedge div_clk or negedge rst_n) beginif(!rst_n) beginremote_in_d0 <= 1'b0;remote_in_d1 <= 1'b0;endelse beginremote_in_d0 <= remote_in;remote_in_d1 <= remote_in_d0;end
end//采用三段式状态机对红外信号进行解析
always @ (posedge div_clk or negedge rst_n) beginif(!rst_n)cur_state <= idle;elsecur_state <= next_state ;
endalways @(*) beginnext_state = idle; case(cur_state)idle : begin //默认在空闲状态,time_cnt_clr的值置为1,time_cnt也就为0if(remote_in_d0 == 1'b0) //在空闲状态中检测到下降沿,则进入9ms低电平判断next_state = start_low_9ms; //此时time_cnt_clr的值置为0,time_cnt开始计数elsenext_state = idle; //否则一直保持空闲状态endstart_low_9ms : begin //监测同步码低电平if(time_done) //计数达到9ms,跳转判断重复码和同步码高电平next_state = start_judge;else if(error_en) //计数不在9ms范围,发生错误,跳转到空闲状态next_state = idle;elsenext_state = start_low_9ms; //否则一直保持在start_low_9msendstart_judge : begin //判断重复码和同步码高电平(空闲信号)if(time_done) beginif(judge_flag == 1'b0) //如果是同步码,则跳转到接收数据状态next_state = rec_data;else next_state = repeat_code; //否则跳转到重复码状态endelse if(error_en)next_state = idle;elsenext_state = start_judge;endrec_data : begin //接收数据,当数据传输完成,跳转到空闲状态if(ir_pos && data_cnt == 6'd32) next_state = idle;elsenext_state = rec_data; endrepeat_code : begin //重复码if(ir_pos)next_state = idle; //进入空闲状态elsenext_state = repeat_code; end default : next_state = idle;endcase
endalways @(posedge div_clk or negedge rst_n ) begin if (!rst_n) begin time_cnt_clr <= 1'b0;time_done <= 1'b0;error_en <= 1'b0;judge_flag <= 1'b0;data_en <= 1'b0;data <= 8'd0;repeat_en <= 1'b0;data_cnt <= 6'd0;data_temp <= 32'd0;endelse begintime_cnt_clr <= 1'b0;time_done <= 1'b0;error_en <= 1'b0;repeat_en <= 1'b0;data_en <= 1'b0;case(cur_state)idle : begintime_cnt_clr <= 1'b1;if(remote_in_d0 == 1'b0)time_cnt_clr <= 1'b0;end start_low_9ms : begin //9ms/0.125ms = 72if(ir_pos) begin //当检测到ir_pos(红外信号上升沿)为高电平时,说明此时红外信号拉高,即同步码低电平结束time_cnt_clr <= 1'b1; //停止计数 if(time_cnt >= 69 && time_cnt <= 75) //判断time_cnt的值是否接近9ms,如果接近9ms,跳转到start_judee状态time_done <= 1'b1; else //如果time_cnt的值不接近9ms,则发生了错误,跳转到空闲状态error_en <= 1'b1;end endstart_judge : beginif(ir_neg) begin time_cnt_clr <= 1'b1; if(time_cnt >= 15 && time_cnt <= 20) begin //重复码高电平2.25ms 2.25/0.125 = 18time_done <= 1'b1;judge_flag <= 1'b1; //检测出是重复码,跳转到repeat_code重复码状态end else if(time_cnt >= 33 && time_cnt <= 38) begin //同步码高电平4.5ms 4.5/0.125 = 36time_done <= 1'b1;judge_flag <= 1'b0; //检测出是同步码,跳转到rec_data接收数据状态 endelseerror_en <= 1'b1;end endrec_data : begin if(ir_pos) begin //当有红外信号上升沿time_cnt_clr <= 1'b1;if(data_cnt == 6'd32) begin //有32个数据即32个上升沿或下降沿,分别为16位地址码以及16位数据data_en <= 1'b1; //当计数到32即数据传输完成data_cnt <= 6'd0;data_temp <= 16'd0;if(data_temp[7:0] == ~data_temp[15:8]) //校验控制码和控制反码data <= data_temp[7:0];endendelse if(ir_neg) begin //当有红外信号下降沿time_cnt_clr <= 1'b1;data_cnt <= data_cnt + 1'b1; //每当1bit数据到来时也就是一个下降沿到来时,数据位数计数器加1//解析控制码和控制反码,判断是560us还是1690us计数完成,进而得到这个数据位是0还是1 if(data_cnt >= 6'd16 && data_cnt <= 6'd31) begin if(time_cnt >= 2 && time_cnt <= 6) begin //0.565/0.125 = 4.52data_temp <= {1'b0,data_temp[15:1]}; //逻辑“0”endelse if(time_cnt >= 10 && time_cnt <= 15) //1.69/0.125 = 13.52data_temp <= {1'b1,data_temp[15:1]}; //逻辑“1”endendendrepeat_code : begin if(ir_pos) begin time_cnt_clr <= 1'b1;repeat_en <= 1'b1;endenddefault : ;endcaseend
endendmodule
相关文章:

红外NEC通信协议
一、NEC简介 红外(Infrared,IR)遥控是一种无线、非接触控制技术,常用于遥控器、无线键盘、鼠标等设备之间的通信。IR协议的工作原理是,发送方通过红外线发送一个特定的编码,接收方通过识别该编码来执行相应的操作。 IR协议是指红外…...
数据分析DAY1
数据分析 引言 这一周:学习了python的numpy和matplotlib以及在飞桨paddle上面做了几个小项目 发现numpy和matplotlib里面有很多api,要全部记住是不可能的,也是不可能全部学完的,所以我们要知道并且熟悉一些常用的api࿰…...

算法通关村—迭代实现二叉树的前序,中序,后序遍历
1. 前序中序后序递归写法 前序 public void preorder(TreeNode root, List<Integer> res) {if (root null) {return;}res.add(root.val);preorder(root.left, res);preorder(root.right, res);}后序 public static void postOrderRecur(TreeNode head) {if (head nu…...

二叉搜索树(BST)的模拟实现
序言: 构造一棵二叉排序树的目的并不是为了排序,而是为了提高查找效率、插入和删除关键字的速度,同时二叉搜索树的这种非线性结构也有利于插入和删除的实现。 目录 (一)BST的定义 (二)二叉搜…...
【MFC】01.MFC框架-笔记
基本概念 MFC Microsoft Fundation class 微软基础类库 框架 基于Win32 SDK进行的封装 属性:缓解库关闭 属性->C/C/代码生成/运行库/MTD 属性->常规->MFC的使用:在静态库中使用MFC,默认是使用的共享DLL,运行时库 SD…...
基于ArcGIS污染物浓度及风险的时空分布
在GIS发展的早期,专业人士主要关注于数据编辑或者集中于应用工程,以及主要把精力花费在创建GIS数据库并构造地理信息和知识。慢慢的,GIS的专业人士开始在大量的GIS应用中使用这些知识信息库。用户应用功能全面的GIS工作站来编辑地理数据集&am…...
【项目开发计划制定工作经验之谈】
一、背景介绍 随着信息技术的发展,项目管理越来越受到企业和组织的重视。项目管理是一项旨在规划、组织、管理和控制项目的活动,以达到特定目标的过程。项目开发计划是项目管理的一个重要组成部分,它是指定项目目标、工作范围、进度、质量、…...

基于STM32的格力空调红外控制
基于STM32的格力空调红外控制 1.红外线简介 在光谱中波长自760nm至400um的电磁波称为红外线,它是一种不可见光。目前几乎所有的视频和音频设备都可以通过红外遥控的方式进行遥控,比如电视机、空调、影碟机等,都可以见到红外遥控的影子。这种技…...
rust中thiserror怎么使用呢?
thiserror 是一个Rust库,可以帮助你更方便地定义自己的错误类型。它提供了一个类似于 macro_rules 的宏,可以帮助你快速地定义错误类型,并为错误添加上下文信息。下面是一个使用 thiserror 的示例: 首先,在你的Rust项…...
ceph tier和bcache区别
作者:吴业亮 博客:wuyeliang.blog.csdn.net Ceph tier(SSD POOL HDD POOL)不推荐的原因: 数据在两个资源池之间迁移代价太大,存在粒度问题(对象级别),且需要进行write…...
Idea 2023.2 maven 打包时提示 waring 问题解决
Version idea 2023.2 问题 使用 Maven 打包 ,控制台输出 Waring 信息 [WARNING] [WARNING] Plugin validation issues were detected in 7 plugin(s) [WARNING] [WARNING] * org.apache.maven.plugins:maven-dependency-plugin:3.3.0 [WARNING] * org.apache.…...

docker数据持久化
在Docker中若要想实现容器数据的持久化(所谓的数据持久化即数据不随着Container的结束而销毁),需要将数据从宿主机挂载到容器中。目前Docker提供了三种不同的方式将数据从宿主机挂载到容器中。 (1)Volumes:…...

安全防护,保障企业图文档安全的有效方法
随着企业现在数据量的不断增加和数据泄露事件的频发,图文档的安全性成为了企业必须高度关注的问题。传统的纸质文件存储方式已不适应现代企业的需求,而在线图文档管理成为了更加安全可靠的数字化解决方案。那么在在线图文档管理中,如何采取有…...

Open3D (C++) 基于拟合平面的点云地面点提取
目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示1、原始点云2、提取结果四、相关链接本文由CSDN点云侠原创,原文链接。爬虫网站自重,把自己当个人,爬些不完整的误导别人有意思吗???? 一、算法原理...
【Linux】Kali Linux 渗透安全学习笔记(2) - OneForAll 简单应用
OneForAll (以下简称“OFA”)是一个非常好用的子域收集工具,可以通过一级域名找到旗下的所有层级域名,通过递归的方式我们很容易就能够知道此域名下的所有域名层级结构,对于进一步通过域名推测站点功能起到非常重要的作…...

DAY56:单调栈(二)下一个最大元素Ⅱ(环形数组处理思路)
文章目录 思路写法1完整版环形数组处理:i取模,遍历两遍写法2完整版(环形数组推荐写法)debug测试:逻辑运算符短路特性result数组在栈口取元素,是否会覆盖原有数值? 给定一个循环数组 nums &#…...
kafka简介
kafka是什么? Kafka最初采用Scala语言开发的一个多分区、多副本并且基于ZooKeeper协调的分布式消息系统。目前Kafka已经定位为一个分布式流式处理平台,它的特性有高吞吐、可持久化、可水平扩展、支持流处理。 Apache Kafka是一个分布式的发布-订阅消息系…...

Kafka-消费者组消费流程
消费者向kafka集群发送消费请求,消费者客户端默认每次从kafka集群拉取50M数据,放到缓冲队列中,消费者从缓冲队列中每次拉取500条数据进行消费。...

FFmepg视频解码
1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置,本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单,实际就4步: 打开媒体流获取…...

SpringCloud深入理解 | 生产者、消费者
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! SpringCloud Spring Cloud是一组用于构建分布式系统和微服务架构的开源框架和工具集合。它是在Spring生态系统的基础上构建的,旨在简化开发人员构建分布式…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...