实验37跑马灯设计.docx
《实验37跑马灯设计.docx》由会员分享,可在线阅读,更多相关《实验37跑马灯设计.docx(20页珍藏版)》请在冰点文库上搜索。
实验37跑马灯设计
实验37跑马灯设计
一、实验目的
1.学习VHDL程序的基本设计技巧;
2.学习状态机的设计技巧;
二、实验仪器和设备
序号
名称
型号规格
数量
备注
1
计算机
1台
2
KH-31001实验箱
1台
3
KH-33001/2/3下载板
1块
三、实验原理
1.彩灯(二极管)发光原理
图2.37.1LED小灯显示模块
图2.37.1为KH-31001实验箱上显示模块,发光二极管(LED)是一种由磷化镓(GaP)等半导体材料制成的、能直接将电能转变成光能的发光显示器件。
当其内部有一定电流通过时,它就会发光。
发光二极管也与普通二极管一样由PN结构成,也具有单向导电性。
它广泛应用于各种电子电路、家电、仪表等设备中、作电源指示或电平指示。
2.状态机简介
状态机是一个有向图形,由一组节点和一组相应的转移函数组成。
状态机通过响应一系列事件而“运行”。
每个事件都在属于“当前”节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。
函数返回“下一个”(也许是同一个)节点。
这些节点中至少有一个必须是终态。
当到达终态,状态机停止。
状态机包含一组状态集(states)、一个起始状态(startstate)、一组输入符号集(alphabet)、一个映射输入符号和当前状态到下一状态的转换函数(transitionfunction)的计算模型。
当输入符号串,模型随即进入起始状态。
它要改变到新的状态,依赖于转换函数。
在有限状态机中,会有有许多变量,例如,状态机有很多与动作(actions)转换(Mealy机)或状态(摩尔机)关联的动作,多重起始状态,基于没有输入符号的转换,或者指定符号和状态(非定有限状态机)的多个转换,指派给接收状态(识别者)的一个或多个状态等等。
3.控制8个LED进行花式显示,设计四种显示模式:
1.从左到右逐个点亮LED;
2.从右到左逐个点亮LED;
3.从两边到中间逐个点亮LED;
4.从中间到两边逐个点亮LED。
四种模式循环切换,如图2.37.2所示,由KH-31001实验箱上左下侧键盘附近的拨码开关SW3的“I01”来控制系统的运行与停止,当“I01”拨到“ON”位置时系统运行,当“I01”拨到“OFF”位置时系统停止。
图2.37.2四种模式循环切换
可用移位寄存器来控制逐个点亮LED的操作,移位的频率为10Hz。
四、实验内容
基本实验:
在EDA实验箱上控制8个LED完成S0、S1、S3、S4四种循环模式
1.实验前的准备
1打开KH-31001实验箱电源。
2打开
QuartusⅡ软件。
2.建立项目工程
点击菜单“File”“NewProjectWizard”如图2.37.3所示。
点击“Next”,如图2.37.4所示。
图2.37.3点击菜单“File”“NewProjectWizard”
图2.37.4向导界面
选择工程文件存储位置,并输入项目工程名称,如图2.37.5所示。
点击“Next”。
图2.37.5项目工程名称设置
3.选择器件
器件选择如图2.37.6所示。
随后点击“Next”,“Finish”,如图2.37.7。
图2.37.6选择器件
图2.37.7完成工程项目设置
4.建立VHDL文件
点击界面“新建文件”按钮
,或点击菜单“File”“New”。
在弹出的如图2.37.8所示的窗口中选“VHDL”语言文件。
输入VHDL程序代码后,如图2.37.9所示,保存文件。
文件名应该与实体名称一致。
如:
led.vhd。
代码如下:
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityledis
port(clk:
instd_logic;
rst:
instd_logic;
q:
outstd_logic_vector(7downto0));
end;
architectureledofledis
constants0:
std_logic_vector(1downto0):
="00";--模式1
constants1:
std_logic_vector(1downto0):
="01";--―模式2
constants2:
std_logic_vector(1downto0):
="10";--―模式3
constants3:
std_logic_vector(1downto0):
="11";--―模式4
signalpresent:
std_logic_vector(1downto0);--――当前模式
signalq1:
std_logic_vector(7downto0);
signalcount:
std_logic_vector(3downto0);
begin
process(rst,clk)
begin
if(rst='0')then--――系统初始化
present<=s0;
q1<=(others=>'0');
elsif(clk'eventandclk='1')then
casepresentis
whens0=>if(q1="00000000")then--――S0模式:
从左到右逐个点亮LED
q1<="10000000";
elseif(count="0111")then
count<=(others=>'0');
q1<="00000001";
present<=s1;
elseq1<=q1(0)&q1(7downto1);
count<=count+1;
present<=s0;
endif;
endif;
whens1=>if(count="0111")then--S1模式:
从右到左逐个点亮LED
count<=(others=>'0');
q1<="10000001";
present<=s2;
elseq1<=q1(6downto0)&q1(7);
count<=count+1;
present<=s1;
endif;
whens2=>if(count="0011")then--S2模式:
从两边到中间逐个点亮LED
count<=(others=>'0');
q1<="00011000";
present<=s3;
elseq1(7downto4)<=q1(4)&q1(7downto5);
q1(3downto0)<=q1(2downto0)&q1(3);
count<=count+1;
present<=s2;
endif;
whens3=>if(count="0011")then--S3模式:
从中间到两边逐个点亮LED
count<=(others=>'0');
q1<="10000000";
present<=s0;
elseq1(7downto4)<=q1(6downto4)&q1(7);
q1(3downto0)<=q1(0)&q1(3downto1);
count<=count+1;
present<=s3;
endif;
endcase;
endif;
endprocess;
q<=q1;
end;
图2.37.8新建VHDL文件
图2.37.9输入VHDL程序代码
5.设置顶层文件
如图2.37.10所示,在项目导航栏“ProjectNegatior”下方的
“Files”中选择文件,点击鼠标右键,选“SetasTop-LevelEntity”。
点击工具栏中,编译按钮
编译文件。
图2.37.10设置顶层文件
6.引脚设置
点击菜单“Assignments”“Pins”,如图2.37.11所示。
在如图2.37.12所示的界面中“Location”中输入引脚号。
并再次编译。
图2.37.11进入引脚设置
图2.37.12输入引脚号
7.下载代码
如图2.37.13所示,点击菜单“Tools”“Programmer”。
在如图2.37.14所示的界面中,设置Mode栏中选择JTAG方式。
点击“HardwareSetup”,在如图2.37.15界面中点击“AddHardware”,如图2.37.16设置为“ByteBlaster[LPT1]”。
点击左侧的AddFile选项,在弹出的对话框中依文件路径找到实验的.sof文件,打开。
Program/configure选项下的小方框中打对勾选中。
点击“Start”,下载代码,观察实验箱实验现象。
图2.37.13进入下载代码
图2.37.14下载代码界面
图2.37.15进入下载硬件设置
图2.37.16设置符合实验箱要求的硬件类型
图2.37.17时钟单元
图2.37.18拨码开关
将实验箱的脉冲选择开关SW7调至“2”的位置,如图2.37.17所示,使触发脉冲频率为10Hz;
将实验箱的拨码开关SW3的“I01”调至“ON”的位置,如图2.37.18所示,观察实验现象。
提高实验:
10路彩灯循环输出
将VHDL文件改为如下代码,编译并下载文件,观察实验现象,思考其原因是什么?
将实验箱的脉冲选择开关SW7调至“2”的位置,如图2.37.17所示,使触发脉冲频率为10Hz;
将实验箱的拨码开关SW3的“I01”调至“ON”的位置,如图2.37.18所示,观察实验现象。
libraryieee;
useieee.std_logic_1164.all;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entityled10isport(
reset,clk:
instd_logic;
y:
outstd_logic_vector(9downto0));
end;
architecturebehaviolofled10is
signaly_out:
std_logic_vector(9downto0);
typestatesis(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,
s12,s13,s14,s15,s16,s17,s18,s19,s20,S21);--状态生成,将所需变化以状态机形式输出
signalstate:
states;
begin
process(CLK,RESET)--状态转移
begin
if(reset='1')then
state<=s0;else
if(clk'eventandclk='1')then
casestateis
whens0=>state<=s1;
whens1=>state<=s2;
whens2=>state<=s3;
whens3=>state<=s4;
whens4=>state<=s5;
whens5=>state<=s6;
whens6=>state<=s7;
whens7=>state<=s8;
whens8=>state<=s9;
whens9=>state<=s10;
whens10=>state<=s11;
whens11=>state<=s12;
whens12=>state<=s13;
whens13=>state<=s14;
whens14=>state<=s15;
whens15=>state<=s16;
whens16=>state<=s17;
whens17=>state<=s18;
whens18=>state<=s19;
whens19=>state<=s20;
whens20=>state<=s21;
WHENS21=>STATE<=S0;
endcase;
endif;
endif;
endprocess;
process(reset)--状态赋值输出
begin
ifreset='1'then
y_out<="1111111111";
else
casestateis
whens0=>y_out<="1111111111";
whens1=>y_out<="0111111111";
whens2=>y_out<="0101111111";
whens3=>y_out<="0101011111";
whens4=>y_out<="0101010111";
whens5=>y_out<="0101010101";
whens6=>y_out<="1111111111";
whens7=>y_out<="1011111111";
whens8=>y_out<="1010111111";
whens9=>y_out<="1010101111";
whens10=>y_out<="1010101011";
whens11=>y_out<="1010101010";
whens12=>y_out<="1111111111";
whens13=>y_out<="0111111111";
whens14=>y_out<="0011111111";
whens15=>y_out<="0001111111";
whens16=>y_out<="0000111111";
whens17=>y_out<="0000011111";
whens18=>y_out<="0000001111";
whens19=>y_out<="0000000111";
whens20=>y_out<="0000000011";
whens21=>y_out<="0000000001";
whenothers=>y_out<="1111111111";
endcase;
endif;
y<=y_out;
endprocess;
end;
拓展实验:
12路彩灯循环输出
将VHDL文件改为如下代码,编译并下载文件,观察实验现象,思考其原因是什么?
将实验箱的脉冲选择开关SW7调至“2”的位置,如图2.37.17所示,使触发脉冲频率为10Hz;
将实验箱的拨码开关SW3的“I01”调至“ON”的位置,如图2.37.18所示,观察实验现象。
libraryieee;
useieee.std_logic_1164.all;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entityled12isport(
reset,clk:
instd_logic;
y:
outstd_logic_vector(11downto0));
end;
architecturebehaviolofled12is
signaly_out:
std_logic_vector(11downto0);
typestatesis(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,
s12,s13,s14,s15,s16,s17,s18,s19,s20,s21);--状态生成,将所需变化以状态机形式输出
signalstate:
states;
begin
process(CLK,RESET)--状态转移
begin
if(reset='0')then
state<=s0;else
if(clk'eventandclk='1')then
casestateis
whens0=>state<=s1;
whens1=>state<=s2;
whens2=>state<=s3;
whens3=>state<=s4;
whens4=>state<=s5;
whens5=>state<=s6;
whens6=>state<=s7;
whens7=>state<=s8;
whens8=>state<=s9;
whens9=>state<=s10;
whens10=>state<=s11;
whens11=>state<=s12;
whens12=>state<=s13;
whens13=>state<=s14;
whens14=>state<=s15;
whens15=>state<=s16;
whens16=>state<=s17;
whens17=>state<=s18;
whens18=>state<=s19;
whens19=>state<=s20;
whens20=>state<=s21;
WHENS21=>STATE<=S0;
endcase;
endif;
endif;
endprocess;
process(reset)--状态赋值输出
begin
ifreset='0'then
y_out<="111111111111";
else
casestateis
whens0=>y_out<="111111111111";
whens1=>y_out<="011111111111";
whens2=>y_out<="010111111111";
whens3=>y_out<="010101111111";
whens4=>y_out<="010101011111";
whens5=>y_out<="010101010111";
whens6=>y_out<="010101010101";
whens7=>y_out<="101111111111";
whens8=>y_out<="101011111111";
whens9=>y_out<="101010111111";
whens10=>y_out<="101010101111";
whens11=>y_out<="101010101010";
whens12=>y_out<="011111111111";
whens13=>y_out<="001111111111";
whens14=>y_out<="000111111111";
whens15=>y_out<="000011111111";
whens16=>y_out<="000001111111";
whens17=>y_out<="000000111111";
whens18=>y_out<="000000011111";
whens19=>y_out<="000000001111";
whens20=>y_out<="000000000111";
whens21=>y_out<="000000000011";
whenothers=>y_out<="111111111111";
endcase;
endif;
y<=y_out;
endprocess;
end;