2024年6月13日发(作者:)

实 验 报 告

实验名称: [

16X16点阵显示实验

]

姓 名:

学 号:

指导教师:

实验时间:

[2013年

6月15日]

信息与通信工程学院

16X16点阵显示实验

1、 实验要求:

理解并掌握点阵显示符号的原理,理解原有程序,会使用动态扫描的方式使点阵显示

汉字,明白点阵滚动显示的原理。根据原有程序,掌握LPM_ROM的应用,会应用LPM_ROM

存储需要显示的内容。参照液晶显示程序,编写16*16点阵显示程序。

任务一:实现点阵列扫描。点亮点阵的一列,并让其不断的向右移动。

任务二:在点阵上循环滚动显示“嵌入式系统设计”。

2、实验原理:

2.1点阵基本原理

本实验对点阵的扫描使用列扫描的方式。就是将要显示的数据分成16列,在某一时刻

只选中一列,并向点阵传送该列需要显示的数据,那么如果从左往右依次循环选中所有列,

并且循环的速度足够快,因为视觉停留效应,我们就能看到完整的显示了。

如果要显示大于16列的信息,比如要显示多个汉字,由于只能同时显示16列,那么就

需要在一个比较慢的时钟的指挥下,不断更新要显示的连续的16列数据,使用这样的方法

就能实现滚动显示。

2.2任务原理

8*8LED点阵共由64个发光二极管组成,每个发光二极管放置在行线和列线的交叉点上,

当对应的某一行高电平(置1),且某一列低电平(置0),则相应的发光二极管就亮;因此

要用8*8LED点阵来显示一个字符或汉字,只需要根据字符或汉字图形中的线条或笔画,通过

点亮多个发光二极管来勾勒出字符或汉字的线条或笔画就行了。

当要比较完美的显示一般的汉字,单个8*8LED点阵模块很难做到,因为LED的点数(也称为

像素点)不够多,因此要显示汉字的话,需要多个8*8LED点阵拼合成一个显示屏。假如用4

个8*8LED点阵模块拼成16*16的点阵,即能满足一般汉字的显示。

16×16扫描LED点阵的工作原理同8位扫描数码管类似。它有16个共阴极输出端口,

每个共阴极对应有16个LED显示灯,所以其扫描译码地址需4位信号线(SEL0-SEL3),其

汉字扫描码由16位段地址(0-15)输入。通过时钟的每列扫描显示完整汉字。

2.3、实验设计流程:

任务一系统结构图如图1所示。

图1 任务一系统结构图

任务二系统结构图如图2所示。

图2 任务二系统结构图

3.管脚分配

choose[3] PIN_139

choose[2] PIN_137

choose[1] PIN_134

choose[0] PIN_127

clk_50M PIN_23

data[15] PIN_46

data[14] PIN_44

data[13] PIN_41

data[12] PIN_39

data[11] PIN_35

data[10] PIN_33

data[9] PIN_30

data[8] PIN_15

data[7]

data[6]

data[5]

data[4]

data[3]

data[2]

data[1]

data[0]

l5

rst

sel[2]

sel[1]

sel[0]

4、实验结果:

PIN_13

PIN_11

PIN_10

PIN_8

PIN_6

PIN_5

PIN_4

PIN_3

PIN_142

PIN_56

PIN_146

PIN_145

PIN_144

使用QuartusII软件将实验工程分别下载到实验箱中,能够看到预期的现象:

将任务一的工程下载到实验箱后,可以看到一竖条向右移动,移动速度为1s每列。

将任务二的工程下载到实验箱后,点阵上滚动显示汉字“嵌入式系统设计”,字体移动

速度为0.34秒每列。

实验现象表明实验程序符合要求,能够完成实验要求任务。

5实验心得

通过这次实验,我学到了一个有时序功能的器件如何用verilog语言实现其功能。学

会了8*8LED点阵共由64个发光原理,要用8*8LED点阵来显示一个字符或汉字,只需要根

据字符或汉字图形中的线条或笔画,通过点亮多个发光二极管来勾勒出字符或汉字的线条或

笔画就行了。如何用点阵拼合成一个显示屏假如用4个8*8LED点阵模块拼成16*16的点阵,

即能满足一般汉字的显示。而16×16扫描LED点阵的工作原理同8位扫描数码管类似。它

有16个共阴极输出端口,每个共阴极对应有16个LED显示灯,所以其扫描译码地址需4位

信号线(SEL0-SEL3),其汉字扫描码由16位段地址(0-15)输入。通过时钟的每列扫描显

示完整汉字。并通过模块和模块的嵌套或者连接实现相应功能。

通过这次实验,学到了很多东西,同时也认识到了自己只是FPGA道路上的新手,还

有很多未知的知识需要学习。真正学习的历程需要在课下多努力,希望通过这学期的学习自

己能熟练掌握一些编程的技术,培养良好的思维模式。

6 参考文献

[1] 王金明. 《数字系统设计与Verilog HDL》第3版、第2版, 电子工业出版社, 2009、

2005. TP271/W24.

[2] 夏宇闻. 《Verilog数字系统设计教程》, 北京航空航天大学出版社, 第1、2版, 2008.

TP312VH/X31.

[3] 蒋璇,臧春华. 《数字系统设计与PLD应用技术》, 电子工业出版社, TP271/J63.

[4] 侯伯亨,顾新. 《VHDL硬件描述语言与数字逻辑电路设计》(修订版), 西安电子科技

大学出版社. TP312/H490.

[5] (美)John 威廉斯著; 李林,陈亦欧,郭志勇译. 《Verilog数字VLSI设计教程》, 电

子工业出版社. 2010.7.

[6] 潘松,黄继业. 《EDA技术实用教程》, 科学出版社, 2006. TN702/P18.

附录:程序清单

任务一:

module scan (clk_50M,rst,choose,data,sel,l5);

input clk_50M;

input rst;

output reg[3:0] choose;

output reg[15:0] data;

output wire[2:0] sel;

output wire l5;

assign sel=3'b010;

assign l5=1'b0;

// +++++++++++++++++++++++++++++++++++++

// 分频模块 开始

// +++++++++++++++++++++++++++++++++++++

reg scan_clk;

reg [40:0] count_div;

always @(posedge clk_50M)

begin

if(count_div == 24'd49999999999)

begin

scan_clk <= ~scan_clk;

count_div<= 24'b;

end

else

begin

count_div <= count_div+1;

end

end

// -------------------------------------

// 分频模块 结束

// ------------------------------------

always @(posedge scan_clk,negedge rst)

begin

if(!rst)

choose <= 0;

else

choose <= choose +1'b1;

end

always data=16'hffff;

endmodule

任务二:

`define BETA_TIME 8'h02

module scan (clk_50M,rst,choose,data,sel,l5,rom_addr,romdata);

input clk_50M;

input rst;

output reg[3:0] choose;

output reg[15:0] data;

output wire[2:0] sel;

output wire l5;

reg[15:0] disp_memery[0:15];

reg[15:0] rom[0:128];

assign sel=3'b010;

assign l5=1'b0;

// +++++++++++++++++++++++++++++++++++++

// 分频模块 开始

// 分频得到的时钟用于改变显示内容

// +++++++++++++++++++++++++++++++++++++

reg disp_change_clk;

reg [40:0] count_div;

//

always @(posedge clk_50M)

begin

if(count_div == 24'd49999999999)

begin

disp_change_clk <= ~disp_change_clk;

count_div<= 24'b;

end

else

begin

count_div <= count_div+1;

end

end

// -------------------------------------

// 分频模块 结束

// ------------------------------------

// +++++++++++++++++++++++++++++++++++++

// 分频得到的时钟用于改变屏幕扫描

// +++++++++++++++++++++++++++++++++++++

reg disp_scan_clk;

reg [40:0] count_div1;

always @(posedge clk_50M)

begin

if(count_div1 == 24'd4999)

begin

disp_scan_clk <= ~disp_scan_clk;

count_div1<= 24'b;

end

else

begin

count_div1 <= count_div1+1;

end

end

// -------------------------------------

// 分频模块 结束

// ------------------------------------

reg [6:0] rom_addr;

//wire [15:0] romdata;

output[6:0] rom_addr;

output[15:0] romdata;

always @ (posedge clk_50M or negedge rst)

begin

if(!rst)

rom_addr <= 7'h0;

else

if(rom_addr==7'b000_1111)

rom_addr

else

rom_addr <= rom_addr+7'b000_0001;

end

always @(posedge disp_scan_clk or negedge rst)

begin

if(!rst)

choose <= 4'hf;

<=0;

else

choose <= choose +1'b1;

end

reg [6:0] disp_count;

always @(posedge disp_change_clk or negedge rst)

begin

if(!rst)

disp_count <= 7'h00;

else

disp_count <= disp_count +1'b1;

end

always@(posedge clk_50M)

begin

disp_memery[rom_addr ] <= rom[rom_addr+disp_count];

end

always data=disp_memery[4'hf-choose];

always @(*)

begin

rom[7'h00]=

rom[7'h01]=

rom[7'h02]=

rom[7'h03]=

rom[7'h04]=

rom[7'h05]=

rom[7'h06]=

rom[7'h07]=

rom[7'h08]=

rom[7'h09]=

rom[7'h0a]=

rom[7'h0b]=

rom[7'h0c]=

16'h0000;

16'h0200;

16'h6FFE;

16'h2248;

16'h2248;

16'h2FFE;

16'h2201;

16'hE082;

16'h2104;

16'h2E18;

16'h22E0;

16'h2210;

16'h628C;

rom[7'h0d]=

rom[7'h0e]=

rom[7'h0f]=

rom[7'h10]=

rom[7'h11]=

rom[7'h12]=

rom[7'h13]=

rom[7'h14]=

rom[7'h15]=

rom[7'h16]=

rom[7'h17]=

rom[7'h18]=

rom[7'h19]=

rom[7'h1a]=

rom[7'h1b]=

rom[7'h1c]=

rom[7'h1d]=

rom[7'h1e]=

rom[7'h1f]=

rom[7'h20]=

rom[7'h21]=

rom[7'h22]=

rom[7'h23]=

rom[7'h24]=

rom[7'h25]=

rom[7'h26]=

rom[7'h27]=

rom[7'h28]=

rom[7'h29]=

16'h0306;

16'h0004;

16'h0000;

16'h0002;

16'h0004;

16'h0008;

16'h0010;

16'h8060;

16'hC180;

16'h6E00;

16'h1800;

16'h0600;

16'h0100;

16'h00C0;

16'h0020;

16'h0018;

16'h000C;

16'h0008;

16'h0000;

16'h0000;

16'h1004;

16'h1106;

16'h110C;

16'h11F8;

16'h1108;

16'h1110;

16'h1010;

16'hFF00;

16'h10E0;

rom[7'h2a]=

rom[7'h2b]=

rom[7'h2c]=

rom[7'h2d]=

rom[7'h2e]=

rom[7'h2f]=

rom[7'h30]=

rom[7'h31]=

rom[7'h32]=

rom[7'h33]=

rom[7'h34]=

rom[7'h35]=

rom[7'h36]=

rom[7'h37]=

rom[7'h38]=

rom[7'h39]=

rom[7'h3a]=

rom[7'h3b]=

rom[7'h3c]=

rom[7'h3d]=

rom[7'h3e]=

rom[7'h3f]=

16'h9018;

16'h7004;

16'h5002;

16'h1001;

16'h000E;

16'h0000;

16'h0000;

16'h0002;

16'h4084;

16'h44C8;

16'h4D90;

16'h55A0;

16'h6682;

16'h4681;

16'h44FE;

16'h8880;

16'hB2A0;

16'h8190;

16'h80C8;

16'h8046;

16'h0000;

16'h0000;

rom[7'h40]= 16'h0404;

rom[7'h41]= 16'h0C44;

rom[7'h42]= 16'h34C4;

rom[7'h43]= 16'hC548;

rom[7'h44]= 16'h0648;

rom[7'h45]= 16'h0849;

rom[7'h46]= 16'h2102;

rom[7'h47]= 16'h230C;

rom[7'h48]= 16'h25F0;

rom[7'h49]= 16'hB900;

rom[7'h4A]= 16'h6100;

rom[7'h4B]= 16'h21FC;

rom[7'h4C]= 16'h2502;

rom[7'h4D]= 16'h2382;

rom[7'h4E]= 16'h210E;

rom[7'h4F]= 16'h0000;

rom[7'h50]= 16'h0200;

rom[7'h51]= 16'h8200;

rom[7'h52]= 16'h73FE;

rom[7'h53]= 16'h2004;

rom[7'h54]= 16'h0009;

rom[7'h55]= 16'h0101;

rom[7'h56]= 16'h0202;

rom[7'h57]= 16'h7DC2;

rom[7'h58]= 16'h4134;

rom[7'h59]= 16'h4108;

rom[7'h5A]= 16'h4108;

rom[7'h5B]= 16'h7D34;

rom[7'h5C]= 16'h03C2;

rom[7'h5D]= 16'h0203;

rom[7'h5E]= 16'h0202;

rom[7'h5F]= 16'h0000;

rom[7'h60]= 16'h0400;

rom[7'h61]= 16'h8400;

rom[7'h62]= 16'h7400;

rom[7'h63]= 16'h27FE;

rom[7'h64]= 16'h0004;

rom[7'h65]= 16'h0008;

rom[7'h66]= 16'h0410;

rom[7'h67]= 16'h0400;

rom[7'h68]= 16'h0400;

rom[7'h69]= 16'h0400;

rom[7'h6A]= 16'hFFFF;

rom[7'h6B]= 16'h0400;

rom[7'h6C]= 16'h0400;

rom[7'h6D]= 16'h0400;

rom[7'h6E]= 16'h0400;

rom[7'h6F]= 16'h0000;

rom[7'h70]= 16'h0000;

rom[7'h71]= 16'h0000;

rom[7'h72]= 16'h0000;

rom[7'h73]= 16'h0000;

rom[7'h74]= 16'h0000;

rom[7'h75]= 16'h0000;

rom[7'h76]= 16'h0000;

rom[7'h77]= 16'h0000;

rom[7'h78]= 16'h0000;

rom[7'h79]= 16'h0000;

rom[7'h7A]= 16'h0000;

rom[7'h7B]= 16'h0000;

rom[7'h7C]= 16'h0000;

rom[7'h7D]= 16'h0000;

rom[7'h7E]= 16'h0000;

rom[7'h7F]= 16'h0000;

end

Endmodule