本文主要是介绍北邮VHDL数电实验—电子沙漏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
由于APEC假期推迟了一周,上周五我们才交实验报告,在这里我就不把自己的全部实验报告贴上来了。北邮或是其他学校的学生可以参考我的代码,并且欢迎提出交流
实验室里用的板子是EPM1270T144C5,内部时钟50MHz。我用的软件是Quartus9.0
实验基本要求:
(1)采用 8*8 双色点阵显示电子沙漏的开机界面,如图2 所示。其中红色LED 代表沙漏的上半部分沙粒VD0~VD15,绿色LED 代表沙漏的下半部分VD0'~VD15'。
(2)用拨码开关 SW1 模拟重力感应器。当SW1 为低电平时,沙粒从VD0~VD15 向VD0'~VD15'移动;当SW1 为高电平时,沙粒从VD0'~VD15'向VD0~VD15 移动。
(3)按键 BTN0 作为计时启动停止按键,启动后沙粒即可按照SW1 设定的方向移动,以SW1 为低电平时为例,LED 移动的顺序与对应关系如图3 的①~⑯所示(若SW1为高电平,则点阵显示移动顺序为⑯~①)。每颗沙粒的移动时间为1 秒,当移动到图3 的○16时,若SW1 仍为低电平,则保持沙粒不动,但计时继续,直到SW1 的电平发生变化或者BTN0 计时停止。
(4)设计实现一个 60 秒计时器,当按键BTN0 启动时开始工作,用于在沙粒移动过程中进行计时校准,并用数码管DISP0~DISP1 显示计时结果。
3.提高要求:
(1)可以调节控制电子沙漏的流动速度。
(2)用多种方式呈现电子沙漏界面。
(3)自行设定沙粒的移动路径,显示每颗沙粒的移动过程。
(4)外接重力感应器,实现真实的电子沙漏功能。
(5)自拟其它功能。
这里就直接给出代码了,注释写的很详细,自己对于自己没有用到分模块的写法而感到惋惜,自己之前也是借鉴了一下一个点阵赛车的实验报告 http://wenku.baidu.com/view/02bfbd9d6bec0975f565e200.html
全段代码如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity SandGlass is
port(
clk:in std_logic; --50MHZ自带晶振频率
reset: in std_logic; --启动停止键
direction: in std_logic; --方向控制键
showPath : in std_logic; --是否显示路径
speed : in std_logic; --加速键
beep: out std_logic; --蜂鸣器
row:out std_logic_vector(0 to 7); --点阵8行
colorRed:out std_logic_vector(0 to 7); --点阵8列,红点
colorGreen:out std_logic_vector(0 to 7); --点阵8列,绿点
cat :out std_logic_vector(5 downto 0); --数码管的6个位
seven:out std_logic_vector(6 downto 0)); --数码管的7位
end SandGlass ;
architecture a of SandGlass is
type figure is array(1 downto 0) of integer range 0 to 9;
signal shownum: figure; --数码管输出的数字
signal tim:std_logic; --扫描点阵和数码管的频率
signal timm:std_logic; --扫描点阵和数码管的频率
signal positiveMap:integer:=0; --正向刷新漏斗的标号
signal beep_count:integer range 0 to 1000000:=0;
signal beep_temp:std_logic; --蜂鸣器辅助信号
signal clk1:std_logic; --路径显示时沙漏的时钟
signal shuzi:integer:=1; --暂停按键计数器
signal clk2:std_logic; --常规沙漏的移动时钟
signal a:integer:=0; --辅助分频信号
signal count:integer:=0; --5秒倒数以及倒数后的状态标记
begin
clktim:process(clk) --分频模块
variable cout1: integer:=0;
variable cout2: integer:=0;
variable cout3: integer:=0;
variable cout4: integer:=0;
begin
if clk'event and clk = '1' then --扫描点阵和数码管
cout1:= cout1+1;
if cout1<= 25 then tim <= '0';
elsif cout1< 50 then tim <= '1';
else cout1:=0;
end if;
cout2:=cout2+1; --扫描按键
if cout2<= 4500000 then timm<='0';
elsif cout2< 9000000 then timm<='1';
else cout2:=0;
end if;
cout3:=cout3+1; --沙漏快速移动
if cout3<= 6250000 then clk1<='0';
elsif cout3< 12500000 then clk1<='1';
else cout3:=0;
end if;
cout4:=cout4+1; --时钟计时及沙漏常规移动
if cout4<= 25000000 then clk2<='0';
elsif cout4< 50000000 then clk2<='1';
else cout4:=0;
end if;
end if;
end process;
control:process(timm,reset,shuzi) --按键计数
begin
if (timm'event and timm='1') and (reset='1')then
shuzi<= shuzi+1;
end if;
end process;
controlsmg: process(clk2,shownum,shuzi,reset,count) --数码管控制
begin
if(shownum(1)<6) then
if reset='0' and (shuzi rem 2 =0) and (count=5)then
if (clk2'event and clk2='1') then
if(shownum(1)<=5) then
if(shownum(0)=9) then
shownum(0)<=0;
shownum(1)<=shownum(1)+1;
else
shownum(0)<= shownum(0)+1;
end if;
end if;
end if;
else
shownum(1)<=shownum(1);
shownum(0)<= shownum(0);
end if;
elsif( reset ='1') then
shownum(1)<=0;
shownum(0)<=0;
end if;
end process;
timeshow:process(reset,tim) --扫描显示数码管
variable sstate:integer range 0 to 1:=0;
begin
if tim'event and tim='1' then --个位和十位快速轮流亮
sstate:=sstate+1;
case sstate is
when 1=>cat<="111101"; --个位亮
when 0=>cat<="111110"; --十位亮
end case;
case shownum(sstate) is --显示数字
when 0=>seven<="1111110";
when 1=>seven<="0110000";
when 2=>seven<="1101101";
when 3=>seven<="1111001";
when 4=>seven<="0110011";
when 5=>seven<="1011011";
when 6=>seven<="1011111";
when 7=>seven<="1110000";
when 8=>seven<="1111111";
when 9=>seven<="1111011";
when others=>seven<="0000000";
end case;
end if;
end process;
beepfre_division:process(clk) --蜂鸣器分频
begin
if clk'event and clk = '1' then
beep_count <= beep_count+1;
if beep_count = 10 then
beep_count <= 0;
beep_temp <= not beep_temp;
end if;
end if;
end process;
beep_sound:process(beep_temp,shownum) --60秒到时蜂鸣器叫
begin
if shownum(1) =6 then
if beep_temp ='1' then
beep <= '1';
else beep<='0';
end if ;
else beep<='0';
end if;
end process;
secondscount:process(clk2,reset,shuzi,count) --5秒倒数及倒数后的状态标记
begin
if reset='0' and (shuzi =1) then count<=0;
elsif(clk2'event and clk2='1')then
if (count<5)then --5秒倒数
count<=count+1;
else
count<=5; --倒数结束,保持游戏状态
end if;
end if;
end process;
sandMove: process(clk1,reset,shuzi,count,showPath,direction,shownum,positiveMap,speed) --沙漏移动
begin
if reset='0' and (shuzi rem 2 =0) then
if(clk1'event and clk1='1') and (shownum(1)<6)and(count=5) then
case showPath is --是否显示路径
when '0'=>
if (direction ='0') and (positiveMap <=50)and (positiveMap>=0) then --正向显示路径
positiveMap<= positiveMap +1;
if(positiveMap = 50) then
positiveMap <= 50;
end if;
elsif(direction ='1')and (positiveMap <=50)and (positiveMap>=0) then --反向显示路径
positiveMap <= positiveMap -1;
if( positiveMap = 0) then
positiveMap <=0;
end if;
else
positiveMap <= positiveMap;
end if;
when '1'=>
a<=a+1;
if(speed='0') then
case direction is
when '0'=> --常速正向标准沙漏
if (a>=3) and (positiveMap <=50)and (positiveMap>=0) and(count=5) then
case positiveMap is
when 0|1|2|3 =>
positiveMap<=4;
a<=0;
when 4|5|6|7=>
positiveMap<=8;
a<=0;
when 8|9|10|11=>
positiveMap<=12;
a<=0;
when 12|13|14|15=>
positiveMap<=16;
a<=0;
when 16|17|18|19=>
positiveMap<=20;
a<=0;
when 20|21|22|23=>
positiveMap<=24;
a<=0;
when 24|25|26|27=>
positiveMap<=28;
a<=0;
when 28|29|30=>
positiveMap<=31;
a<=0;
when 31|32|33=>
positiveMap<=34;
a<=0;
when 34|35|36=>
positiveMap<=37;
a<=0;
when 37|38|39=>
positiveMap<=40;
a<=0;
when 40|41|42=>
positiveMap<=43;
a<=0;
when 43|44=>
positiveMap<=45;
a<=0;
when 45|46=>
positiveMap<=47;
a<=0;
when 47|48=>
positiveMap<=49;
a<=0;
when 49|50=>
positiveMap<=50;
a<=0;
when others =>null;
end case;
else
positiveMap<=positiveMap;
end if;
when '1'=> --常速反向标准沙漏
if (a>=3)and (positiveMap <=50)and (positiveMap>=0) and(count=5) then
case positiveMap is
when 0|1|2|3|4 =>
positiveMap<=0;
a<=0;
when 8|5|6|7=>
positiveMap<=4;
a<=0;
when 12|9|10|11=>
positiveMap<=8;
a<=0;
when 16|13|14|15=>
positiveMap<=12;
a<=0;
when 20|17|18|19=>
positiveMap<=16;
a<=0;
when 24|21|22|23=>
positiveMap<=20;
a<=0;
when 28|25|26|27=>
positiveMap<=24;
a<=0;
when 31|29|30=>
positiveMap<=28;
a<=0;
when 34|32|33=>
positiveMap<=31;
a<=0;
when 37|35|36=>
positiveMap<=34;
a<=0;
when 40|38|39=>
positiveMap<=37;
a<=0;
when 43|41|42=>
positiveMap<=40;
a<=0;
when 45|44=>
positiveMap<=43;
a<=0;
when 47|46=>
positiveMap<=45;
a<=0;
when 49|48=>
positiveMap<=47;
a<=0;
when 50=>
positiveMap<=49;
a<=0;
when others =>null;
end case;
else
positiveMap<= positiveMap;
end if;
end case;
elsif(speed ='1') then
case direction is
when '0'=> --加速正向标准沙漏
if (a>=1) and (positiveMap <=50)and (positiveMap>=0) and(count=5) then
case positiveMap is
when 0|1|2|3 =>
positiveMap<=4;
a<=0;
when 4|5|6|7=>
positiveMap<=8;
a<=0;
when 8|9|10|11=>
positiveMap<=12;
a<=0;
when 12|13|14|15=>
positiveMap<=16;
a<=0;
when 16|17|18|19=>
positiveMap<=20;
a<=0;
when 20|21|22|23=>
positiveMap<=24;
a<=0;
when 24|25|26|27=>
positiveMap<=28;
a<=0;
when 28|29|30=>
positiveMap<=31;
a<=0;
when 31|32|33=>
positiveMap<=34;
a<=0;
when 34|35|36=>
positiveMap<=37;
a<=0;
when 37|38|39=>
positiveMap<=40;
a<=0;
when 40|41|42=>
positiveMap<=43;
a<=0;
when 43|44=>
positiveMap<=45;
a<=0;
when 45|46=>
positiveMap<=47;
a<=0;
when 47|48=>
positiveMap<=49;
a<=0;
when 49|50=>
positiveMap<=50;
a<=0;
when others =>null;
end case;
else
这篇关于北邮VHDL数电实验—电子沙漏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!