项目名称

HT6221红外遥控解码设计

具体要求

接收红外按键的数据在ISSP上观察

设计说明

下图为红外遥控器及按键图。红外接收头有三个引脚,电源、地和信号输出。

HT6221芯片的红外遥控发送数据帧定义,一帧数据由引导码、地址码、数据码及数据反码组成。地址码共16位,低位在前,高位在后,8位数据码及其反码也是低位在前,高位在后。

HT6221芯片是一款基于NEC红外通信协议的遥控编码芯片,该协议采用脉冲之间不同时长的时间间隔来区分“1”和“0”,下图为其编码协议中“1”和“0”的编码波形,而在实际接收时,接收头接收到信号后输出的波形刚好与此波形反相。

数据1是0.56ms的低电平和1.69ms的高电平,数据0是0.56ms的低电平和0.56ms的高电平。

代码设计

本次将代码拆开说明,先定义红外解码模块端口列表。iIR为接收头输出数据,irdata为解码后的数据码,iraddr为解码后的地址码,get_flag为解码完成标志信号。

module ir_decode(input               clk,input               rst_n,input             iIR,output  [15:0]irdata,output [15:0]iraddr,output         get_flag
);

对接收头输出的数据进行同步,并定义一个上升沿和下降沿信号。

reg iIR_s0;
reg iIR_s1;
always@(posedge clk or negedge rst_n)if(!rst_n)beginiIR_s0<=0;iIR_s1<=0;end else beginiIR_s0<=iIR;iIR_s1<=iIR_s0;end
wire nedge=iIR_s1 && ~iIR_s0;
wire pedge=~iIR_s1 && iIR_s0;

在使能计数的时候开始计数,计数超过10ms,计数器就开始清零。

reg en_cnt;
reg [18:0] cnt;
always@(posedge clk or negedge rst_n)if(!rst_n)cnt<=0;else if(en_cnt)cnt<=cnt+1;elsecnt<=0;reg timeout;
always@(posedge clk or negedge rst_n)if(!rst_n)timeout<=0;else if(cnt>=500000)timeout<=1;elsetimeout<=0;

定义一个计数到9ms、4.5ms、560us、1690us的标志信号。因为有一定的延迟或者其他原因取这些时间的一个范围。


reg flag_9ms;
reg flag_4_5ms;
reg flag_5_6us;
reg flag_1_6_9ms;
always@(posedge clk or negedge rst_n)if(!rst_n)flag_9ms<=0;else if(cnt>400000 && cnt<495000)flag_9ms<=1;elseflag_9ms<=0;always@(posedge clk or negedge rst_n)if(!rst_n)flag_4_5ms<=0;else if(cnt>152500 && cnt<277500)flag_4_5ms<=1;elseflag_4_5ms<=0;always@(posedge clk or negedge rst_n)if(!rst_n)flag_5_6us<=0;else if(cnt>20000 && cnt<35000)flag_5_6us<=1;elseflag_5_6us<=0;always@(posedge clk or negedge rst_n)if(!rst_n)flag_1_6_9ms<=0;else if(cnt>75000 && cnt<90000)flag_1_6_9ms<=1;elseflag_1_6_9ms<=0;

根据帧头数据与数据波形对接收波形采用状态机进行实现.

s_idle为空闲状态,等待接收信号的下降沿。

s_flag_9ms为识别9ms的低电平引导码。

s_flag_4_5ms为识别4.5ms的低电平引导码。

s_get_data为读码状态

reg [3:0] state;
localparam s_idle      =4'b0001;
localparam s_flag_9ms  =4'b0010;
localparam s_flag_4_5ms=4'b0100;
localparam s_get_data  =4'b1000;reg get_flag_done;

在空闲状态检测到接收信号下降沿跳转下一个状态,并开始使能计数,否则保持在空闲状态。第二个状态开始的时候使能计数,检测到上升沿的时候并且9ms的标志信号为高就开始跳转下一个状态,并让计数器清零,下一个状态重新开始计数,如果没有检测到9ms的标志信号继续等待。第三个状态类似。最后一个状态刚开始的时候使能计数,如果检测到上升沿并且560us的标志信号为低,或者检测到下降沿并且560us的标志信号与1690us的表示信号为低,表明接收数据有误,返回初始状态,数据接收成功后也返回初始状态。如果检测到上升沿并且560us的标志信号为高,或者如果检测到下降沿并且560us的标志信号与1690us的标志信号都为高,计数器清零。根据下图就可以很轻松设计出来。

always@(posedge clk or negedge rst_n)if(!rst_n)beginstate<=s_idle;en_cnt<=0;endelse if(!timeout)case(state)s_idle       :   if(nedge)beginstate<=s_flag_9ms;en_cnt<=1;endelse beginstate<=state;en_cnt<=0;ends_flag_9ms  :  if(pedge)beginif(flag_9ms)beginstate<=s_flag_4_5ms;en_cnt<=0;endelse state<=s_idle;end  else beginstate<=state;en_cnt<=1;ends_flag_4_5ms:   if(nedge)beginif(flag_4_5ms)beginstate<=s_get_data;en_cnt<=0;endelsestate<=s_idle;end   else beginstate<=state;en_cnt<=1;ends_get_data  :   if(pedge && !flag_5_6us)state<=s_idle;else if(nedge && (!flag_5_6us && !flag_1_6_9ms))state<=s_idle;else if(get_flag_done)state<=s_idle;else if(pedge && flag_5_6us) en_cnt<=0;else if(nedge && (flag_1_6_9ms || flag_5_6us)) en_cnt<=0;elseen_cnt<=1;endcaseelsebeginen_cnt<=0;state<=s_idle;end

最后对数据进行接收,在读码状态如果数据计数到32,解码完成标志信号拉高,数据计数清零,根据上图,如果检测到下降沿,数据计数加一,在检测到下降沿的同时如果1690us的标志信号为高表明解码到数据1,如果560us的标志信号为高表明解码到数据0。

data_temp为总共的数据位数,iraddr为地址,irdata为数据,协议规定先发送低位。所以现将地址位从低位到高位开始发送,再将数据位从低位到高位开始发送。

reg [5:0] data_cnt;
reg [31:0] data_temp;
assign irdata=data_temp[31:16];
assign iraddr=data_temp[15:0];
always@(posedge clk or negedge rst_n)if(!rst_n)begindata_cnt<=0;data_temp<=0;get_flag_done<=0;endelse if(state==s_get_data)beginif( data_cnt==32)beginget_flag_done<=1;data_cnt<=0;endelse beginif(nedge)data_cnt<=data_cnt+1;if(nedge && flag_5_6us)data_temp[data_cnt]<=0;else if(nedge && flag_1_6_9ms)data_temp[data_cnt]<=1;get_flag_done<=0;endend
assign get_flag=get_flag_done;

仿真验证

将模块进行例化

`timescale 1ns/1ns
`define clk_period 20module ir_decode_tb;reg               clk;reg             rst_n;reg               iIR;wire    [15:0]irdata;wire   [15:0]iraddr;wire           get_flag;ir_decode ir_decode(.clk(clk),.rst_n(rst_n),.iIR(iIR),.irdata(irdata),.iraddr(iraddr),.get_flag(get_flag)
);

iIR空闲状态为1,发送地址为1数据为 32和地址为2数据为22

initial clk=0;
always #(`clk_period/2) clk=~clk;initial beginrst_n=0;iIR=1;#(`clk_period*10+1)rst_n=1;#2000;send_data(1,8'h32);#60000000;send_data(2,8'h22);#60000000;$stop;
end

这里先说明一个小语法,task的用法,定义一个任务。

task task_demo;                //任务定义结构开头,命名为 task_demo
    input  [7:0] x,y;           //输入端口说明
    output [7:0] tmp;           //输出端口说明

begin

end

endtask

任务调用方法,其中端口1,端口2为参数。

task_demo(端口1,  端口 2, ........,  端口 N);

发送引导码, 9ms的低电平和4.5ms的高电平。然后发送数据发送,560us的低电平之后拉高,之后如果iIR是1就延时1690us,否则延迟560us。

integer i;
task send_data;
input   [15:0] addr;
input [7:0] data;
beginiIR=0;#9000000;iIR=1;#4500000;for(i=0;i<=15;i=i+1)beginiIR=0;#560000;iIR=1;if(addr[i])#1690000;else#560000;endfor(i=0;i<=7;i=i+1)beginiIR=0;#560000;iIR=1;if(data[i])#1690000;else#560000;endfor(i=0;i<=7;i=i+1)beginiIR=0;#560000;iIR=1;if(~addr[i])#1690000;else#560000;endiIR=0;#560000;iIR=1;end
endtask

仿真结果

issp调试

新建issp的ip核,在顶层模块中例化,将工程下载到板子上。

module decode_top(input              clk,input               rst_n,input             iIR,output  [15:0]irdata,output [15:0]iraddr,output         get_flag);issp  issp(.probe({irdata,iraddr}),.source()
);ir_decode ir_decode(.clk(clk),.rst_n(rst_n),.iIR(iIR),.irdata(irdata),.iraddr(iraddr),.get_flag(get_flag)
);endmodule

打开issp,将数据改为16进制,选择连续抓取,按下按键0,可以看到抓取的数据。

HT6221红外遥控解码设计相关推荐

  1. 基于51单片机 的红外遥控解码设计

    红外线遥控在生活中有着广泛的应用,比如空调,电视,音响,机顶盒等.红外线遥控实际上就是一种通信方法,利用LED发射红外线,接收器接收到数据,进行处理后就可以得到发送端的信号.利用一个简单的红外线发光二 ...

  2. 基于FPGA的红外遥控解码与PC串口通信

    基于FPGA的红外遥控解码与PC串口通信 zouxy09@qq.com http://blog.csdn.net/zouxy09 这是我的<电子设计EDA>的课程设计作业(呵呵,这个月都拿 ...

  3. 遥控窗帘c语言程序,基于单片机的红外遥控窗帘设计论文(含c语言源程序) 本科毕业论文(设计).doc...

    基于单片机的红外遥控窗帘设计论文(含c语言源程序) 本科毕业论文(设计) 摘 要 随着电子技术和自动化技术的发展,人们对生活质量的要求越来越高.家用电器产品也在不断的更新换代.从始初的晶体管.到电子管 ...

  4. 遥控窗帘c语言程序,基于单片机的红外遥控窗帘设计论文(含c语言源程序) 本科毕业论文.doc...

    基于单片机的红外遥控窗帘设计论文(含c语言源程序) 本科毕业论文 摘 要 随着电子技术和自动化技术的发展,人们对生活质量的要求越来越高.家用电器产品也在不断的更新换代.从始初的晶体管.到电子管:由模拟 ...

  5. 红外遥控C语言程序设计,光电红外遥控开关设计(光电系统课程设计)【PCB图仿真图单片机C语言分工心得】..doc...

    光电红外遥控开关设计(光电系统课程设计)[PCB图仿真图单片机C语言分工心得]. 本科生课程论文 论文题目光电红外遥控开关设计课程名称光电系统设计学生姓名学号所在学院所在班级指导教师 目 录 摘要3 ...

  6. 万能遥控程序c语言,51单片机万能红外遥控解码程序

    51hei单片机论坛里流传的遥控解码程序现在都弱爆了根本解不了现在的遥控自己写个万能红外遥控解码 本程序中需要用的头文件下载:http://www.51hei.com/mcu/2564.html // ...

  7. 基于51单片机+红外遥控解码+LCD1602显示

    红外遥控解码(NEC) 基本介绍 什么是红外线? 红外线系统的组成 发射管和接收管 红外遥控发射(载波频率) 重要介绍 NEC协议 数据格式(必看) 位定义(必看) 编写程序思路(2种) 方式一 方式 ...

  8. 实战篇:基于HT6221的红外遥控解码实现

    本次主要实现红外遥控解码模块的实现,红外模块发送端采用的是HT6221的编码芯片,而在接收端由于红外对管,生成的正好是与发送端电平相反的信号.要实现解码模块程序编写,需先知道协议的过程以及编码的格式, ...

  9. 学习型红外遥控器设计(3) 红外遥控解码学习

    学习型红外遥控器设计(0) 摘要   (1) 绪论  (2) 方案设计   (3) 遥控解码   (4) 编码还原  (5) 硬件实现   (6) 总结展望 如方案设计所述,制作红外接收解码装置,该装 ...

最新文章

  1. 一加7充电_夜话丨一加7超级快充明天见
  2. 艾伟_转载:C# Design Patterns (4) - Proxy
  3. 杭电 hdu 1003
  4. Spring Cloud Netflix—如何加入Hystrix
  5. 纯java应用搭建,16、BoneCp纯java项目使用
  6. LeetCode MySQL 1225. 报告系统状态的连续日期(date_sub + over)
  7. java webtable_java winform开发:JTable详解
  8. 百度视频播放器android,百度视频播放器
  9. xshell5字体大小调整
  10. 打印服务器后台程序没有运行,win10遇到“打印后台程序服务没有运行”的解决方法...
  11. 耿建超英语语法---陈述句(1)
  12. 【AGC031E】Snuke the Phantom Thief(费用流)
  13. postgres用户管理及权限控制--赋予某账号只读权限
  14. potplayer录制视频包含字幕
  15. 解决idea上传文件到svn频繁报错 “Error:Node remians in conflict”、“remains in conflict”
  16. 社会治理网格化新华三移动IT助江西铺设综合治理“一张网”
  17. eclipse安装STS插件失败
  18. 波产生衍射的原因是什么
  19. Centos-7游戏服务器环境部署(上)
  20. 前方高能!用java写自动售货机的程序

热门文章

  1. 7-20 电话聊天狂人
  2. 华为云服务器如何搭建微信公众号后台-收发文本信息?
  3. C语言求老师及其夫人的年龄
  4. B站里的宝藏UP主你知道多少?
  5. python的celery的面试_Python面试经验总结,面试一时爽,一直面试一直爽!
  6. 华为IPsec预共享密钥配置命令汇总
  7. 华为HMS Scankit 扫码SDK集成-实现扫一扫功能
  8. ios 旋转屏幕试图切换_iOS屏幕横竖屏切换
  9. 【Laravel系列7.3】Session与响应
  10. Linux操作(vi编辑器)