哈工程FPGA实验报告1616点阵.docx

上传人:b****7 文档编号:8956878 上传时间:2023-02-02 格式:DOCX 页数:20 大小:306.13KB
下载 相关 举报
哈工程FPGA实验报告1616点阵.docx_第1页
第1页 / 共20页
哈工程FPGA实验报告1616点阵.docx_第2页
第2页 / 共20页
哈工程FPGA实验报告1616点阵.docx_第3页
第3页 / 共20页
哈工程FPGA实验报告1616点阵.docx_第4页
第4页 / 共20页
哈工程FPGA实验报告1616点阵.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

哈工程FPGA实验报告1616点阵.docx

《哈工程FPGA实验报告1616点阵.docx》由会员分享,可在线阅读,更多相关《哈工程FPGA实验报告1616点阵.docx(20页珍藏版)》请在冰豆网上搜索。

哈工程FPGA实验报告1616点阵.docx

哈工程FPGA实验报告1616点阵

FPGA实验报告

 

姓名:

学号:

指导教师:

 

2013.6.10

 

 

实验六点阵扫描显示实验

一、实验原理

根据硬件电路可知,点阵的控制端口由行端口和列端口组成,分别为16个,相当于256个LED灯。

要是某一个灯亮,只需使对应位置上一端为高,一端为低。

该16*16的点阵的列端口由一个74154四位译码器控制。

由其资料可知,要使74154正常工作,其12脚、18脚与19脚必须接低。

20、21、22、23脚是数据输入端。

24脚为VCC,其他为数据输出端口。

16×16扫描LED点阵的工作原理同8位扫描数码管类似。

它有16个共阴极输出端口,每个共阴极对应有16个LED显示灯,所以其扫描译码地址需4位信号线(SEL0-SEL3),其汉字扫描码由16位段地址(0-15)输入。

通过时钟的每列扫描显示完整汉字。

点阵LED一般采用扫描式显示,实际运用分为三种方式:

(1)点扫描

(2)行扫描

(3)列扫描

若使用第一种方式,其扫描频率必须大于16×64=1024Hz,周期小于1ms即可。

若使用第二和第三种方式,则频率必须大于16×8=128Hz,周期小于7.8ms即可符合视觉暂留要求。

此外一次驱动一列或一行(8颗LED)时需外加驱动电路提高电流,否则LED亮度会不足。

汉字显示使用的是16×16的点阵,FPGA实验箱上有其接口电路,列选信号为SEL0,SEL1,SEL2,SEL3,经4线16线译码器输出16列,从左起为第一列,列选信号是由一个4位向量SEL[3..0]控制;行选信号为H0~H15,是由16个行信号组成的,每一行由一个单独的位来控制,高电平有效。

例如“0000”表示第0列,“0000000000000001”表示第一行的点亮。

由于列是由一个向量决定,而每一时刻的值只能有一个固定的值,因而只能使某一列的若干个点亮,因此就决定了只能用逐列扫描的方法。

例如要使第一列的2,4,6,8,行亮,则列为“0001”、行为“0000000010101010”就可以实现了

用动态分时扫描技术使LED点阵模块显示图像,需要进行两步工作。

第一步是获得数据并保存,即在存贮器中建立汉字数据库。

第二步是在扫描模块的控制下,配合行扫描的次序正确地输出这些数据。

获得图像数据的步骤是,先将要显示的每一幅图像画在一个如图3.3所示的被分成16×16共256个小方格的矩形框中,再在有笔划下落处的小方格里填上“1”,无笔划处填上“0”,这样就形成了与这个汉字所对应的二进制数据在该矩形框上的分布,再将此分布关系以32×16的数据结构组成64个字节的数据,并保存在只读存贮器ROM中。

以这种方式将若干个汉字的数据贮存在存贮器内,就完成了图像数据库的建立工作。

二、实验框图及原理图

实验原理图

实验框图

三、实验程序详解

1)行扫描

使行扫描端口依次拉低,同时较高频率进行列扫秒

moduleD_Z(clk,lie,hang,sel0,sel1,sel2);

inputclk;//时钟输入

output[4:

0]lie;//点阵引脚

output[15:

0]hang;

outputsel0;//扩张功能选择引脚

outputsel1;

outputsel2;

regclk_s;

regclk_ms;

reg[4:

0]lie;

reg[15:

0]hang;

reg[3:

0]XS_data;//显示状态

reg[3:

0]PY_data;//平移状态

reg[31:

0]XS_DIV;//显示计数

reg[31:

0]PY_DIV;//平移计数

wiresel0;

wiresel1;

wiresel2;

parameterCLK_XS='D25_000;

parameterCLK_PY='D1_000;

assignsel0=1'b0;//扩展功能选择点阵

assignsel1=1'b1;

assignsel2=1'b0;

always@(posedgeclk)//时钟分频产生毫秒时钟,用于点阵动态显示

begin

if(XS_DIV

XS_DIV<=XS_DIV+1'b1;

else

begin

XS_DIV<=0;

clk_ms<=~clk_ms;

end

end

always@(posedgeclk_ms)//毫秒时钟计数产生秒级时钟,用于平移

begin

if(PY_DIV<=CLK_PY)

PY_DIV<=PY_DIV+1;

else

begin

PY_DIV<=0;

clk_s<=~clk_s;

end

end

always@(posedgeclk_ms)//显示一行点阵

begin

case(XS_data)

0:

begin

lie=5'b00000;

XS_data=1;

end

1:

begin

lie=5'b00001;

XS_data=2;

end

2:

begin

lie=5'b00010;

XS_data=3;

end

3:

begin

lie=5'b00011;

XS_data=4;

end

4:

begin

lie=5'b00100;

XS_data=5;

end

5:

begin

lie=5'b00101;

XS_data=6;

end

6:

begin

lie=5'b00110;

XS_data=7;

end

7:

begin

lie=5'b00111;

XS_data=8;

end

8:

begin

lie=5'b01000;

XS_data=9;

end

9:

begin

lie=5'b01001;

XS_data=10;

end

10:

begin

lie=5'b01010;

XS_data=11;

end

11:

begin

lie=5'b01011;

XS_data=12;

end

12:

begin

lie=5'b01100;

XS_data=13;

end

13:

begin

lie=5'b01101;

XS_data=14;

end

14:

begin

lie=5'b01110;

XS_data=15;

end

15:

begin

lie=5'b01111;

XS_data=0;

end

default

begin

lie=5'b01111;

XS_data=0;

end

endcase

end

always@(posedgeclk_s)//行平移,间隔1秒显示每一行

begin

case(PY_data)

0:

begin

hang=16'h0001;

PY_data=1;

end

1:

begin

hang=16'h0002;

PY_data=2;

end

2:

begin

hang=16'h0004;

PY_data=3;

end

3:

begin

hang=16'h0008;

PY_data=4;

end

4:

begin

hang=16'h0010;

PY_data=5;

end

5:

begin

hang=16'h0020;

PY_data=6;

end

6:

begin

hang=16'h0040;

PY_data=7;

end

7:

begin

hang=16'h0080;

PY_data=8;

end

8:

begin

hang=16'h0100;

PY_data=9;

end

9:

begin

hang=16'h0200;

PY_data=10;

end

10:

begin

hang=16'h0400;

PY_data=11;

end

11:

begin

hang=16'h0800;

PY_data=12;

end

12:

begin

hang=16'h1000;

PY_data=13;

end

13:

begin

hang=16'h2000;

PY_data=14;

end

14:

begin

hang=16'h4000;

PY_data=15;

end

15:

begin

hang=16'h8000;

PY_data=0;

end

default

begin

hang=16'h0000;

PY_data=0;

end

endcase

end

endmodule

2)列扫描

将行端口全部拉高,同时给译码器的数据输入端口加一,每次使对应显示的行端口保持低电平,与行扫描必须同时进行扫描的字符才能显示正确。

moduleD_Z(clk,lie,hang,sel0,sel1,sel2);

inputclk;//时钟输入

output[4:

0]lie;//点阵引脚

output[15:

0]hang;

outputsel0;//扩张功能选择引脚

outputsel1;

outputsel2;

regclk_s;

reg[4:

0]lie;

reg[3:

0]XS_data;//显示状态

reg[31:

0]XS_DIV;//显示计数

wire[15:

0]hang;

wiresel0;

wiresel1;

wiresel2;

parameterCLK_XS='D25_000_000;

assignsel0=1'b0;//扩展功能选择点阵

assignsel1=1'b1;

assignsel2=1'b0;

assignhang=16'b1111_1111_1111_1111;

always@(posedgeclk)//时钟分频,产生秒级时钟,用于平移

begin

if(XS_DIV

XS_DIV<=XS_DIV+1'b1;

else

begin

XS_DIV<=0;

clk_s<=~clk_s;

end

end

always@(posedgeclk_s)//间隔一秒平移显示每列

begin

case(XS_data)

0:

begin

lie=5'b00000;

XS_data=1;

end

1:

begin

lie=5'b00001;

XS_data=2;

end

2:

begin

lie=5'b00010;

XS_data=3;

end

3:

begin

lie=5'b00011;

XS_data=4;

end

4:

begin

lie=5'b00100;

XS_data=5;

end

5:

begin

lie=5'b00101;

XS_data=6;

end

6:

begin

lie=5'b00110;

XS_data=7;

end

7:

begin

lie=5'b00111;

XS_data=8;

end

8:

begin

lie=5'b01000;

XS_data=9;

end

9:

begin

lie=5'b01001;

XS_data=10;

end

10:

begin

lie=5'b01010;

XS_data=11;

end

11:

begin

lie=5'b01011;

XS_data=12;

end

12:

begin

lie=5'b01100;

XS_data=13;

end

13:

begin

lie=5'b01101;

XS_data=14;

end

14:

begin

lie=5'b01110;

XS_data=15;

end

15:

begin

lie=5'b01111;

XS_data=0;

end

default

begin

lie=5'b01111;

XS_data=0;

end

endcase

end

endmodule

3)显示姓名

moduledainzhen(clk,en,column,line,sel0,sel1,sel2,stop);

inputclk;

inputstop;

output[3:

0]column;

output[15:

0]line;

reg[3:

0]column;

reg[15:

0]line;

reg[7:

0]i,j,k;//定义计算用于显示具体一个点的参数

 

outputen;

outputsel0;

outputsel1;

outputsel2;

assignen=0;

assignsel0=0;

assignsel1=1;

assignsel2=0;

reg[16:

0]counter;

regclk_1;

always@(posedgeclk)

begin

if(counter[15])

begin

clk_1<=~clk_1;

counter<=0;

end

else

counter<=counter+1'b1;

end

 

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

taskdisplay;//定义任务display

reg[3:

0]column_out;//行显示中间变量,可以省略

reg[15:

0]line_out;//列显示中间变量,可以省略

begin

case(i)//每一个i值进来以后,判断需要显示一个点的列坐标?

0:

column_out=4'h0;//

1:

column_out=4'h1;//

2:

column_out=4'h2;//

3:

column_out=4'h3;//

4:

column_out=4'h4;//

5:

column_out=4'h5;//

6:

column_out=4'h6;//

7:

column_out=4'h7;//

8:

column_out=4'h8;//

9:

column_out=4'h9;//

10:

column_out=4'ha;//

11:

column_out=4'hb;//

12:

column_out=4'hc;//

13:

column_out=4'hd;//

14:

column_out=4'he;//

15:

column_out=4'Hf;//

endcase

k=(i+j)%48;//k用取余计算来确定,使字符能够向左移动,每次移动一步

case(k)//每一个k值进来以后,判断需要显示一行上面的

//坐标上的数据

0:

line_out=16'h2004;//刘

1:

line_out=16'h1804;//

2:

line_out=16'h0924;//

3:

line_out=16'hFFA4;//

4:

line_out=16'h0224;//

5:

line_out=16'h4224;//

6:

line_out=16'h2224;//

7:

line_out=16'h1424;//

8:

line_out=16'h1424;//

9:

line_out=16'h0824;//

10:

line_out=16'h0824;//

11:

line_out=16'h1424;//

12:

line_out=16'h2204;//

13:

line_out=16'h4304;//

14:

line_out=16'h8114;//

15:

line_out=16'h0008;//

16:

line_out=16'h1004;//妍

17:

line_out=16'h17FE;//

18:

line_out=16'h1088;//

19:

line_out=16'h1088;//

20:

line_out=16'hFC88;//

21:

line_out=16'h2488;//

22:

line_out=16'h2488;//

23:

line_out=16'h27FE;//

24:

line_out=16'h2488;//

25:

line_out=16'h4488;//

26:

line_out=16'h2888;//

27:

line_out=16'h1088;//

28:

line_out=16'h2888;//

29:

line_out=16'h4488;//

30:

line_out=16'h8108;//

31:

line_out=16'h0288;//

32:

line_out=16'h0008;//玉

33:

line_out=16'h7FFC;//

34:

line_out=16'h0100;//

35:

line_out=16'h0100;//

36:

line_out=16'h0100;//

37:

line_out=16'h0100;//

38:

line_out=16'h0110;//

39:

line_out=16'h3FF8;//

40:

line_out=16'h0100;//

41:

line_out=16'h0100;//

42:

line_out=16'h0140;//

43:

line_out=16'h0130;//

44:

line_out=16'h0110;//

45:

line_out=16'h0104;//

46:

line_out=16'hFFFE;//

47:

line_out=16'h0000;//

endcase

column=column_out;//结束判断后给行输出赋值

line=line_out;//结束判断后给列输出赋值

end

endtask

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

always@(posedgeclk_1)

begin

i=i+1;//每个clk信号来了以后自加1

if(i==16)

begin

i=0;//八行都显示完毕后归零

if(stop)

begin

j=j+1;

end

//同时纵向所有数据向左移动一位

end//

if(j==48)j=0;//都完成移动后计数器j归零

display;//调用显示任务,clk连续不断,保持视觉暂留,形成滚动//的S字样

end

endmodule

四、管脚分配

五、实验现象

1.行扫描

点阵上的点逐行依次点亮

2.列扫描

点阵上的点逐列依次点亮

3.姓名显示

点阵上滚动显示姓名“刘妍玉”

六、实验总结

实验结果显示字符可以正常显示并在点阵上滚动,通过将扫描的行与列的管脚分别反向分配可以实现字符的镜像显示

通过实验了解了点阵显示的基本原理,通过扫描的方式将存在存储器中的数据显示出来。

实验中发现,行扫描和列扫描需要同时分别进行,即要想使得某一位置亮起,就要保持列端口一直为高,行端口依次拉低即可,但是在实验过程中由于对语言的不熟悉,在实验开始阶段遇到了很大的困难,自己写程序很吃力,分频阶段之后行扫描与列扫描的并行处理,在老师同学帮助和查找网上资料,基本熟悉了大致的程序过程,但对于自己把握大段的程序仍然有困难,需要进一步的学习。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 自考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1