#FPGA(IRDA)

1.IDE:Quartus II


2.设备:Cyclone II  EP2C8Q208C8N  


3.实验:IRDA(仿真接收一个来自0x57地址的数据0x22  (十进制34))


4.时序图:

 


5.步骤


6.代码:

irda_receive.v

module irda_receive
(
input      wire               sys_clk      ,
input      wire               sys_rst_n    ,
input      wire               irda_in      ,        //irda接收端引脚输入output     reg      [19:0]     data         ,        //数据输出
output     reg                 repeat_en             //重复使能
);/**状态*/
parameter  IDLE          =    5'b00001     ;     //空闲
parameter  TIME_9MS      =    5'b00010     ;     //引导或者重复的9ms低电平
parameter  ARBIT         =    5'b00100     ;     //地址
parameter  DATA          =    5'b01000     ;     //数据
parameter  REPEAT        =    5'b10000     ;     //重复/**时间范围*/
parameter  CNT_560US_MIN         =        19'd20000         ; 
parameter  CNT_560US_MAX         =        19'd35000         ; 
parameter  CNT_1_69MS_MIN        =        19'd80000         ; 
parameter  CNT_1_69MS_MAX        =        19'd90000         ; 
parameter  CNT_2_25MS_MIN        =        19'd100000        ; 
parameter  CNT_2_25MS_MAX        =        19'd125000        ; 
parameter  CNT_4_5MS_MIN         =        19'd175000        ; 
parameter  CNT_4_5MS_MAX         =        19'd275000        ; 
parameter  CNT_9MS_MIN           =        19'd400000        ; 
parameter  CNT_9MS_MAX           =        19'd490000        ; /**寄存器*/
reg      [4:0]        state                ;     //状态   
reg                   inf_in_dly1          ;     //用于电平跳转判断(下一时刻)
reg                   inf_in_dly2          ;     //用于电平跳转判断(上一时刻)
wire                  inf_in_fall          ;     //下降沿标志位
wire                  inf_in_rise          ;     //上升沿标志位reg      [18:0]       cnt                  ;     //计数器reg                   flag_9ms             ;     //9ms标志位
reg                   flag_4_5ms           ;     //4.5ms标志位
reg                   flag_560us           ;     //560us标志位
reg                   flag_1_69ms          ;     //1.69ms标志位
reg                   flag_2_25ms          ;     //2.25ms标志位reg      [5:0]        cnt_data             ;     //记录接收的数据个数
reg      [31:0]       data_reg             ;     //数据记录/**状态跳转*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)state <= IDLE;else  case(state)IDLE    :begin if(inf_in_fall == 1'b1)      //引导信号下降沿到来state <= TIME_9MS;elsestate <= IDLE;endTIME_9MS:beginif((inf_in_rise == 1'b1)&&(flag_9ms == 1'b1))      //引导信号到来后持续低电平再拉高,低电平时间达到9ms(进入接收地址码状态)state <= ARBIT;                                   else if((inf_in_rise == 1'b1)&&(flag_9ms == 1'b0)) //引导信号到来后持续低电平再拉高,低电平时间未达到9ms(恢复空闲状态)state <= IDLE;else                                             //引导信号到来后持续低电平未检测到高电平时期(还未拉高,等待中,保持状态不变)state <= TIME_9MS;end	ARBIT   :beginif((inf_in_fall==1'b1)&&(flag_2_25ms == 1'b1))     //下降沿到来接收到重复码(高电平时间未2.25ms,则为重复码,高电平时间为4.5ms则为引导码)state <= REPEAT;else if((inf_in_fall==1'b1)&&(flag_4_5ms == 1'b1)) state <= DATA ;else if((inf_in_fall==1'b1)&&(flag_4_5ms == 1'b0)&&(flag_2_25ms == 1'b0))  //下降沿到来,高电平不满足2.25ms和4.5ms  state <= IDLE;else                                               //保持原状态state <= ARBIT;endDATA    :beginif((inf_in_rise == 1'b1) && (flag_560us == 1'b0))  //数据信号低电平不满足“0”要求state <= IDLE;else if((inf_in_fall == 1'b1)&&(flag_560us == 1'b0)&&(flag_1_69ms == 1'b0))  //下降沿到来,但是高电平不足560usstate <= IDLE;else if((inf_in_rise == 1'b1)&&(cnt_data == 6'd32)) //结束信号是拉高,计数到32个数据state <= IDLE;elsestate <= DATA;end		 REPEAT  :beginif(inf_in_rise == 1'b1)state <= IDLE;elsestate <= REPEAT;enddefault :beginstate <= IDLE; endendcase	 
end/**电平翻转记录*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)begininf_in_dly1 <= 1'b0;inf_in_dly2 <= 1'b0;endelsebegininf_in_dly1 <= irda_in;  //记录当前电平inf_in_dly2 <= inf_in_dly1; //记录上一时刻电平end
end/**下降沿上升沿标志位赋值*/
assign inf_in_fall = ((inf_in_dly1 == 1'b0)&&(inf_in_dly2 == 1'b1)) ? 1'b1 : 1'b0;  //上一时刻高电平,当前时刻低电平(下降沿标志位拉高)
assign inf_in_rise = ((inf_in_dly1 == 1'b1)&&(inf_in_dly2 == 1'b0)) ? 1'b1 : 1'b0;  //上一时刻低电平,当前时刻高电平(上升沿标志位拉高)/**cnt控制*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)cnt <= 19'd0;else case(state)IDLE         : cnt <= 19'd0;TIME_9MS     :beginif((inf_in_rise == 1'b1)&&(flag_9ms == 1'b1))cnt <= 19'd0;elsecnt <= cnt + 1'b1;endARBIT        :beginif((inf_in_fall == 1'b1) && ((flag_4_5ms == 1'b1)||(flag_2_25ms == 1'b1)))         //仲裁(引导信号还是重复信号)cnt <= 19'd0;elsecnt <= cnt + 1'b1;endDATA         :beginif((inf_in_rise == 1'b1)&&(flag_560us == 1'b1))cnt <= 19'd0;else if((inf_in_fall == 1'b1)&&((flag_560us == 1'b1)||(flag_1_69ms == 1'b1)))      // 0/1cnt <= 19'd0;elsecnt <= cnt + 1'b1; enddefault      : cnt <= 19'd0;endcase
end/**时间标志位控制*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)flag_9ms <= 1'b0;else if((state == TIME_9MS)&&(cnt >= CNT_9MS_MIN)&&(cnt <= CNT_9MS_MAX))flag_9ms <= 1'b1;elseflag_9ms <= 1'b0;
endalways @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)flag_4_5ms <= 1'b0;else if((state == ARBIT)&&(cnt >= CNT_4_5MS_MIN)&&(cnt <= CNT_4_5MS_MAX))flag_4_5ms <= 1'b1;elseflag_4_5ms <= 1'b0;
endalways @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)flag_560us <= 1'b0;else if((state == DATA)&&(cnt >= CNT_560US_MIN)&&(cnt <= CNT_560US_MAX))flag_560us <= 1'b1;elseflag_560us <= 1'b0;
endalways @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)flag_1_69ms <= 1'b0;else if((state == DATA)&&(cnt >= CNT_1_69MS_MIN)&&(cnt <= CNT_1_69MS_MAX))flag_1_69ms <= 1'b1;elseflag_1_69ms <= 1'b0;
endalways @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)flag_2_25ms <= 1'b0;else if((state == ARBIT)&&(cnt >= CNT_2_25MS_MIN)&&(cnt <= CNT_2_25MS_MAX))flag_2_25ms <= 1'b1;elseflag_2_25ms <= 1'b0;
end/**接收数据计数*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)cnt_data <= 6'd0;else if((inf_in_rise == 1'b1)&&(cnt_data == 6'd32))cnt_data <= 6'd0;else if((inf_in_fall == 1'b1)&&(state == DATA))cnt_data <= cnt_data + 1'b1;elsecnt_data <= cnt_data;
end/**接收的数据*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)data_reg <= 32'b0;else if((state == DATA)&&(inf_in_fall == 1'b1)&&(flag_560us == 1'b1))data_reg[cnt_data] <= 1'b0;else if((state == DATA)&&(inf_in_fall == 1'b1)&&(flag_1_69ms == 1'b1))data_reg[cnt_data] <= 1'b1;elsedata_reg <= data_reg;
end/**数据倒排(LSB)*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)data <= 20'b0;else if((cnt_data == 6'd32)&&(~data_reg[23:16] == data_reg[31:24])&&(~data_reg[15:8] == data_reg[7:0]))data <= {12'b0,data_reg[23:16]};elsedata <= data;
end/**重复信号使能控制*/
always @ (posedge sys_clk or negedge sys_rst_n) beginif(sys_rst_n == 1'b0)repeat_en <= 1'b0;else if((state ==REPEAT)&&(~data_reg[23:16] == data_reg[31:24]))repeat_en <= 1'b1;elserepeat_en <= 1'b0;
endendmodule

 仿真代码:

`timescale 1ns/1ns
module tb_irda_receive();reg        sys_clk             ;
reg        sys_rst_n           ;
reg        inf_in             ;wire       [19:0]   data       ;
wire                repeat_en  ;initial beginsys_clk = 1'b1;sys_rst_n = 1'b0;inf_in <= 1'b1;#30sys_rst_n <= 1'b1;#1000
//引导码    inf_in <= 1'b0;#9000_000inf_in <= 1'b1;#4500_000
//地址码(8'h57     0101_0111         1110_1010)inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0
//地址反码(1110_1010     0001_0101)inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1
//数据码(8'h22  0010_0010   0100_0100)inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000             //逻辑0
//数据反码(0100_0100   1011_1011)inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #560_000            //逻辑0inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1inf_in <= 1'b0;#560_000inf_in <= 1'b1;     #1690_000            //逻辑1
//结束位inf_in <= 1'b0;#560_000
//高电平保持			  inf_in <= 1'b1;#4200_0000
//重复码inf_in <= 1'b0;#9000_000inf_in <= 1'b1;#2250_000			
//结束位inf_in <= 1'b0;#560_000inf_in <= 1'b1;			  endalways #10 sys_clk = ~ sys_clk;/**实例化*/
irda_receive irda_receive_inst
(
.sys_clk            (sys_clk  )    ,
.sys_rst_n          (sys_rst_n)    ,
.irda_in            (inf_in  )    ,        //irda接收端引脚输入.data               (data     )    ,        //数据输出
.repeat_en          (repeat_en)             //重复使能
);endmodule

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

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

相关文章

从故宫修建看「软件物料清单」的重要性 @安全历史01

故宫&#xff0c;这座中国传统文化的重要代表和象征性建筑已屹立近600年&#xff0c;是世界上现存规模最大、保存最为完整的木质结构古建筑之一。 故宫之所以能至今保存完好&#xff0c;除持续保护和修缮外&#xff0c;其使用的木材和砖石等材料也经过了精挑细选&#xff0c;保…

C++函数对象-运算符函数对象 - 旧式绑定器与适配器 - 从成员函数指针创建包装器,可以一个对象指针调用 (std::mem_fun)

任何定义了函数调用操作符的对象都是函数对象。C 支持创建、操作新的函数对象&#xff0c;同时也提供了许多内置的函数对象。 旧式绑定器与适配器 早期提供功能支持的几个工具在 C11 中弃用&#xff0c;并于 C17 中移除&#xff08;旧否定器于 C17 中弃用并于 C20 中移除&#…

IOBR2 更新(学习自备)

IOBR查看其收录的相关基因集(自备)_肿瘤 tme特征 iobr-CSDN博客 IOBR2&#xff1a;多维度解析肿瘤微环境 - 知乎 (zhihu.com) 学习手册&#xff1a;https://iobr.github.io/book/ &#xff08;里面有详细教程&#xff09; 系统综合的分析工具&#xff08;Immuno-Oncology Bi…

渗透工具——kali中wpscan简介

一、什么是wpscan 1、常用于做用户名枚举爆破 2、WPScan是一个扫描 WordPress 漏洞的黑盒子扫描器&#xff0c;它可以为所有 Web 开发人员扫描 WordPress 漏洞并在他们开发前找到并解决问题。我们还使用了 Nikto &#xff0c;它是一款非常棒的Web 服务器评估工具&#xff0c;…

神经网络系列---独热编码(One-Hot Encoding)

文章目录 独热编码&#xff08;One-Hot Encoding&#xff09; 独热编码&#xff08;One-Hot Encoding&#xff09; 是一种常用的数据预处理技术&#xff0c;用于将分类变量转换为计算机易于处理的二进制格式。在机器学习和数据分析中&#xff0c;我们通常会遇到非数值型的特征…

深入浅出JVM(九)之字节码指令(上篇)

本篇文章主要围绕字节码的指令&#xff0c;深入浅出的解析各种类型字节码指令&#xff0c;如&#xff1a;加载存储、算术、类型转换、对象创建与访问、方法调用与返回、控制转义、异常处理、同步等 由于字节码指令种类太多&#xff0c;本文作为上篇概述加载存储、算术、类型转…

IT廉连看——C语言——操作符

IT廉连看—操作符 c语言中有许多操作符&#xff0c;可以用于对变量进行各种不同的操作 一、算术操作符 - * / % 除了 % 操作符之外&#xff0c;其他的几个操作符可以作用于整数和浮点数。 对于 / 操作符如果两个操作数都为整数&#xff0c;执行整数除法。而只要有浮点…

vue+nodejs+uniapp婚纱定制婚庆摄影系统 微信小程序 springboot+python

目前移动互联网大行其道&#xff0c;人人都手中拿着智能机&#xff0c;手机手机&#xff0c;手不离机&#xff0c;如果开发一个用在手机上的程序软件&#xff0c;那是多么的符合潮流&#xff0c;符合管理者和客户的理想。本次就是开发婚庆摄影小程序&#xff0c;有管理员&#…

基础光学系列:(三)揭秘机器视觉中的光圈、焦距与景深的作用

​今天来聊聊成像原理、光圈、焦距和景深&#xff0c;这些概念在摄影、摄像以及机器视觉领域都非常重要。它们共同影响着成像设备捕捉图像的质量和特性。让我们一一解析这些概念以及它们如何在机器视觉行业中应用。 成像原理&#xff1a;怎样把外面的世界捕捉进来 想象一下&a…

大厂面试-美团高频考察算法之重排链表

本文学习目标或巩固的知识点 学习如何处理链表重排类题目 巩固反转链表巩固快慢指针巩固合并链表 提前说明&#xff1a;算法题目来自力扣、牛客等等途径 &#x1f7e2;表示简单 &#x1f7e1;表示中等 &#x1f534;表示困难 &#x1f92e;表示恶心 博主真实经历&#xff0c;…

前后端分离Vue+ElementUI+nodejs蛋糕甜品商城购物网站95m4l

本文主要介绍了一种基于windows平台实现的蛋糕购物商城网站。该系统为用户找到蛋糕购物商城网站提供了更安全、更高效、更便捷的途径。本系统有二个角色&#xff1a;管理员和用户&#xff0c;要求具备以下功能&#xff1a; &#xff08;1&#xff09;用户可以修改个人信息&…

LabVIEW储氢材料循环寿命测试系统

LabVIEW储氢材料循环寿命测试系统 随着氢能技术的发展&#xff0c;固态储氢技术因其高密度和安全性成为研究热点。储氢材料的循环寿命是衡量其工程应用的关键。然而&#xff0c;传统的循环寿命测试设备存在成本高、测试效率低、数据处理复杂等问题。设计了一种基于LabVIEW软件…

uniapp 使用 z-paging组件

使用 z-paging 导入插件 获取插件进行导入 自定义上拉加载样式和下拉加载样式 页面结构 例子 搭建页面 <template><view class"content"><z-paging ref"paging" v-model"dataList" query"queryList"><templ…

记录 | docker基本操作

重命名镜像 docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库&#xff1a;标签)# 例子 docker tag ca1b6b825289 registry.cn-hangzhou.aliyuncs.com/xxxxxxx:v1.0 启动 docker cuda docker hub 地址&#xff1a; https://hub.docker.com/r/nvidia/cuda/tags/?page1&na…

蓝桥杯倒计时48天!二分模板

倒计时48天&#xff01; 二分 二分模板 判断是否可以二分 &#xff08;1&#xff09;单调性 备选答案集是有序的 &#xff08;2&#xff09;二段性 在检查了mid是否符合要求之和&#xff0c;我可以舍弃mid左右某一边的答案 两个模板 关键词&#xff1a;满足条件的最小值…

【每日前端面经】2023-02-24

题目来源: 牛客 对Vue的理解 Vue是一款流行的JS前端框架&#xff0c;关注的核心是MVC模式的视图层&#xff0c;能够简化数据更新 Vue的核心是数据驱动、组件化和指令系统 数据驱动: 分为模型层、视图层和视图模型层组件化: 可以把各种逻辑封装进统一组件进行复用指令系统: 当…

【VSCode】SSH Remote 通过跳板机连开发机提示“bash行1 powershell未找到命令”

需求背景 因为需要&#xff0c;在家我需要挂上公司VPN然后SSH连到跳板机&#xff0c;然后再从跳板机SSH进开发机。 问题背景 跳板机进开发机输入完密码显示 bash行1 powershell未找到命令VSCode SSH Remote跳板机配置请自行搜素其他文章config配置 注意其中ssh.exe地址请根据…

Microsoft Edge 越用越慢、超级卡顿?网页B站播放卡顿?

记录10个小妙招 Microsoft Edge 启动缓慢、菜单导航卡顿、浏览响应沉闷&#xff1f;这些情况可能是由于系统资源不足或浏览器没及时更新引起的。接下来&#xff0c;我们将介绍 10 种简单的方法&#xff0c;让 Edge 浏览器的速度重新起飞。 基础检查与问题解决 如果 Microsoft…

基于Python爬虫河南开封酒店数据可视化系统设计与实现(Django框架) 研究背景与意义、国内外研究现状

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

并发编程(5)共享模型之不可变

7 共享模型之不可变 本章内容 不可变类的使用不可变类设计无状态类设计 7.1 日期转换的问题 问题提出 下面的代码在运行时&#xff0c;由于 SimpleDateFormat 不是线程安全的, 有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果&#xff0c;…