当前位置:文档之家› 红外线遥控接收器设计

红外线遥控接收器设计

一、题目要求数字系统课程设计包括EDA实验板组装调试及红外遥控系统设计制作两个部分,各部分要求如下:红外遥控系统由发射编码和接收解码两个部分组成,本课程设计要求制作发射编码电路板(遥控器)以及编写程序在EDA实验板上实现接收解码,具体说明如下:1、发射编码部分发射编码部分要求使用指定的元器件在万用板上完成红外遥控器的制作,该部分电路原理图参照《PT2248数据手册》,制作前请详细阅读《红外遥控器制作说明》,制作时要求元器件在万用板上排列整齐,布局合理,焊接良好,各按键功能正常,均能发送编码。

2、接收解码部分接收解码用VHDL语言编写程序,在EDA实验板上实现解码,要求具有以下功能:(1)基本要求:(a)将一体化红外接收解调器的输出信号解码(12个单击键、6个连续键,单击键编号为7-18,连续键编码为1-6),在EDA实验板上用七段数码管显示出来;(b)当按下遥控器1—6号连续键时,在EDA实验板上用发光二极管点亮作为连续键按下的指示,要求遥控器上连续键接下时指示灯点亮,直到松开按键时才熄灭,用于区别单击键。

(c)EDA实验板上设置四个按键,其功能等同于遥控器上的1—4号按键,当按下此四个按键时七段数码管分别对应显示“1”、“2”、“3”、“4”。

(d)每当接收到有效按键时,蜂鸣器会发出提示音。

(2)扩展功能:(能完成的加分)通过遥控器跳线改变用户码,EDA实验板上用三个发光二极管正确显示发送端的用户码。

二、解题分析根据题目意思,此设计关键在于如何将接收器接收到的信号解码并显示。

这是本设计的难点所在。

其中解码的信号来源有两种,分别是:一、从键盘上直接按键输入。

二、从遥控器上按键以后将信号发射出去,然后键盘上的接收器将其接收。

这当中有一个优先权的问题,在本次设计中我将其设置为遥控器接收优先,即,当在按下键盘后,若此时遥控也按下则显示数码管优先显示遥控器按下的信号。

接收解码红外编码信号并成功解码以后,需要将解码出来的相应信息(用户码,连续键等)进行显示!经分析实际的电路原理图,发现在控制数码管显示只有一个4511去控制,这说明一次只能显示一个数码,因此如何显示两位数码是数码管控制的难点所在!这时应该编写一个专门的模块来解决这个问题。

三、设计方案为了实现题目中的要求,程序采用单进程并将系统划分为下列两个模块:一、接收编码信号及翻译模块二、输出显示模块各模块功能描述:接收编码信号及翻译模块:该模块的主要功能是接收从键盘或者从遥控器发出的信号,将其翻译成可以让CD4511用来控制数码管显示的编码。

输出显示模块:输出显示模块主要是对两个数码显像管的输出进行控制,该模块根据翻译出的BCD码,将此编码输入到CD4511驱动显像管循环显示。

系统结构框图:说明:1、CLK是的系统时钟信号。

2、DATAIN是38kHz一体化红外接收解调器输入到CPLD中的串行信号。

3、RESET是系统复位信号,高电平有效。

4、KEYIN4是小键盘输入的信号。

5、BIT指示选中的数码管6、NUM是数码管个位或十位的BCD码7、BEEP是控制蜂鸣器信号,根据电路原理图,其低电平有效8、USER是三位的用户码9、LED是LED灯控制信号,用来显示用户码和连续键注:两个模块间相连的CODE信号是翻译出来后的五位的BCD码。

详细设计思路:一、接收编码信号及翻译模块:(1)分析解码原理:(一)键盘输入解码:该模块中接收编码信号分为从键盘接收信号和从遥控器接收信号,本程序设置为从遥控器发射优先。

从键盘接收到的信号直接翻译对应的二进制编码然后再输出到显示模块。

(二)遥控器发射信号解码:如何解码是本次设计的关键。

发射端编码方式已经在“附录一”中给出,要接收发射端发射的编码最关键的地方是解决发射段频率和接收段频率不一致的问题。

发射端频率为38KHz,程序中设计的接收端频率为2.048MHz的2的8次方分频,分出来以后即为8KHz。

发射端每四个周期(4a)代表一个二进制编码,时间为1/38KHz*16*4=1.684ms,四个周期的时间换算成接收端周期数为 1.684ms/(1/8KHz)=13.47个。

一个a所占的周期数为13.47/4=3.37个,三个a共占的周期数为13.47/4*3=10.1个。

由于编码中一个周期的低电平代表“1”,三个周期的低电平代表“0”。

如下形式的1位的编码时分别表示“0”和“1”:1个a的低电平,3个a的高电平表示编码“0”3个a的低电平,1个a的高电平表示编码“1”再考虑到同步的问题,取(10.1+3.37)/2=6.7 7作为判断“0”、“1”的分界线,即当检测到连续收到等于或超过7个接收端周期的低电平后即可认为接收到的是“1”,否则为“0”。

以上就是解码的基本原理。

翻译出编码信号后根据编码的规则,分析用户码和所应显示的数字即可。

(2)解码的具体流程:从“附录一”中的说明可知,按下一个按键将会发送出去一串编码,而无论是连续信号还是单发信号,接收的波形中有用部分仅其中的十二位码,且其中的H、S1、S3位已经能名区分单发与连续信号,为节约资源,只需对接收信息中的十二位码进行编码即可。

而从接收到的波形图可看出,仅当接收有编码时才有低电平,其余时间均为高电平。

这样就可从低电平开始,对BIT‘0’和BIT‘1’进行编码。

而BIT‘0’和BIT‘1’的区别在于其占空比不同,可以考虑用这样一个计数器cnt1:在低电平时被启动开始计数,当计数器的输入变为高电平时停止计数,这时可以比较计数值的大小。

根据以上“分析解码原理”中分析可知:当计数值大于或等于7时编码为“1”,否则编码为“0”。

这样便完成一位编码的接收,照此方法继续接收其他编码。

当接收到的编码位数满足12位时,表明按下一个键发射的编码已被解码完毕,此时即可输出一串完整的翻译后的编码。

这就需要一个计数值上限为12的计数器cnt2来指示接收到的编码位数,以此来控制编码的输出。

当接收到一个有效按键后在显示的同时还需要用响铃来提示,可以考虑预设一个上限值为常量的计数器cnt3来控制响铃时间。

本程序用状态机来完成这些功能,其ASM图如下,图中各个状态的说明如下:S0:复位等待状态,键盘输入状态,低电平检测计数器cnt1、编码位数计数器cnt2和响铃时间计数器cnt3清零,12位移位寄存器清零,响铃标志位输出为低电平。

因为设置为遥控器接收优先,所以此时若接收到遥控器发射的信号则转入遥控器发射信号解码状态,否则就进行键盘输入解码。

S1:接收信号有低电平,转入S2状态低电平检测计数器开始计数,否则继续检测是否有低电平。

S2:低电平检测计数器cnt1开始计数,检测低电平时间长度,当检测到输入信号为高电平时,计数器停止工作并转入下一状态。

S3:编码位数计数器cnt2加‘1’,计算已收到多少位编码。

并且以7为分界线,检测到输入信号为BIT‘1’,则12位移位寄存器向前移一位,最低位并入一个‘1’;检测到输入信号为BIT‘0’,则12位移位寄存器向前移一位,最低位并入一个‘0’。

当编码计数器达到计数上限12,表明已经接收到一个完整的12位编码,跳入下一状态开始译码。

S4:译码部分,对解码之后的信号进行相应的译码输出。

ACTION:响应状态,接收并翻译完一个按键信号后,指示器开始作出响应:单击/连续指示器信号输出,用户码输出,响铃计数器cnt3开始计数直到预设值才停止。

然后复位。

(3)ASM图:(4)模块源程序:--ANAL YZE.VHDlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity analyze isport (clk : in std_logic; --时钟信号datain : in std_logic; --串行输入信号reset : in std_logic; --复位信号keyin4 : in std_logic_vector(3 downto 0); --键盘输入信号code : out std_logic_vector(4 downto 0); --解码后的编码,可输入CD4511显像led : out std_logic; --彩灯控制信号,用于区分单击/连续键user : out std_logic_vector (2 downto 0); --用户端信号beep : out std_logic ); --蜂鸣信号end analyze;architecture behav of analyze istype statetype is (s0, s1, s2, s3, s4,action);signal state : statetype ;constant beeptime : integer := 80 ;beginst: process (clk,datain)variable cnt1,cnt2,cnt3 : integer range 0 to 30; --定义三个计数器:cnt1是收到0的个数variable reg : std_logic_vector(11 downto 0); --cnt2是收到1的个数cnt3控制响铃时间variable temp : std_logic_vector (4 downto 0);variable templed : std_logic;begin---------------------------------------------------------------------------------------------------------------------- -- 检测键盘输入和开始远程端接收部分,设置为遥控发射器优先if reset= '1' then --复位,进入s0状态state <= s0; code <= "00000"; led <= '1'; user <="111";elsif rising_edge (clk) thencase state iswhen s0 =>if datain = '0' thenreg:="000000000000"; templed:= '1'; temp:="00000"; --若接收到遥控器发出的低--电平即开始启动计数器cnt1:=0; cnt2:=0; cnt3 := 0; --计数器、寄存器和数据暂存器清零state <= s1;elsif keyin4 = "0111" then --当键盘输入为"1"时code <= "00001"; beep<='1'; led <= '1'; user <="111";elsif keyin4 = "1011" then --当键盘输入为"2"时code <= "00010"; beep<='1'; led <= '1'; user <="111";elsif keyin4 = "1101" then --当键盘输入为"3"时code <= "00011"; beep<='1'; led <= '1'; user <="111";elsif keyin4 = "1110" then --当键盘输入为"4"时code <= "00100"; beep<='1'; led <= '1'; user <="111";elsestate <= s0;beep<='0';led <= '1';end if;---------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------- --译码部分,检测发射端的发射信号when s1 => --扫描发射器是否有输出低电平if datain = '0' then --如果收到低电平那么转到s2状态并启动计数器cnt1 state <= s2;elsestate <= s1; --否则继续检测end if;---------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------when s2 =>if datain = '0' then --收到一个低电平就计数一次cnt1:=cnt1 + 1;state <= s2;elsif datain='1' then --如果收到一个高电平表明收到一位数此时停止计数器cnt1 state <= s3; --并进入状态2启动计数器cnt2,开始计已收到多少位数end if;---------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------when s3 =>cnt2:=cnt2 + 1; --cnt2计算已收到多少位数--以7为分界线,区分出收到的数是0还是1 if cnt1 < 7 then --如果收到的低电平数少于7个则表明收到的是0reg:=reg(10 downto 0) & '0'; --此时将0存入12位的移位寄存器中else --若收到的低电平数大于或等于7,则收到的是1reg:=reg(10 downto 0) & '1'; --此时将1存入12位的一位寄存器中end if;if cnt2 = 12 then state <= s4; --如果计数器cnt2的计数值为12,--表明已经接收完一个发射码else cnt1:= 0 ; --否则将cnt1清零以后继续检测收到的数state <= s1;end if;---------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------- --译码部分,对译码之后的信号进行相应的译码输出when s4 =>beep <= '1' ;case reg(8 downto 0) iswhen "100100000" =>temp := "00001";-- 1when "100010000" =>temp := "00010";-- 2when "100001000" =>temp := "00011";-- 3when "100000100" =>temp := "00100";-- 4when "100000010" =>temp := "00101";-- 5when "100000001" =>temp := "00110";-- 6when "010100000" =>temp := "00111";-- 7when "010010000" =>temp := "01000";-- 8when "010001000" =>temp := "01001";-- 9when "010000100" =>temp := "10000";--10when "010000010" =>temp := "10001";--11when "010000001" =>temp := "10010";--12when "001100000" =>temp := "10011";--13when "001010000" =>temp := "10100";--14when "001001000" =>temp := "10101";--15when "001000100" =>temp := "10110";--16when "001000010" =>temp := "10111";--17when "001000001" =>temp := "11000";--18when others =>temp := "00000";end case;user <= reg(11 downto 9); --移位寄存器的前三位是用户码templed := not reg(8); --可以用12位接收码的第4位(H)作为连续键的标志state <= action ; --位来区分其他单击键,将其取反后作为连续键指示灯的输入---------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------when action => --响应状态led <= templed; --led信号输出给连续键指示灯控制其亮灭code <= temp;cnt3 := cnt3+1; --每翻译出一个码,响铃计数器cnt3就计数一次if cnt3 = beeptime then --计数到设定的时间后,铃声不再响跳到初始状态beep <= '0'; --检测下帧数据(一帧数据是12位码)state <= s0 ;elsestate <= action ;end if;when others =>state <= s0;end case;end if;end process st;end behav;(5)仿真图:a)键盘直接输入(遥控器不按下时)的仿真图:由上图可知,当顺序循环按下键盘上的1~4号按键时,可以看到经解码模块解码后得到的对应输出编码分别为“00001”,“00010”,“00011”,“00100”;响铃信号为高电平,铃响;单击/连续指示信号为低电平,灯不亮。

相关主题