数字系统课程设计 红外线遥控接收器.docx
《数字系统课程设计 红外线遥控接收器.docx》由会员分享,可在线阅读,更多相关《数字系统课程设计 红外线遥控接收器.docx(35页珍藏版)》请在冰豆网上搜索。
数字系统课程设计红外线遥控接收器
数字系统
课程设计报告
第一部分设计题目及要求
本次课程设计的题目及要求如下:
一、设计题目
红外线遥控接收器
二、设计步骤
1、EDA实验板组装调试
参照提供的EDA实验板电路原理图、PCB图以及元器件清单进行电路板的组装。
电路板组装完成后,编写三个小程序进行电路板测试。
2、红外遥控系统的设计
(1)发射编码部分
使用指定的元器件在万用板上完成红外遥控器的制作。
(2)接收解码部分
接收解码用VHDL语言编写程序,在EDA实验板上实现解码。
二、功能要求
1、将一体化红外接收解调器的输出信号解码(12个单击键、6个连续键,单击键编号为7-18,连续键编码为1-6),在EDA实验板上用七段数码管显示出来。
2、当按下遥控器1—6号连续键时,在EDA实验板上用发光二极管点亮作为连续键按下的指示,要求遥控器上连续键接下时指示灯点亮,直到松开按键时才熄灭,用于区别单击键。
3、EDA实验板上设置四个按键,其功能等同于遥控器上的1—4号按键,当按下此四个按键时七段数码管分别对应显示“1”、“2”、“3”、“4”。
4、每当接收到有效按键时,蜂鸣器会发出提示音。
第二部分设计分析
本次课程设计包括两大部分,一是电路设计及电路焊接,二是程序的设计及编写。
电路部分,根据题目要求,要做到红外发送,显然整个电路系统要分为红外发射和红外接收两个电路,分别做到红外的编码发射和译码接受,再在接收板上显示接受到的红外信号。
另外还包括一个从电脑下载程序到芯片上的下载线电路。
一、红外发射电路
本次课程设计的红外遥控器由红外遥控专用芯片PT2248作为编码及发送部分,PT2248最大可用作18路红外遥控系统的编码,其内部己集成了38kHz的红外载波振荡及相应的数字脉码调制电路,只需外接3×6的矩阵式按键、红外发光二极管及其驱动电路等少量元器件便可完成编码发送的功能。
由PT2248和少量外围元件组成的红外遥控发射电路如下图所示
芯片的发送指令由12位码组成,其中C1~C3是用户码,可用来确定不同的模式。
用户码设定是以列线内接入二极管为界线,当T1~T3与CODE之间分别接入二极管时,用户码(C1~C3)为“1”;当T1~T3引脚不接二极管时,用户码为“0”。
如果该芯片与BL9150相结合,则C3引脚必须接入二极管;如果该芯片与BL9149相结合,则C2必须接二极管,H、S1和S2是代表连续发送或单次发送的码,且分别与T1、T2和T3列的键对应。
D4~D6是发送的数据码(也是键输入码)
上图中3V电源电压一方面为芯片提供推荐工作电压并加到引脚16,另一方面作为信号输出指示复合管的工作电压。
为了使振荡频率为455kHz,特采用外接晶振,并外接两个电容120pF旁路到地。
图7中三列T1、T2、T3和CODE分别接一个二极管,目的是为了使用户码(C1、C2、C3)为“1”。
二、红外接受部分
本次课程设计的红外接受部分采用EDA实验板,EDA实验板的顶层PCB图如下:
.
硬件部分的设计:
板的中心部件采用的是max7000系列CPLD,另外采用4M晶振以及红外接收管(38K接收头)直接在逻辑箱制作红外接收解码电路。
红外接收管有3个管脚,自左至右分别是信号输出端,地端,电源端,分别接到逻辑箱的相应管脚上;同时,为了得到更加稳定的信号,在信号输出端与地端加入一滤波电容。
三,下载线电路
本次课程设计采用的下载线把电脑的打印机口和实验板的数据口连接起来,从而把程序从电脑下载到实验板的芯片里,如下图:
下载线电路采用芯片74LS244构成下载线电路,电路图如下:
下载线电路板的顶层PCB图如下:
第三部分系统模块的划分以及各模块的功能描述
在这一部分,我将对系统功能进行模块化划分,对各模块功能作详细阐述。
一、发射板部分
发射板主要由红外线编码芯片PT2248构成红外编码这个模块。
PT2248的管脚图如下图所示:
其各个管脚的功能如下表:
PT2248组成的十八路遥控发送器其编码规则如下:
(1)设a为一个时间单位,时间长度是38kHz的16个时钟周期,即
a=1÷38kHz×16=0.421ms
编码是以串行形式发送的,在接收端(38kHz一体化红外接收解调器)接收到如下形式的1位的编码时分别表示“0”和“1”:
1个a的低电平,3个a的高电平表示编码“0”
3个a的低电平,1个a的高电平表示编码“1”
编码以串行形式发送,接收端的一体化红外接收解调器输出波形如下图所示:
此外,由于发射器发送的时候,有两个信号,一种是表示单击的,一种则是表示连续的,这两种不同的信号,其自身都有自己的特点:
(2)遥控器的每个按键编码由12位按以上编码规则所代表的“0”、“1”组成,时间长度为48a,当按下遥控器的7到18号单击按键,则以12位为一组(48a)发送两次编码,如下图所示:
60a为自按下按键到发送编码的等待时间,80a是前后两次发送12位48a编码的高电平时间间隔。
7到18号单击按键无论发送端按键时间持续多长只发送一次这样形式的两组相同的12位编码。
(3)当按下1到6号连续按键时,编码按如下格式连续发送:
由上图可以清楚的看到,两种信号的巨大差别,可是在程序的编写过程中,这种差别却没有什么很大的作用,因为两种信号在译码上的区别也是相当明显的,故为了简化程序,直接由译码来区别连续单击比利用上图的效果更好,具体见程序。
(4)芯片的发送指令由12位码组成,如下所列。
其中C1~C3是用户码,可用来确定不同的模式。
用户码设定是以列线内接入二极管为界线,当T1~T3与CODE之间分别接入二极管时,用户码(C1~C3)为“1”;当T1~T3引脚不接二极管时,用户码为“0”。
具体每个12位的串行编码规则如下:
C1、C2、C3为用户可通过在遥控器发射电路中是否接入IN4148二极管决定其为“0”或“1”,这里取“111”,H、S1、S2为单击连续按键的标志位,相当于列坐标,D1至D6为按键输入码,相当于行坐标,低9位的按键编码如下表所示:
按键
低9位编码
H
S1
S2
D1
D2
D3
D4
D5
D6
1
1
0
0
1
0
0
0
0
0
2
1
0
0
0
1
0
0
0
0
3
1
0
0
0
0
1
0
0
0
4
1
0
0
0
0
0
1
0
0
5
1
0
0
0
0
0
0
1
0
6
1
0
0
0
0
0
0
0
1
7
0
1
0
1
0
0
0
0
0
8
0
1
0
0
1
0
0
0
0
9
0
1
0
0
0
1
0
0
0
10
0
1
0
0
0
0
1
0
0
续上表:
二,接收部分
接收部分电路主要可分为红外接受模块,译码电路模块,小键盘模块和数码管显示模块几个部分,红外信号的编码从发射板发射到接收板上的红外信号接收头后,译码电路把红外编码翻译后送到数码管显示,小键盘输入的代码也经译码电路在数码管上显示对应的按键信息。
(一).红外信号接受
本课程设计的红外接受头采用一体化红外接收解调器,如下图:
其引脚图如下:
一体化红外接收解调器的内部电路如下图:
上面详述的红外信号发射电路把发射板上的按键信息编成编码以红外信号的形式发射到接收板,该一体化红外接收解调器接收到红外信息后,把其包含的编码信息传到下一级译码电路,从而完成红外信号的接收。
当红外接收头接收到遥控器发出的信号时,逻辑箱上的蜂鸣器需发出提示声。
因设计时只考虑译码器具有最简单的译码功能,这样就要求前面的编码电路在每发出一串12位编码的同时发出一个脉冲给计数器,使计数器输出为高电平,同时开始计数,直至计数到规定值后又回到低电平,完成响铃提示。
(二)红外编码译码电路
根据芯片介绍可知,红外接收头接收到的编码,每一帧完整的串行数据有十二位,而每一位的BIT‘0’、BIT‘1’是占空比不同的矩形方波,要完成以后的功能,就需要一个编码器将其编成逻辑器件能识别的普通逻辑电平‘0’、‘1’。
红外接收头接收负责接收38k载波的红外光,解调得到脉冲,输出至译码电路。
接收头接收到的脉冲如图(与发射波形刚好互为反码):
(a为38kHz时钟的16个周期)
每个按键的值由12bit组成:
按键编码格式:
译码电路有把对应的译码程序下载后的CPLD构成,CPLD的外围电路如下图:
CPLD和芯片74HC4040以及其他元件构成译码电路,74HC4040的管脚图如下图所示:
其内部电路图如下图:
一体化红外接收解调器接收到红外信息后,将红外编码通过73HC4040传到CPLD进行译码。
(三)红外编码显示电路
这部分电路将译码后得到的十二位普通高低电平‘0、’‘1’编码译成相应的压缩BCD码1~18,应十位仅有0、1两种可能,将译得的BCD码直接接芯片4511的输入引脚,4511的译码输出并接到4位LED数码显示管,再在程序中写入十位和个位选择的进程,即可得到相应1~18数字显示输出。
显示部分电路由芯片CD4511BC构成,译码后的高低电平从CPLD的44,45,46,48,49管脚传输到CD4511BC,进行译码,这部份电路如下:
CPLD的33——41角分别接到三级管(8050)Q2——Q9,通过段路线,选择两个四位LED数码显示管里的共八位显示中的哪一位或哪几位显示,没有接段路线的那些位的显示管将不亮。
CD4511BC的管脚图如下图所示:
其真值表及对应的LED数码显示管显示如下:
(四)小键盘电路
EDA实验板上有个4*4的按键矩阵,当按键被按下时,其输出引脚为低电平,而其余时间内均为高电平。
当按下每一行的四个键时,七段码显示管应显示1—4,必须将四个按键并行输入的按键编码转换成1—4的BCD码才能输出显示。
按键输入与遥控输入应共用两个七段码显示管输出,这样就需要在程序中将输入的遥控信号与按键信号先进行选择再输出。
这部分电路如下图所示:
第四部分程序设计及带注释源程序
一、本次课程设计的程序设计的ASM图如下:
二、程序设计时的主要部分以及遇到的问题及解决方案:
1、频率的同步问题:
这是本程序的一个关卡,由于信号的载波是16k,而晶振的频率采用了4M,就是说无论怎么分频,逻辑箱出来的频率都不可能得到载波信号的频率,所以有可能经过几次解码之后便出现误码。
本设计具体采用的处理措施如下:
4M的2的7次方分频(没有安装word的公式,请见谅哦),所得到一个信号(即4个a)为14倍clk,这里用到一个cnt1,每个时钟上升沿计数一次,计数到第7个时钟上升沿时,便进行读数,根据0和1波形的特点,可知在此时输入信号infared_in与其真正表示的值相反,故有:
ifcnt1=7thenreg2<=reg2(7downto0)¬txout;
endif;
在第14个clk后,剩下的0.2个clk将产生误码,故采取以下措施:
whenT1=>
ifcnt1=50then
cnt1<=0;
state<=T0;
else
cnt1<=cnt1+1;
endif;
计到第14个clk时(由于其中经过两个状态,所以计数只计到12),又回到T0,重新检测infared_in=‘0’后回到T1状态,从而取出那0.2个clk的影响。
2)如何判断接收到一串完整的12位数据问题:
如果采用cnt1计数来控制的话,会导致cnt1的取值过大,而且会出现误差时间的积累,故本程序用到的第二个计数器cnt2,其作用也不容小视,在每一次cnt1=7时,都会将cnt2自加,如下:
Ifcnt1=7then
cnt2<=cnt2+1;
reg<=reg(7downto0)¬infared_in;
endif;
ifcnt2=12then
cnt2<=0;
speaker<='1';
endif;
这是用来记录移入寄存器reg的次数,计到12时,说明已经接收了1个完整的信号了,此时把cnt2清零,以便下一次接收信号时使用。
3)指示灯跟蜂鸣器的问题:
当接收一个完整的信号之后,当让就是对这存在reg中的一串01代码进行译码了,同时根据题目要求,蜂鸣器要相应的响一声。
故当cnt2=12时sound赋为高电平,并启用第三个计数器cnt3,cnt3在下一个时钟上升沿开始自加,加至16000,即延时16000/16k=1秒后停止,后将sound从新赋0。
具体实现如下:
ifcnt2=12then
cnt2<=0;
speaker<='1';
endif;
ifspeaker='1'then
cnt3<=cnt3+1;
ifcnt3=16000then
cnt3<=0;
speaker<='0';
endif;
endif;
4、EDA板上的按键问题:
EDA试验板的按键的每一行的四个按键分别对应B1,B2,B3,B4,具体实现只是在时钟上升沿下加入一下程序段即可。
ifB1='0'then
reg<="100100000";
endif;
ifB2='0'then
reg<="100010000";
endif;
ifB3='0'then
reg<="100001000";
endif;
ifB4='0'then
reg<="100000100";
endif;
二、源程序
综合上面所讨论的几点,可的得到本次课程设计的源程序(带注释)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityinfaredis
port(clk,infared_in,B1,B2,B3,B4,reset:
instd_logic;
--B1.B2.B3.B4为实验版上4*4键盘每一行对应的4个按键
--infared_in为红外接收头接收并解码输出的信号
BCD_out:
outstd_logic_vector(3downto0);
--芯片输出到4511的经红外编码后的12位按键码对应的4位代码
selet:
outstd_logic_vector(1downto0);
--数码显示管十位和个位的选择信号
led,speaker:
bufferstd_logic);
--连续键的指示灯信号,按键按下即蜂鸣器信号
endinfared;
architecturebehavofinfaredis
typestate_typeis(s0,s1,s2);
signalstate:
state_type;
signalreg:
std_logic_vector(8downto0);
signalcnt1:
integerrange0to14;
--0,1解码计数器。
对0的个数的计数,遇到0则开始计数,遇到1就停止,以区别0和1的编码
signalcnt2:
integerrange0to12;
--输入的编码位数计数器,计数到到12就把编码输出到infared_in
signalcnt3:
integerrange0to16000;
--蜂鸣器延时计数器
signalcnt4:
integerrange0to1;
--个位十位选择计数器,为0时数码管显示个位,为1显示十位
begin
judge:
process(clk,infared_in,cnt1)
--进程1,判断是否接受到低电平,红外接受低电平有效,infared_in=0时表示有编码输入
begin
ifclk'eventandclk='1'then
casestateis
whens0=>ifinfared_in='0'then
state<=s1;
else
state<=s0;
--检测输入信号,如果是高电平则继续检测;如果为低电平则进入状态s1
endif;
whens1=>ifcnt1=12then
cnt1<=0;
state<=s2;
elsecnt1<=cnt1+1;
--计数到12时,跳到s2状态,继续检测低电平
endif;
whens2=>
ifinfared_in='1'then
--若出现高电平则跳回s0状态
state<=s0;
else
state<=s2;
endif;
endcase;
endif;
--当计数到7时,自动跳到进程com2,每接收完一个完整的0或1信号后,自动接收下一个信号,自身不停地在两个状态中轮换。
endprocessjudge;
coding:
process(clk,cnt1,cnt2,cnt3,B1,B2,B3,B4)
--编码译码进程
begin
ifclk'eventandclk='1'then
ifB1='0'then
reg<="100100000";
--B1按下,寄存器储存表示00000001的代码。
endif;
ifB2='0'then
reg<="100010000";
--B2按下,寄存器储存表示00000010的代码。
endif;
ifB3='0'then
reg<="100001000";
--B3按下,寄存器储存表示00000011的代码。
endif;
ifB4='0'then
reg<="100000100";
--B4按下,寄存器储存表示00000100的代码。
endif;
ifcnt1=7then
cnt2<=cnt2+1;
--cnt2加1,表示移入一位数据
reg<=reg(7downto0)¬infared_in;
endif;
--当计数到7时,将接收到的infared_in的相反值移入寄存器。
ifcnt2=12then
--当cnt2计数到12时,表示接收到了完整的一串数据,自身清零并开启蜂鸣器
cnt2<=0;
speaker<='1';
endif;
ifspeaker='1'then
cnt3<=cnt3+1;
ifcnt3=16000then
cnt3<=0;
speaker<='0';
--计数cnt3计到16000时赋0,蜂鸣器停止,即蜂鸣器鸣响时间持续16000/16k=1秒后停止
endif;
endif;
endif;
endprocesscoding;
display:
process(clk,reg,reset)
--显示进程。
低9位编码转换成对应的BCD输出,1-6连续按键灯亮,7-18单击键灯灭,
begin
if(reset='1')then--高电平复位
BCD_out<="0000";
selet<="11";
led<='1';
--若按下复位键,十位个位同时显示0,指示灯亮
elsif(clk'eventandclk='1')then
led<='1';
caseregis
when"100100000"=>BCD_out<="0001";--显示1
selet<="01";
led<='0';
when"100010000"=>BCD_out<="0010";--显示2
selet<="01";
led<='0';
when"100001000"=>BCD_out<="0011";--显示3
selet<="01";
led<='0';
when"100000100"=>BCD_out<="0100";--显示4
selet<="01";
led<='0';
when"100000010"=>BCD_out<="0101";--显示5
selet<="01";
led<='0';
when"100000001"=>BCD_out<="0110";--显示6
selet<="01";
led<='0';
when"010100000"=>BCD_out<="0111";--显示7
selet<="01";
led<='1';
when"010010000"=>BCD_out<="1000";--显示8
selet<="01";
led<='1';
when"010001000"=>BCD_out<="1001";--显示9
selet<="01";
led<='1';
--连续键时led赋为高电平,灯亮;sel赋值''01''表示采用个位显示
when"010000100"=>if(cnt4=0)then
cnt4<=cnt4+1;
BCD_out<="0000";--个位显示0
selet<="01";
elsecnt4<=0;
BCD_out<="0001";--十位显示1
selet<="10";
endif;
--两位数利用计数器cnt4实现个、十位轮流显示。
when"010000010"=>if(cnt4=0)then
cnt4<=cnt4+1;
BCD_out<="0001";--个位显示1
selet<="01";
elsecnt4<=0;
BCD_out<="0001";--十位显示1
selet<="10";
endif;
when"010000001"=>if(cnt4=0)then
cnt4<=cnt4+1;
BCD_out<="0010";--个位显示2
selet<="01";
elsecnt4<=0;
BCD_out<="0001";--十位显示1
selet<="10";
endif;
when"001100000"=>if(cnt4=0)then
cnt4<=cnt4+1;
BCD_out<="0011";--个位显示3
selet<="01";
elsecnt4<=0;
BCD_out<="0001";--十位显示1
selet<="10";
endif;
when"001010000"=>if(cnt4=0)then
cnt4<=cnt4+1;
BCD_out<="0100";--个位显示4
selet<="01";
el