#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;保…

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;…

深入浅出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…

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

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

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

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

规则持久化(Sentinel)

规则持久化 基于Nacos配置中心实现推送 引入依赖 <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId> </dependency> 流控配置文件 [{"resource":"/order/flow",…

六、Vuex

六、Vuex 6.1 Vuex是什么 概念&#xff1a;专门在 Vue 中实现集中式状态&#xff08;数据&#xff09;管理的一个 Vue 插件&#xff0c;对 vue 应 用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方 式&#xff0c;且…

vue3获取环境变量import.meta.env

vitevue的时候环境变量的获取方式变成如下&#xff1a; console.log(import.meta.env)

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables

目录 一&#xff0c;AArch64 异常向量表 二&#xff0c;栈指针以及SP寄存器的选择 三&#xff0c;从异常返回 一&#xff0c;AArch64 异常向量表 异常向量表&#xff08;vector tables&#xff09;是一组存放于普通内存&#xff08;normal memory&#xff09;空间的&#xf…

【机器学习科学库】全md文档笔记:Jupyter Notebook和Matplotlib使用(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论人工智能相关知识。主要内容包括&#xff0c;了解机器学习定义以及应用场景&#xff0c;掌握机器学习基础环境的安装和使用&#xff0c;掌握利用常用的科学计算库对数据进行展示、分析&#xff0c;学会使用jupyter note…

vue从flask获取数据并显示

记录一个前后端分离遇到的问题&#xff0c;即vue前端从flask后端获取数据。具体描述如下&#xff1a;flask只负责连接数据库并获取数据库的数据&#xff0c;并返回给前端vue&#xff1b;vue则需要获取后端返回的数据并显示。 方法如下&#xff0c;分别用一个vue组件和一个flas…

【网站项目】488服装店销售管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…