88 点阵汉字滚动显示.docx
《88 点阵汉字滚动显示.docx》由会员分享,可在线阅读,更多相关《88 点阵汉字滚动显示.docx(12页珍藏版)》请在冰豆网上搜索。
88点阵汉字滚动显示
VHDL/EDA实习报告
设计题目:
基于FPGA的8*8点阵汉字滚动显示
设计者:
孙建章
学号:
15号
班级:
电子10-1
指导老师:
赵玉刚
实习时间:
2013/3/11~21
FPGA设计的特点
FPGA通常被认为是ASIC实现的一种替代手段.一般ASIC包括三种,既全定制、半定制(含标准单元和门阵列)以及可编程器件。
对于前两种,需要支付不可重复使用的工程费用NRE(NonrecurringEngineering),主要用于芯片的流片、中测、分析的工程开销,一次费用一般在1万至数万美元以上。
如果一次不成功、返工、甚至多次返工,NRE费用将要上升。
成本高、风险大,而通常对每个ASIC品种的需求量往往不大,NRE费用分摊到每个产品上价太高,用户无法接受。
而对于可编程器件PLD(ProgrammableLogicDevice)正是可以解决上述问题的新型ASIC,PLD以其操作灵活、使用方便、开发迅速、投资风险小等突出优点,特别适合于产品开发初期、科研样品研制或小批量的产品.FPGA是一种新型的PLD,其除了具有PLD的优点外,其规模比一般的PLD的规模大。
目前,Xilinx推出的XC4025可以达到25000门的规模,Altera公司的FLEX10K100系列芯片可达到十万门的规模,完全可以满足用户的一般设计需要。
FPGA的主要特点是:
寄存器数目多,采用查找表计数,适合时序逻辑设计。
但是互连复杂,由于互连采用开关矩阵,因而使得延时估计往往不十分准确。
FPGA也有其自身的局限性,其一就是器件规模的限制,其二就是单元延迟比较大。
所以,在设计者选定某一FPGA器件后,要求设计者对器件的结构、性能作深入的了解,在体系结构设计时,就必须考虑到器件本身的结构及性能,尽可能使设计的结构满足器件本身的要求.这样就增加了设计的难度。
离开对FPGA结构的详细了解,设计人员就不可能优化设计。
因而设计人员必须了解FPGA器件的特性和限制,熟悉FPGA的结构。
在了解FPGA结构特点的基础上,就可以利用VHDL语言描写出高效的电路描述实现性能优化的电路。
设计的主要工作
本设计需要利用EDA工具软件QuartusII编写并调试系统的VHDL程序。
并且每一个模块都在这个软件下进行了仿真。
系统的VHDL程序编好过后先在实验室的EDA实验箱上下载调试,成功过后再根据电路焊接相应的电路板。
最好将程序下载到制好的电路上验证。
设计任务与要求
(1)在8*8LED发光二极管点阵上由右至左的方向滚动显示多个汉字
(2)使用FPGA芯片实现硬件设计,并提供后置配置方案
(3)建立描述滚动显示多汉字信息原理的数学模型。
输出预定义“北华电子”
设计原理
LED点阵原理
以下为8×8点阵LED外观及引脚图及其等效电路,只要其对应的X、Y轴顺向偏压,即可使LED发亮。
例如如果想使左上角LED点亮,则Y0=1,X0=0即可。
应用时限流电阻可以放在X轴或Y轴。
点阵LED扫描法介绍
点阵LED一般采用扫描式显示,实际运用分为三种方式:
(1)点扫描
(2)行扫描
(3)列扫描
若使用第一种方式,其扫描频率必须大于16×64=1024Hz,周期小于1ms即可。
若使用第二和第三种方式,则频率必须大于16×8=128Hz,周期小于7.8ms即可符合视觉暂留要求。
此外一次驱动一列或一行(8颗LED)时需外加驱动电路提高电流,否则LED亮度会不足。
8×8扫描LED点阵的工作原理同8位扫描数码管类似。
它有8个共阴极输出端口,每个共阴极对应有8个LED显示灯,所以其扫描译码地址需3位信号线(SEL0-SEL2),其汉字扫描码由16位段地址(0-8)输入。
通过时钟的每列扫描显示完整汉字。
设计方案
方案一
8×8扫描LED点阵只要其对应的X、Y轴顺向偏压,即可使LED发亮。
例如如果想使左上角LED点亮,则Y0=1,X0=0即可。
应用时限流电阻可以放在X轴或Y轴。
它有8个共阴极输出端口,每个共阴极对应有8个LED显示灯。
本实验就是要通过芯片产生读时序,将字形从寄存器中读出,然后产生写时序,写入8×8的点阵,使其扫描显示输出。
为了显示整个汉字,首先分布好汉字的排列,以列给出汉字信息(从8个Y轴线输入字模信息);然后以128HZ的时序逐个点亮每一行(行扫描),即每行逐一加高电平,根据人眼的视觉残留特性,使之形成整个汉字的显示。
LED点阵每个点都有一个红色的发光二极管。
点阵内的二极管间的连接都是行共阳,列共阴(要点亮的二极管给出低电平字模信息)。
本实验采用共阴,当二极管的共阳极为高电平,共阴极为低电平时,所接点发光;反之处于截止状态,不放光。
本实验采取行扫描方式,用列给文字信息,利用周期为1s的脉冲来控制所显示的字。
汉字的存储
用动态分时扫描技术使LED点阵模块显示图像,需要进行两步工作。
第一步是获得数据并保存,即在存贮器中建立汉字数据库。
第二步是在扫描模块的控制下,配合行扫描的次序正确地输出这些数据。
获得图像数据的步骤是,先将要显示的每一幅图像分成8×8共64个小方格的矩形框中,再在有笔划下落处的小方格里填上“1”,无笔划处填上“0”,这样就形成了与这个汉字所对应的二进制数据在该矩形框上的分布,再将此分布关系以32×16的数据结构组成64个字节的数据,并保存在只读存贮器ROM中。
以这种方式将若干个汉字的数据贮存在存贮器内,就完成了图像数据库的建立工作。
汉字显示
汉字显示使用的是8×8的点阵,EDA实验箱上有其接口电路,列选信号为SEL0,SEL1,SEL2经4线8线译码器输出8列,从左起为第一列,列选信号是由一个3位向量SEL[2..0]控制;行选信号为H0~H7,是由8个行信号组成的,每一行由一个单独的位来控制,高电平有效。
例如“0000”表示第0列,“00000001”表示第一行的点亮。
由于列是由一个向量决定,而每一时刻的值只能有一个固定的值,因而只能使某一列的若干个点亮,因此就决定了只能用逐列扫描的方法。
例如要使第一列的2,4,6,8,行亮,则列为“001”、行为“10101010”就可以实现了。
下面是各个部分的程序设计
列循环扫描
通过对每一列的扫描来完成对字母的现实,只要扫描的频率足够快,就能给人以连续的感觉。
因此要控制扫描的频率,不能太低,否则,就会造成视觉上的不连续,本设计的扫描频率不得低于50Hz,扫描程序如下:
Libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
Entitydz_xsis
Port(enable,clk:
instd_logic;--端口定义输入信号
Sel:
outstd_logic_vector(2downto0));--端口定义输出信号
Enddz_xs;
Architecturecountofdz_xsis
Signallie:
std_logic_vector(2downto0);
Begin
Process(clk,enable)--脉冲、使能信号
begin
Ifclk'eventandclk='1'then
Ifenable='1'then
Iflie>"000"then
Lie<=lie-"001";
Else
Lie<="111";
Endif;
Endif;
Endif;
Sel<=lie;
Endprocess;
字符样式设计
本环节是建立一个数据库,使之能在扫描的同时读取所需要的信息,从而完成汉字的显示。
本次设计“北、华”汉字样式设计(仅取前二字)程序如下:
Libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
Entitydz_xsis
Port(enable,clk:
instd_logic;--端口定义输入信号
h0,h8:
outstd_logic_vector(7downto0));--端口定义输出信号(h0-列数据输出,h8-代表行数据输出)
Enddz_xs;
Architecturecountofdz_xsis
Signallie:
std_logic_vector(3downto0);--信号标志
Signalpast1:
std_logic_vector(1downto0);
Begin
Process(enable,clk)--脉冲、使能信号
Begin
Ifclk'eventandclk='1'then
Ifenable='1'then
Caselieis
When"00"=>
Caselieis--“北”字设计
When"000"=>h0<="00001000";h8<="00010100";
When"001"=>h0<="10000100";h8<="00010100";
When"010"=>h0<="01000110";h8<="01111110";
When"011"=>h0<="01100000";h8<="00000000";
When"100"=>h0<="00000001";h8<="01111110";
When"101"=>h0<="00100000";h8<="01010000";
When"110"=>h0<="00100000";h8<="01010000";
When"111"=>h0<="00100000";h8<="01100000";
Endcase;
When"01"=>
Caselieis--“华”字设计
When"000"=>h0<="00100000";h8<="00010000";
When"001"=>h0<="00100011";h8<="00010100";
When"010"=>h0<="00100010";h8<="00011110";
When"011"=>h0<="00100010";h8<="11110001";
When"100"=>h0<="00100010";h8<="00011111";
When"101"=>h0<="00111111";h8<="00011010";
When"110"=>h0<="00100010";h8<="00011100";
When"111"=>h0<="00100010";h8<="00010000";
Endcase;
Whenothers=>h0<="00000000";h8<="00000000";
Endcase;
Endif;
Endif;
Endprocess;
为使字母不断地循环显示,并且使每个字母之间有停顿,就需要在中间加一定的延时和循环环节。
在这一环节中,可以通过修改其数值来控制每个字母的显示时间。
其程序如下:
process(clk)
variableint:
integerrange0to10000;
begin
ifclk’eventandclk=’1’then
ifint<10000then
int:
=int+1;
else
int:
=0;
ifnext1=”11”then
next1<=”00”;
else
next1<=next1+’1’;
endif;
endif;
endif;
endprocess;
方案一总结:
可能由于所学知识有限,基于模块化的方案一在仿真时没有成功,检查源程序也没发现问题,不得已采用了方案二。
方案二:
方案二没有采取模块化思想,而是每一次行扫描都需要整个的汉字信息,所以程序看起来比较冗繁。
源程序:
(用于汉字信息实在太多,所以这儿省略了中间的汉字信息)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entityled_dianzhengis
port(clk_1khz,clk_1hz:
instd_logic;
red:
outstd_logic_vector(2downto0);--定义列共阳红色输出控制端口red[7..0]
com:
outstd_logic_vector(7downto0));--定义行共阴输出控制端口com[7..0]
endled_dianzheng;
architecturebehaveofled_dianzhengis
signalst1,st2:
std_logic_vector(7downto0):
="11111110";--定义信号st1,st2
--signalosc:
std_logic;--定义信号osc
signalosd:
std_logic;--定义信号osd
signalclk:
std_logic;
signaldata:
std_logic_vector(7downto0);--定义信号data
signald0,d1,d2,d3,d4,d5,d6,d7:
std_logic_vector(7downto0);
signalcont:
std_logic_vector(4downto0);
SIGNALQ,cnt8:
std_logic_vector(2downto0);
begincom<=data;--把信号data赋值给行共阴输出控制端口com[7..0]
red<=cnt8;--把信号st1赋值给列共阳红色输出控制端口red[7..0]
------------------------
FenPin:
process(clk_1khz)
begin
ifclk_1khz'EVENTANDclk_1khz='1'then
ifQ="111"thenQ<=(OTHERS=>'0');
ELSEQ<=Q+'1';
endif;
endif;
endprocessFenPin;
clk<=Q(0);
-----------------
osd<=clk_1hz;
--------------------------
third:
process(osd)
begin
if(osd='1'andosd'event)then
ifcont="11110"then
cont<="00000";
elsecont<=cont+'1';
endif;
endif;
endprocessthird;
-------------------------------
P1:
process(clk)
begin
if(clk'eventandclk='1')then
casecnt8is
when"000"=>data<=d0;
when"001"=>data<=d1;
when"010"=>data<=d2;
when"011"=>data<=d3;
when"100"=>data<=d4;
when"101"=>data<=d5;
when"110"=>data<=d6;
when"111"=>data<=d7;
whenothers=>null;
endcase;
endif;
endprocessP1;
-----------------------------------
P2:
process(clk)
begin
ifclk'eventandclk='1'thencnt8<=cnt8+1;
endif;
endprocessP2;
----------------------------
process(cont)
begin
ifcont="00000"then
d0<="00010100";---------北0
d1<="00010100";---------北1
d2<="01111110";---------北2
d3<="00000000";---------北3
d4<="01111110";---------北4
d5<="01010000";---------北5
d6<="01010000";---------北6
d7<="01100000";---------北7
。
。
。
。
。
。
elsifcont="11011"then
d0<="00001001";---------子0
d1<="00001001";---------子1
d2<="01001001";---------子2
d3<="11111001";---------子3
d4<="00001101";---------子4
d5<="00001011";---------子5
d6<="00001001";---------子6
d7<="00000000";---------子7
endif;
endprocess;
endbehave;
程序电路图:
仿真波形图:
方案二总结:
由于方案二相比较方案一来说在结构上要简单些,所以在小组成员的共同努力下,方案二顺利完成,最终成功滚动显示汉字:
北华电子。
开发环境介绍
QuartusII是Altera公司的综合性PLD开发软件,支持原理图、VHDL、Veril-ogHDL以及AHDL(AlteraHardwareDescriptionLanguage)等多种设计输入形式,内嵌自有的综合器以及仿真器,可以完成从设计输入到硬件配置的完整PLD设计流程。
QuartusII支持Altera的IP核,包含了LPM/MegaFunction宏功能模块库,使用户可以充分利用成熟的模块,简化了设计的复杂性、加快了设计速度。
对第三方EDA工具的良好支持也使用户可以在设计流程的各个阶段使用熟悉的第三方EDA工具。
此外,QuartusII通过和DSPBuilder工具与Matlab/Simulink相结合,可以方便地实现各种DSP应用系统;支持Altera的片上可编程系统(SOPC)开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。
实习总结:
通过这一周的实习,让我在实践中学到了很多东西,也发现了很多问题。
让我认识到,有时候光靠书上的知识是远远不够的,很多时候还要考我们自己慢慢的去摸索。
在这个过程中让我意识到,善于借助身边的资源的重要性,比如:
有这方面知识的同学或者是上网去看看别人的实践过程,从别人的亲身经历获得的经验来帮助自己,这样能让自己少走一些弯路。
同时,也要感谢赵玉刚老师给我们提供了这么好的一次实践锻炼的机会,让我们从实践中获得了相关的知识,我相信这对我们以后的发展有很大的帮助。
总的来说,这次设计的8×8点阵显示控制还是比较成功的,在设计中遇到了很多问题,最后在老师的辛勤的指导下,终于解决问题,有点小小的成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更加清楚的认识,同时,对未来有了更多的信心。
最后,对给过我帮助的所有同学和指导老师再次表示忠心的感谢