http://blog.ednchina.com/yicheng/177861/message.aspx
1.实验设备<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
(1) 硬件:PC机,EasyFPGA030实验板,红外接收头,遥控器(具体型号下面介绍)
(2) 软件:Libero
2.应用的器件
(1)红外接收头
(2)遥控器:本文使用的遥控器内部芯片为HS6221。
3.实验内容
遥控器使用方便,应用广泛,同时具有长远的发展前景,因此本实验想通过红外接收在FPGA中的应用来说明红外的个别工作原理,希望通过举一反三,使读者能够对红外遥控熟练掌握。
4.实验原理
本文使用的遥控器内部使用的芯片为HS6221,因此着重针对其的原理来展开说明,同时据业内人士介绍,很多的数字机顶盒的遥控都适用的。
首先介绍一下接收头,由于是接收、放大一体化,所以接收性能还是比较理想的。实物如下图:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
仔细观察一下引脚的排列,只有地,5V电源,数据端,安装十分方便。
硬件就这么简单,接下来就是程序的编写了,当然还要先知道遥控发射数据的格式,然后就是一个相反的过程。
遥控器发射的信号由一串0和1的二进制代码组成。不同的芯片对0和1的编码有所不同。通常有曼彻斯特编码和脉冲宽度编码。HS6221的0和1采用PWM方法编码,即脉冲宽度调制,<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />0码由0.56ms低电平和0.565ms高电平组合而成,脉冲宽度为1.125ms。1码由0.56ms低电平和1.69ms高电平组合而成。脉冲宽度为2.25ms。在编写解码程序时,通过判断脉冲的宽度,即可得到0或1。
HS6221以及同类的芯片的数据格式包括引导码(起始码),用户码(地址码),用户反码(地址反码),数据码,数据反码,编码总共32位,数据反码是数据码反相后的编码,用户反码原理一样,可以用来对数据的纠错。具体格式如下:
当我们按下遥控器的按键时,遥控器将发出如上图的一串二进制代码,我们称它为一帧数据。根据各部分的功能。可将它们分为5部分,分别为引导码、用户码、用户反码、数据码、数据反码。遥控器发射代码时,均是低位在前。高位在后。由图中分析可以得到,引导码高电平为9ms,低电平为4.5ms,当接收到此码时,表示一帧数据的开始。FPGA可以准备接收下面的数据。地址码由8位二进制组成,共256种,图中用户反码主要是加强遥控器的可靠性,不同的设备可以拥有不同的地址码。因此,同种编码的遥控器只要设置地址码不同,也不会相互干扰。在同一个遥控器中,所有按键发出的地址码都是相同的。数据码为8位,可编码256种状态,代表实际所按下的键。数据反码是数据码的各位求反,通过比较数据码与数据反码,可判断接收到的数据是否正确。如果数据码与数据反码之间的关系不满足相反的关系,则本次遥控接收有误,数据应丢弃。在同一个遥控器上。所有按键的数据码均不相同。
上面对工作原理粗略的介绍了一下,虽然只停留于理论层面,但这个原理可是放于四海皆准,经过本人实验,无论是单片机还是ACTEL、ALTERA的FPGA都是十分适用。下面给出是程序代码:
//**************************IR_CTRL.V*****************************************************
//模块名称:IR_CTRL.V
//功能描述:红外接收模块
//适用范围:HS6221,HS6222,CS6121,包含引导码,地址码,地址反码,数据码,数据反码
//
//版权声明:
// (1)本代码属个人知识产权,保留最终解析权。
// (2)本代码仅供交流学习,未经本人同意不能用于其它用途。
//
//_______________________________________________________________________________
//
// Created by: YI CHENG
// QQ: 506009199
// Email: fsyicheng@21cn.com
// Created date: 2008-10-29
// Version: 1.1
//********************************************************************************
module IR_CTRL(clk,IR,OUTDATA,led);
input clk; //系统时钟
input IR; //红外接收
output OUTDATA; //beel
output [7:0]led; //指示LED
//reg OUTDATA;
assign OUTDATA="IR"; //beel
reg led1;
reg led2;
reg led3;
reg [7:0]led;
//--------------------------------------------------------------------
reg [14:0]divcnt;
reg divclk;
reg [2:0]state;
reg [6:0]cnt;
reg [31:0]datatemp; //数据寄存器
reg [4:0]bitcnt; //位计算器
reg ok_flag; //接收完成
//----------------------------------------------------------------------
parameter guide_down=3'b000, //引导码
guide_up=3'b001,
num_down=3'b010, //数据码接收
num_up=3'b011,
key=3'b101,
num_judge=3'b100; //0,1判断状态机
//-----------------------------------------------------------------------------
always@(posedge clk) //0.125ms
begin
if(divcnt==15'd3000) //50MHz 3125
begin //48MHz 3000
divclk=~divclk;
divcnt=0;
end
else
begin
divcnt=divcnt+1'b1;
end
end
//-------------------------------------------------------------------------------
always @(posedge divclk)
begin
case(state)
guide_down:
begin
if(IR==0)
begin
cnt<=cnt+1'b1;
ok_flag<=0;
end
if(IR==1)
begin
if(cnt>7'd50 && cnt<7'd90)
begin
cnt<=0;
state<=guide_up;
end
else
begin
cnt<=0;
state<=guide_down;
end
end
end
guide_up:
begin
if(IR==1)
begin
cnt<=cnt+1'b1;
end
if(IR==0)
begin
if(cnt>7'd26 && cnt<7'd46)
begin
cnt<=0;
state<=num_down;
end
else
begin
cnt<=0;
state<=guide_down;
end
end
end
key:
begin
state<=num_down;
cnt<=0;
end
num_down:
begin
if(IR==0)
begin
cnt<=cnt+1'b1;
end
if(IR==1)
begin
if(cnt<7'd6)
begin
cnt<=0;
state<=num_up;
end
else
begin
cnt<=0;
state<=guide_down;
end
end
end
num_up:
begin
if(IR==1)
begin
cnt<=cnt+1'b1;
end
if(IR==0)
begin
if(cnt<7'd15)
begin
state<=num_judge;
end
else
begin
cnt<=0;
state<=guide_down;
end
end
end
num_judge:
begin
if(cnt<7'd6)
begin
datatemp[bitcnt]<=0;
cnt<=0;
if(bitcnt==5'd31)
begin
state<=guide_down;
bitcnt<=0;
ok_flag<=1;
end
else
begin
bitcnt<=bitcnt+1'b1;
state<=num_down;
end
end
else
begin
datatemp[bitcnt]<=1;
cnt<=0;
if(bitcnt==5'd31)
begin
state<=guide_down;
bitcnt<=0;
ok_flag<=1;
end
else
begin
bitcnt<=bitcnt+1'b1;
state<=num_down;
end
end
end
default:state<=guide_down;
endcase
end
//-----------------------------------------------------------------------------
always@(posedge ok_flag)
begin
case(datatemp)
32'hF50AF708: //ON/OFF
begin
led<=8'b00000001;
end
32'hE01FF708: //左右声道
begin
led<=8'b00000010;
end
32'hF40BF708: //消声
begin
led<=8'b00000011;
end
32'hFE01F708: //1
begin
led<=8'b00000100;
end
32'hFD02F708: //2
begin
led<=8'b00000101;
end
32'hFC03F708: //3
begin
led<=8'b00000110;
end
32'hFB04F708: //4
begin
led<=8'b00000111;
end
32'hFA05F708: //5
begin
led<=8'b00001000;
end
32'hF906F708: //6
begin
led<=8'b00001001;
end
32'hF807F708: //7
begin
led<=8'b00001010;
end
32'hF708F708: //8
begin
led<=8'b00001011;
end
32'hF609F708: //9
begin
led<=8'b00001100;
end
32'hFF00F708: //0
begin
led<=8'b00001101;
end
32'hBA45F708: //节目表
begin
led<=8'b00001110;
end
32'hEF10F708: //清除
begin
led<=8'b00001111;
end
32'hF10EF708: //返回
begin
led<=8'b00010000;
end
32'hBF40F708: //喜爱
begin
led<=8'b00010001;
end
32'hE718F708: //菜单
begin
led<=8'b00010010;
end
32'hB748F708: //退出
begin
led<=8'b00010011;
end
32'hEA15F708: //ok
begin
led<=8'b00010100;
end
32'hEE11F708: //up
begin
led<=8'b00010101;
end
32'hED12F708: //down
begin
led<=8'b00010110;
end
32'hEC13F708: //left
begin
led<=8'b00010111;
end
32'hEB14F708: //right
begin
led<=8'b00011000;
end
32'hF30CF708: //音量+
begin
led<=8'b00011001;
end
32'hB946F708: //音量-
begin
led<=8'b00011010;
end
32'hF00FF708: //频道+
begin
led<=8'b00011011;
end
32'hE817F708: //频道-
begin
led<=8'b11111100;
end
default:;
endcase
end
endmodule
上面的代码均加有注释,因此不再重复讲述,如有疑问欢迎联系本人,大家相互讨论。
把上面的代码放到你自己的实验平台上就可以使用,特别提醒的就是注意一下系统的工作时钟,本人使用的EasyFPGA030板上是48M,ALTERA的1C6是50M,因此上面提供了两种时钟方案,只要稍微修改一下就可以通用了。
5.上电实验
把程序下载到实验板上(注意管脚配置),当你按不同的按键,实验板上的LED就会显示不同的状态,同时蜂鸣器会发出不同的声音,至此实验就证明成功了,当然你可以通过遥控去控制其他的仪器。
6.实验总结
实验的难度一般,同时采用了较多的顺序思维,说透一点,就是把单片机的程序搬到FPGA上来,而且,如果比较熟悉单片机的话,可以先用单片机来验证原理的有效性,然后就可以直接把思想保留,修改语言,适应对应的平台就可以了。
附:
如果你曾使用过FUSION的话,那你更方便,因为FUSION可以嵌入MCU的软核,然后使用普通的MCU程序就可以运行了,相比其他的SOPC平台,其优点显而易见。
下例预告:
下例的内容初定为红外线测障,如果有兴趣的朋友可以提出自己的意见以及方案,本人希望通过网络等交流平台,与大家一起共同学习,交流,实现“分享传递价值”的理念,助人自助,提升自我,实现双赢。
联系方式:
QQ: 506009199
EMAIL: fsyicheng@21cn.com
用户212563 2010-2-5 11:53
用户513348 2009-1-1 15:40
用户1485490 2008-12-1 10:02
用户1532875 2008-11-17 10:55
用户1448907 2008-11-13 07:52
用户18411 2008-11-13 07:52
用户1532875 2008-11-5 09:33
用户461316 2008-11-4 16:00
用户46900 2008-4-30 22:02
echo2005 2008-3-31 14:55