北邮数电实验报告_简易迷宫游戏_第1页
北邮数电实验报告_简易迷宫游戏_第2页
北邮数电实验报告_简易迷宫游戏_第3页
北邮数电实验报告_简易迷宫游戏_第4页
北邮数电实验报告_简易迷宫游戏_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、数字电路与逻辑设计实验简易迷宫游戏专 业:电子信息工程姓 名:班 级:2012211102学 号:班内序号:设计课题的任务要求(一) 实验目的1. 熟练掌握 VHDL 语言和QuartusII 软件的使用;2. 理解状态机的工作原理和设计方法;3. 掌握利用 EDA 工具进行自顶向下的电子系统设计方法;(二) 相关知识本实验主要利用状态机来设计实现一个简易迷宫系统,本系统分为控制器与受控电路两部分。控制器主要控制整个系统按设定的工作方式实现点阵、计时器、数码管工作的通与断,并使用逻辑判断判决小人是否移动与否和移动的方向。同时本实验也运用到了包括分频器、计数器、数码管、点阵等相关知识。主要利用六

2、位数码管显示30s计时和小人移动步数,用点阵显示开机画面、迷宫地图、小人移动过程和游戏失败、胜利的相应画面。(三) 实验任务基本要求:1、 用88点阵进行游戏显示。2、 迷宫游戏如图1所示,采用双色点阵显示,其中红色LED为迷宫墙壁,绿色LED表示人物。通过BTN0BTN3四个按键控制迷宫中的人物进行上下左右移动,使人物从起始点出发,走到迷宫的出口,游戏结束3、 普通计时模式:通过按键BTN7启动游戏,必须在30秒内找到出口,否则游戏失败,用两个数码管进行倒计时显示。游戏胜利或者失败均要在88点阵上有相应的画面出现。4、 迷宫中的人物在行走过程中,如果碰到墙壁,保持原地不动提高要求:1. 多种

3、迷宫地图可以选择。2. 在计时的基础上增加计步的功能,每按一次控制按键步数加1,碰壁不计算步数,计步结果用数码管显示。3. 增加了计时显示的精确度,让倒计时精确到0.01s4.增加了开机画面,当按下START开始键后,点阵上开始显示“GO- 6-5-4-3-2-1”的开始画面。系统设计(一) 设计思路此程序利用自顶向下的设计思想。首先要考虑实现基本功能所需要哪些模块,倒计时的功能要用数码管来实现,地图的显示和迷宫游戏中动画的交互要用88点阵来实现,方向的选择和开始游戏需要独立按键来显示,这些都是最顶层的模块。然后,要实现这些模块,第一需要适当的时钟频率来驱动,这就要完成一个分频器,根据点阵、数

4、码管以及独立按键各自的特征完成相应频率的分配。实现倒计时功能的时候,需要一个计时器在每秒改变一次数码管的显示状态,于是还需要一个计时器模块。而数码管动态扫描需要相应的LED灯亮灭,这就需要先定义好了显示相应数字的时候对应八段LED的高低电平状态。点阵的显示控制原理和数码管类似,都是一个较高频率的动态扫描过程,只是代码量更大。其次,也是该程序最关键的地方就是绿色小人移动的控制。题干中说明小人撞墙后原地不动,不撞墙的时候进行移动。这就需要我们判断是否撞墙。经过和同学的商讨,我绝对将点阵坐标化,而小人所处的位置用(x,y)表示并实时的更新,然后将墙壁坐标封装好,当下一步的坐标在墙壁坐标的集合中则判定

5、为撞墙,否则根据方向进行移动。而终点坐标也都是提前用代码设定好的,这样通过坐标显示出点阵应该进行的下一画面。到此为止,该实验的基本功能都已经规划得较为清晰。对于提高要求,我通过一个拔码开关控制初始迷宫地图的选择,在程序中加入一个输入信号来选择相应地图;在程序中添加两个计数变量,分别表示步数的个位和十位,两者添加到判断撞墙与否的逻辑语句中,在数码管显示模块中增加两个数码管的显示便可实现。此外,为了丰富点阵界面,我还添加了开机画面,通过一个1s加1的变量扫描显示“GO- 6-5-4-3-2-1”;想到很多倒计时显示中个都精确到了0.01s甚至更精确,我又增加两个数码管来显示倒计时的小数点后两位。(

6、二) 总体框图1. 系统结构框图2. 逻辑划分方框图3. 控制模块流程图4. 状态转移图 (三) 分块设计 点阵模块:点阵模块主要分为点阵扫描显示模块、小人移动逻辑判断模块。扫描显示模块,主要是对迷宫地图、开机动画以及小人移动变化后的图案进行动态扫描,完成游戏交互。开机画面通过一个一秒更新一次的变量,然后通过case语句来完成扫描;地图图案的显示也是同样的方案,只不过要胜利或者失败的逻辑判断。小人移动的逻辑判断模块,主要通过坐标定位。首先将地图中墙壁的坐标位置封装好,然后将小人时刻的位置定义为(x,y),再根据按键对x,y进行变化,最后通过判断新的坐标是否在封装好的墙壁集合中来进行移动与否的判

7、决。如果移动则更新(x,y);如果不移动,则保持(x,y)不变。数码管显示模块:数码管显示模块主要分为30s倒计时模块和小人移动步数计数模块倒计时模块中将一个1KHZ的时钟信号进行四次的十分频,可以得到一个精确到0.01s的倒计时。每个变量都是十进制的数,再将它们传送到数码管动态扫描模块,便可以顺利地显示30s倒计时。小人移动步数计数模块,定义两个计数变量count、count10分别表示计数的个位和十位,将其放在小人移动逻辑判断模块中,当逻辑判定为移动,则将count加一,当加到10的时候进位。再将两者传送到数码管动态扫描模块,就可以实时显示小人移动的步数。按键防抖模块:该程序再一开始开发的

8、时候并没有加防抖模块,而是尽可能地找到一个最佳的按键扫描控制频率,使得既可以得到灵敏可靠的按键控制,又可以再长按一次后进行多步移动,这样可以方便用户的操作,一开始测试得到的按键扫描频率为5Hz。但是好像要求按键必须加防抖,并且为了提高按键输入可靠性,由于机械触点的弹性振动, 因而在按键闭合和断开的瞬间均会出现一连串的抖动,按键的抖动会造成按一次键产生的开关状态被 CPU 误读几次。 为了使 CPU 能正确地读取按键 状态,必须在按键闭合或断开时,消除产生的前沿或后沿抖动。一、 仿真波形及波形分析(一) 复位、开始()注:以下关于点阵显示的仿真都是最开始测试用的模块,并不包含点阵动态显示的所有状

9、态,只是挑选其中一些典型状态展示,而且点阵扫描红色和绿色是分开的。1.复位:当按下复位键的时候,停止对点阵的扫描,点阵上无任务图形显示。2开始:当按下开始键的时候,点阵开始进行行扫描,开始倒计时显示“GO- 6-5-4-3-2-1”,上图为点阵用红色LED显示“GO”。(二)点阵显示胜利、失败胜利:当玩家在30s之内到达了迷宫的终点,游戏结束并点阵显示“V”的标志。上图为当信号victory置高电平的时候,点阵开始行扫描,并将红色、绿色LED均点亮显示“V”,上图可明显地看出。失败:当玩家在30s之内没有到达迷宫的终点,游戏结束并且点阵显示“X”的标志。上图为信号fail置高电平的时候,点阵开

10、始行扫描,并将红色、绿色LED均点亮显示“X”,由上图可以明显地看出。(三)数码管倒计时数码管倒计时:实际上应该是四位数码管从30.00s倒计时,为了方便展示将倒计时的计数变量改成二进制,上图中输出信号ledshow代表数码管段选的信号,而ledstate代表数码管位选的信号,变量ledsao表示分五次对四位数字加上一个小数点进行扫描。上图红色圈中表示显示小数点,“00000001”表示小数点,而ledstate在“111110 111101 111011 110111 111011 ”五个状态之间循环表示对四位数字和一个小数点的显示。而ledshow显示相应的数字。(四)按键防抖按键防抖:k

11、eyin输入一个持续时间约为0.1s的按键信号并用高频时钟模拟抖动,keyout输出一个时钟周期的高电平。二、 源程序(注释)LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;use ieee.std_logic_unsigned.all;ENTITY maze ISPORT(clk:IN STD_LOGIC; -总时钟start,reset:IN STD_LOGIC; -开始和复位键l,r,f,b,mapflag:IN STD_LOGIC;-BTN -b/r/f/b分别代表小人向左、右、前、后移动;mapflag代表两种地图的选择dotshow:OUT STD

12、_LOGIC_VECTOR(23 DOWNTO 0); -点阵显示ledstate:OUT STD_LOGIC_VECTOR(5 DOWNTO 0); -数码管状态ledshow:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -数码管显示END maze;ARCHITECTURE main of maze IS signal cnt : integer range 0 to 25000; -分频器的计数 signal cnt1 : integer range 0 to 25000000; signal cnt2 : integer range 0 to 5000000;

13、signal clk_tmp : std_logic; -分频器的临时信号 signal clk_tmp1 : std_logic; signal tclk: std_logic; signal clk_tmp2 : std_logic; signal key_tmp0,key_tmp1,key_tmp2,key_tmp3:std_logic; signal row: std_logic_vector(7 downto 0); -点阵行状态 signal cul: std_logic_vector(15 downto 0); -点阵列状态 signal aclk: std_logic; -点阵

14、倒计时开机画面的时钟信号 signal binclk: std_logic; -按键时钟信号shared variable tend : integer range 0 to 1; signal tostart : std_logic; -开始标志信号 signal preset : std_logic; -逻辑判断模块重置signal dotreset : std_logic; -点阵模块重置 signal ledreset : std_logic; -数码管重置 signal treset : std_logic; -计时器重置 signal pwork : std_logic; -逻辑判

15、断模块工作 signal dotwork : std_logic; -点阵工作 signal ledwork : std_logic; -数码管工作 signal twork : std_logic; -计时器工作 signal worked : std_logic; signal vic : std_logic; - 成功signal fal : std_logic ; - 失败type nst is array(0 to 9)of std_logic_vector(7 downto 0);signal ledshowed:nst; shared variable rowsao:intege

16、r range 0 to 9; -点阵的行扫描shared variable ledsao :integer range 0 to 6; -数码管的扫描shared variable daojishi :integer range 0 to 7; -开机动画倒计时扫描shared variable dotsao :integer range 0 to 3;shared variable mapsao :integer range 0 to 9;shared variable x :integer range -7 to 0; -小人的坐标shared variable y :integer r

17、ange -6 to 1;shared variable count :integer range 0 to 9; -count和count10分别代表步数的个位和十位shared variable count10 :integer range 0 to 9;shared variable timems :integer range 0 to 9;shared variable time001s :integer range 0 to 9; -以下分别代表30倒计时的位数shared variable time01s :integer range 0 to 9;shared variable

18、time1s :integer range 0 to 9;shared variable time10s :integer range 0 to 9;begin -数码管显示高低电平初始化ledshowed(1)=01100000;ledshowed(2)=11011010;ledshowed(3)=11110010;ledshowed(4)=01100110;ledshowed(5)=10110110;ledshowed(6)=10111110;ledshowed(7)=11100000;ledshowed(8)=11111110;ledshowed(9)=11110110;ledshowe

19、d(0)=11111100;tdiv:process(clk,clk_tmp) - 计时器分频-1Kbeginif (clkevent and clk=1) thenif cnt=24999 thencnt=0;clk_tmp= not clk_tmp;elsecnt=cnt+1;end if;end if;tclk=clk_tmp;end process;adiv:process(clk,clk_tmp1) -点阵分频-1HZbeginif (clkevent and clk=1) thenif cnt1=24999999 thencnt1=0;clk_tmp1= not clk_tmp1;

20、elsecnt1=cnt1+1;end if;end if;aclk=clk_tmp1;end process;usediv:process(clk,clk_tmp2) -按键控制判断分频-5HZbeginif (clkevent and clk=1) thenif cnt2=4999999 thencnt2=0;clk_tmp2= not clk_tmp2;elsecnt2=cnt2+1;end if;end if;binclk=clk_tmp2;end process;process(clk_fd) -防抖模块begin if (clk_fdevent and clk_fd=1) then

21、 key_tmp0 = keyin; key_tmp1 = key_tmp0;end if; end process; -利用信号赋值延时将前后信号相与完成防抖 key_tmp2 = key_tmp0 and key_tmp1; process(clk_fd ) begin if (clk_fdevent and clk_fd=1) then key_tmp3 = key_tmp2; keyout= not( key_tmp2 ) and key_tmp3; end if; end process; end; -时钟上升沿输出一个时钟周期宽度的脉冲control:process(clk,res

22、et,start) -控制器beginif (clkevent and clk=1) thenif (start=1) thentostart=1;end if;if (reset=1 or tend=1) then preset=1; dotreset=1; ledreset=1; treset=1; tostart=0; dotwork=0; else preset=0;dotreset=0;ledreset=0;treset=0;if(tostart=1)thendotwork=1; -启动点阵模块end if;end if;end if;end process;a:process(ac

23、lk,dotreset) -点阵工作模块beginif (dotreset=1) thendotsao:=0;elseif ( aclkevent and aclk=1) thenif(vic=1 or fal=1)thenif(dotsao=2)thendotsao:=dotsao+1;end if;end if;end if;end if;end process;process(tclk,dotreset)beginif (dotreset=1) thenmapsao:=0;elseif (tclkevent and tclk=1) thenif(mapsao=9)thenmapsao:=

24、0;elsemapsao:=mapsao+1;end if;end if;end if;end process;process(aclk,dotwork,worked,dotreset)beginif (dotreset=1) thendaojishi:=0;elseif (aclkevent and aclk=1 and dotwork=1 and worked=0) thenif(daojishi=7)thendaojishi:=0;elsedaojishi:=daojishi+1;end if;end if;end if;end process;process(tclk,dotreset

25、)beginif (dotreset=1) thenrowsao:=0;elseif (tclkevent and tclk=1) thenif(rowsao=9)thenrowsao:=0;elserowsao:=rowsao+1;end if;end if;end if;end process;process(clk,dotreset,dotwork,mapflag) -开机动画begin if (dotreset=1) thendotshow=000000000000000000000000;tend:=0;worked=0;twork=0;pworkcase rowsao iswhen

26、 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdot

27、showdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase rowsao iswhen 1=dotshowdotshowdotshowdotshowdotshowdotshowdotshowdo

28、tshowdotshowdotshowworked=1;pwork=1;ledwork=1;twork=1;if (reset=1) thenpwork=0;ledwork=0;twork=0;end if;end case;elseif(fal=1)thentwork=0;pwork=0; if(dotsaodotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshow=111111111111111100000000;end case;elsetend:=1;end if;elsif(vic=1)thentwor

29、k=0;pwork=0;if(dotsaodotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase x iswhen 0=culculculculculculculculrowrowrowrowrowrowrowrow=01111111;end case;dotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowdotshowcase x iswhen 0=culculculculculculculculrowrowrowrowrowrowrowrow=01111111;end case;dotshow=row&cul;end case;end if;end if;end if;end if;end if;end process;p:process(clk,preset,pwork,binclk,l,r,f,b) -逻辑判断模块variable derx :integer range -1 to 1;variable dery :integer range -1 to 1;b

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论