红外线遥控接收器设计.docx
- 文档编号:30083840
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:23
- 大小:288.05KB
红外线遥控接收器设计.docx
《红外线遥控接收器设计.docx》由会员分享,可在线阅读,更多相关《红外线遥控接收器设计.docx(23页珍藏版)》请在冰豆网上搜索。
红外线遥控接收器设计
红外线遥控接收器
一、题目要求
数字系统课程设计包括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)模块源程序:
--ANALYZE.VHD
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityanalyzeis
port(
clk:
instd_logic;--时钟信号
datain:
instd_logic;--串行输入信号
reset:
instd_logic;--复位信号
keyin4:
instd_logic_vector(3downto0);--键盘输入信号
code:
outstd_logic_vector(4downto0);--解码后的编码,可输入CD4511显像
led:
outstd_logic;--彩灯控制信号,用于区分单击/连续键
user:
outstd_logic_vector(2downto0);--用户端信号
beep:
outstd_logic);--蜂鸣信号
endanalyze;
architecturebehavofanalyzeis
typestatetypeis(s0,s1,s2,s3,s4,action);
signalstate:
statetype;
constantbeeptime:
integer:
=80;
begin
st:
process(clk,datain)
variablecnt1,cnt2,cnt3:
integerrange0to30;--定义三个计数器:
cnt1是收到0的个数
variablereg:
std_logic_vector(11downto0);--cnt2是收到1的个数cnt3控制响铃时间
variabletemp:
std_logic_vector(4downto0);
variabletempled:
std_logic;
begin
----------------------------------------------------------------------------------------------------------------------
--检测键盘输入和开始远程端接收部分,设置为遥控发射器优先
ifreset='1'then--复位,进入s0状态
state<=s0;code<="00000";led<='1';user<="111";
elsifrising_edge(clk)then
casestateis
whens0=>
ifdatain='0'then
reg:
="000000000000";templed:
='1';temp:
="00000";--若接收到遥控器发出的低--电平即开始启动计数器
cnt1:
=0;cnt2:
=0;cnt3:
=0;--计数器、寄存器和数据暂存器清零
state<=s1;
elsifkeyin4="0111"then--当键盘输入为"1"时
code<="00001";beep<='1';led<='1';user<="111";
elsifkeyin4="1011"then--当键盘输入为"2"时
code<="00010";beep<='1';led<='1';user<="111";
elsifkeyin4="1101"then--当键盘输入为"3"时
code<="00011";beep<='1';led<='1';user<="111";
elsifkeyin4="1110"then--当键盘输入为"4"时
code<="00100";beep<='1';led<='1';user<="111";
else
state<=s0;beep<='0';led<='1';
endif;
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--译码部分,检测发射端的发射信号
whens1=>--扫描发射器是否有输出低电平
ifdatain='0'then--如果收到低电平那么转到s2状态并启动计数器cnt1
state<=s2;
else
state<=s1;--否则继续检测
endif;
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
whens2=>
ifdatain='0'then--收到一个低电平就计数一次
cnt1:
=cnt1+1;
state<=s2;
elsifdatain='1'then--如果收到一个高电平表明收到一位数此时停止计数器cnt1
state<=s3;--并进入状态2启动计数器cnt2,开始计已收到多少位数
endif;
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
whens3=>
cnt2:
=cnt2+1;--cnt2计算已收到多少位数
--以7为分界线,区分出收到的数是0还是1
ifcnt1<7then--如果收到的低电平数少于7个则表明收到的是0
reg:
=reg(10downto0)&'0';--此时将0存入12位的移位寄存器中
else--若收到的低电平数大于或等于7,则收到的是1
reg:
=reg(10downto0)&'1';--此时将1存入12位的一位寄存器中
endif;
ifcnt2=12thenstate<=s4;--如果计数器cnt2的计数值为12,--表明已经接收完一个发射码
elsecnt1:
=0;--否则将cnt1清零以后继续检测收到的数
state<=s1;
endif;
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
--译码部分,对译码之后的信号进行相应的译码输出
whens4=>
beep<='1';
casereg(8downto0)is
when"100100000"=>temp:
="00001";--1
when"100010000"=>temp:
="00010";--2
when"100001000"=>temp:
="00011";--3
when"100000100"=>temp:
="00100";--4
when"100000010"=>temp:
="00101";--5
when"100000001"=>temp:
="00110";--6
when"010100000"=>temp:
="00111";--7
when"010010000"=>temp:
="01000";--8
when"010001000"=>temp:
="01001";--9
when"010000100"=>temp:
="10000";--10
when"010000010"=>temp:
="10001";--11
when"010000001"=>temp:
="10010";--12
when"001100000"=>temp:
="10011";--13
when"001010000"=>temp:
="10100";--14
when"001001000"=>temp:
="10101";--15
when"001000100"=>temp:
="10110";--16
when"001000010"=>temp:
="10111";--17
when"001000001"=>temp:
="11000";--18
whenothers=>temp:
="00000";
endcase;
user<=reg(11downto9);--移位寄存器的前三位是用户码
templed:
=notreg(8);--可以用12位接收码的第4位(H)作为连续键的标志
state<=action;--位来区分其他单击键,将其取反后作为连续键指示灯的输入
----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
whenaction=>--响应状态
led<=templed;--led信号输出给连续键指示灯控制其亮灭
code<=temp;
cnt3:
=cnt3+1;--每翻译出一个码,响铃计数器cnt3就计数一次
ifcnt3=beeptimethen--计数到设定的时间后,铃声不再响跳到初始状态
beep<='0';--检测下帧数据(一帧数据是12位码)
state<=s0;
else
state<=action;
endif;
whenothers=>
state<=s0;
endcase;
endif;
endprocessst;
endbehav;
(5)仿真图:
a)键盘直接输入(遥控器不按下时)的仿真图:
由上图可知,当顺序循环按下键盘上的1~4号按键时,可以看到经解码模块解码后得到的对应输出编码分别为“00001”,“00010”,“00011”,“00100”;响铃信号为高电平,铃响;单击/连续指示信号为低电平,灯不亮。
用户码为“111”。
由此可知,解码结果正确。
b)遥控器连续按键(1~6)中按下“1”时的仿真图:
由以上的仿真图可知,当按下连续键“1”时,接收到的编码是“11110010000”,经解码模块解码后输出的BCD码为“00001”;此时单击/连续指示灯led为低电平,灯亮;响铃信号为高电平,铃响;用户码为“111”。
由此可知,解码结果正确。
c)遥控器单击按键(7~18)中按下“10”时的仿真图:
由以上的仿真图可知,当按下单击键“10”时,接收到的编码是“111010000100”,经解码模块解码后输出的BCD码为“10000”;此时单击/连续指示灯led为高电平,灯灭;响铃信号为高电平,铃响;用户码为“111”。
由此可知,解码结果正确。
二、输出显示模块:
(1)分析
译码模块输入的5位BCD译码信号做为数码管的控制芯片CD4511的ABCD端,来控制数码管显示键码。
因为只有一个CD4511来控制数码管的显示,所以最难就在于如何解决两位键码的同时显示问题。
由于系统时钟为8Khz,如果按系统时钟的频率来反复动态扫描数码管,通过片选信号“bit”去点亮所选择的数码管,令其反复显示两位数,由于人眼对影像有滞后性,所以看上去就像是两位数同时显示一样。
这样就解决了两位数的显示。
(2)显示模块源程序:
--DISPLAY.VHD负责各显像管的显示
libraryieee;
useieee.std_logic_1164.all;
entitydisplayis
port(code:
instd_logic_vector(4downto0);--翻译出的编码
clk:
instd_logic;--时钟信号
bit:
outstd_logic_vector(1downto0);--片选信号,选中需要显示的那只数码管
num:
outstd_logic_vector(3downto0)--编码输入CD4511
);
enddisplay;
architecturebehavofdisplayis
begin
process(clk)
variablea:
std_logic;-定义a变量使两只数码管的显示变化与系统时钟一致
begin
ifrising_edge(clk)then
a:
=nota;
ifa='0'then
num<="000"&code(4);--显示十位数
bit<="10";--选通第一个数码管
else
num<=code(3downto0);--显示个位数
bit<="01";--选通第二个数码管
endif;
endif;
endprocess;
endbehav;
(3)仿真图:
由上图可知,若要显示的数为“2”(其BCD码为00000010),其中显示十位的数码管显示“0”,显示个位的管显示“2”,而且在BIT信号的控制下,两只数码管的转换良好。
其他数也显示正常,由此可知,显示模块可以将翻译出来的编码正常地显示。
三、系统主模块
(1)主模块源程序
将以上两个模块元件例化到主模块中来,得到主模块源程序如下:
--MAIN.VHD主模
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 红外线 遥控 接收器 设计
![提示](https://static.bdocx.com/images/bang_tan.gif)