微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 之三:红外小模块设计

之三:红外小模块设计

时间:10-02 整理:3721RD 点击:
之前在单片机上加过红外接头,感觉质量不是很好,这次刚好利用一下锆石FPGA板载的红外接头。发货套装里面的遥控器不知道被上一个人搞到哪里去了,手头上有一个友善的遥控器。接下来从代码到效果全面展示一下。


一、概述
首先要获取每个按键对应的编码输出。据说红外的发射频率都是38HKZ左右,那么由50MHZ信号源经过512分频的100Khz左右的时钟来对红外接头的输出进行采样,可以满足二倍频率关系。红外编码脉冲大概如下图:


在低电平高电平的引导码接收之后,通过32位保持时间或长或短的高电平来存储信息。经测试F2键和UP键盘的编码分别如下(令先发射的编码为高位):
11011100001000110101100010100111;
11011100001000111011000001001111;
测试采用signaltap。
二、基本原理
内部的主体是一个计数器,每个采样时钟来临的时候,如果连续为1,则计数器加1,当计数器值高于1000时就认为没有信号,内部复位;
当上一个信号是高而这一个信号是低,说明红外发射出了一个下降沿,此时对比计数结果,如果满足这是一个长电平,将code寄存器组的高位设为1,如果是低电平,设为0;同时code寄存器组的编号num改变,下一次计数之后填写的将是code寄存器组的下一位值。
最终,如果检测到上一个num是31,而当前num是0,说明32位编码全部输出,此时将flag设为1;另外一个always块检测到flag为1,则将code数组和所有键的键值对比,从而将某个键对应的输出位设为1,并在下一个时钟来临时将其设为0。整个模块对外的有效输出就是一个个上升沿。
三、代码及signaltap运行结果
//不再识别引导码;
module redline(
        input clk0,
        input en,
        input irda,
        output key_up,
        output key_f2);
       
        reg key_f2_0;
        reg key_up_0;
        reg [4:0]num;//用来标记现在记录的是第几个编号
        reg [4:0]num1;//原来的办法是num到了31就操作flag,可是由于num到了31后,还要经过数十个clk采样周期,flag会震荡,导致led闪不回去。
        reg [9:0]counter1;
        reg last_irda;
        reg [31:0]code;
       
        reg flag;//立个flag,如果num走到了倒数第一个,把flag立为1;此周期最后一位编码被读取,在下个周期读取编码并将flag复位;
        assign key_f2=key_f2_0;
        assign key_up=key_up_0;
        assign clk=clk0;
       
        always@(posedge clk)
        begin
                if((last_irda==1)&&(irda==1))
                        counter1 =160)&&(counter1 =50)&&(counter1 1000)
                        begin
                                counter1<=0;
                                num<=0;
                        end
                if ((num==0)&&(num1==31)&&(flag==0))flag<=1;
                else flag<=0;
                last_irda<=irda;
                num1<=num;
        end
//根据flag来判断是否识别编码;       
        always@(posedge clk)
        begin
                if(flag==1)
                begin
                        if(code==32'b11011100001000111011000001001111)
                                key_up_0<=1;
                        if(code==32'b11011100001000110101100010100111)
                                key_f2_0<=1;
                end
                else
                begin
                        key_f2_0<=0;
                        key_up_0<=0;
                end
        end
endmodule

module lab4(
        input ck0,
        input irda,
        output reg led1,
        output reg led2);
       
        reg clk;
        reg en=1;
        reg [7:0]counter;
        wire key_up;
        wire key_f2;
       
        always@(posedge ck0)
        begin
        counter<=counter+1;
        if(counter==0)clk<=~clk;
        end
       
        redline u1(clk,en,irda,key_up,key_f2);
        always@(posedge key_up)led1<=~led1;
        always@(posedge key_f2)led2<=~led2;
endmodule

四、一些说明
代码中没有对引导码进行检测的部分;红外模块设置了一个使能位,但是发现主模块里面单独的一个reg en=1和红外模块是连接不上的,所以就把红外模块里面的en有关项去掉了。
signaltap的采样资源受限于FPGA芯片。如果模块较小的话,可以采用最大的深度也就是2*64k segment,如果需要观测的节点比较多,需要调小一点,这里采用2*4k segment。
最后附上优酷视频效果:
https://v.youku.com/v_show/id_XMjk4NDk0NDczMg==.html?spm=a2hzp.8253869.0.0
10秒左右。

了解一下    我经常接触热释红外传感器

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top