




已阅读5页,还剩14页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
北 京 邮 电 大 学 数电综合实验报告实验名称: 简易贪吃蛇游戏机 学 院: 信息与通信工程 姓 名: 班 级: 学 号: 班内序号: 一设计课题的任务要求用一个 88 点阵作为基本显示屏,4 个连续移动的的发光点表示一条蛇,用任意出现的一个亮点表示老鼠,用4 个排成一条线的发光点表示“墙”,用四个按键控制蛇的运动方向,完成贪食蛇游戏,蛇撞“墙”、边或者游戏时间到,则游戏结束。(1). 老鼠出现的地方是随机的,在某个地点出现的时间是5秒钟,如果5秒钟之内没有被吃掉,它就会在其它地方随机出现;(2). 用数码管显示得分情况和游戏的剩余时间,每吃掉一只老鼠就加一分。二 系统设计1设计思路 采取模块化的设计思想,主要分为控制和显示模块,控制模块主要针对各种控制信号进行控制处理,比如蛇的移动,倒计时,方向控制等,而进行控制时,控制图形的变化的信号有很多,有外部按键输入,内部时钟驱动,判断的状态也比较多,蛇的位置,老鼠的位置,墙的位置等,在设计过程中将操作“串行化”,即利用高速时钟将判断和操作过程分为多个周期完成,简化设计。而显示模块主要完成鼠,蛇,墙以及分数,剩余时间的显示,而此模块要独立于显示内容,其内容与控制模块进行修改,这样使两个模块可以独立地进行工作,具有很好的扩展性和实现性。2. 总体框图(1)系统机构图贪吃蛇控制电路游戏初始设置:墙、蛇身、鼠初始化方向控制时间、速度控制剩余时间显示点阵显示计分显示 老鼠位置控制墙4点鼠蛇身4点(2)逻辑流程图流程图:Reset 等待按键 Start/pause是否按下 否 是计时、计分开始,墙初始化是60秒时间到蛇初始化位置并显示鼠初始化位置并显示5秒时间到否否蛇身移动 是 按下一次 再次按下鼠位置重置Start/pause上下左右分数增加长度增加撞蛇撞边撞墙吃鼠是是是是否否否否MDS图:Wait Eating mouseNew mouse Moving Change directionMoving into boundaryReset downMoving into Snake Restart startkey downtimeouTimeout (3)功能模块图:计分器点阵显示显示存储器计时器Reset控制模块控制器分频器方向控制模块Start/pause控制模块 CP3.模块设计(1)分频模块:由于实验板上的时钟频率为50MHZ,相对于电路延时时间来说,频率太高,故需要分频将频率降低来适应器件的反应时间要求;同时用来扫描点阵和数码管的频率与用来控制的时钟信号频率是不同的,相对而言用来扫描显示的频率要相对低一些,用来扫描按键和控制的时钟频率要低一些,所以此处将50MHZ的频率分为1MHZ和2KHZ,1MHZ的频率用来扫描按键和进行信号控制,2KHZ用于扫描显示,在控制模块中,又进行了二次分频,用来控制蛇的移动,鼠步的减少,倒计时时间等,不选择直接在分频模块中将所有的所需时钟频率全部分出的原因是在不同的进程中可能会对同一控制信号进行修改,所以这样就会出现多重驱动的问题,然而在进程内部进行二次分频就可以避免出现这种情况。(2)游戏控制模块: 这部分又可细分为四个小的模块:蛇状态判断模块,鼠随机产生模块,方向控制模块,蛇移动及时间控制模块。1. 蛇状态判断模块:主要完成对蛇“死”“活”状态的修改,而产生状态变化的情况有:按下reset键,改变开始暂停键的状态,蛇撞墙,总计是时间到,以及游戏通关(即游戏总得分为3分即为通关),而这些情况中reset键的优先级最高,当按下reset键时蛇的状态都会被置为“死(0)”的状态,而当“start/pause”键状态为“1”的话蛇的状态将会被置成“活(1)”,蛇撞墙,总时间到,通关都会将蛇的状态置为“死(0)”。2. 鼠随机产生模块:这部分主要完成产生新的老鼠坐标,思路是利用两个不同模值的计数器,分别对8取模,获得0到7之间的两个数作为新老鼠的横纵坐标,同时对产生的新左边进行判断,当和墙的坐标重合时进行修正,此处是将横坐标减一。而新老鼠的产生时刻是总计是时间到,鼠被吃掉,或蛇走十步后,刚开始是把这一部分单独作为一个线程,但是后来由于对鼠的产生标志信号的控制不是很好处理,所以这部分只是负责产生下次新老鼠的位置坐标,而真正的赋值操作在对蛇的控制状态线程里面。3. 方向控制模块:主要对控制蛇移动方向的信号进行修改,敏感信号为reset键和按键扫描时钟,但reset键的优先级较高,当reset键按下时,方向控制信号将会被设置成默认的向右,而其他四个方向控制键的检测则是在时钟信号的驱动下进行,由于按键扫描时钟频率为1MHZ,相对较高,所以不会有很大的迟钝感觉。4. 蛇移动和倒计时模块:由于此处设计的蛇移动时间间隔恰好是一秒,和倒计时的时间间隔一样,所以将这两个功能放在了一个进程中,这个进程中同时包含对蛇初始位置,总计时时间,鼠步的初始时间等初始化设置,原因也是为了避免出现双重驱动的问题。此处的时钟信号为1MHZ,在此线程内部进行了二次分频将其分为1HZ,用来控制蛇的移动以及时间计数,在1HZ时钟的驱动下进行剩余时间,剩余鼠步,以及蛇位置坐标的修改控制。(3)显示模块: 此模块主要完成鼠,墙,蛇,分数,剩余时间的显示,因为要同时显示这几项,故需要进行动态扫描,即在某一时间段内只显示其中一位,程序中用一个模为六的计数器实现在不同的计数值下显示不同的项,分别如下:T=0时,扫描老鼠坐标T=1时,扫描蛇头坐标和右边第一个数码管为SCORE显示T=2时,扫描蛇身2坐标T=3时,扫描蛇身3坐标和左边第一个数码管为总计时高位计时显示T=4时,扫描蛇身4坐标。T=5时,扫描墙的坐标和左边第四个数码管为总计时的低位计时显示 功能说明:1.游戏初始化:按下reset(btn0)键,会对鼠的位置,蛇的位置以及默认移动方向,游戏总时间进行初始化设置,此时分数显示为零,时间为六十秒。 2.游戏开始和暂停:当初始化之后将sw0拨上去即为开始游戏,拨下来即为暂停,暂停后蛇,鼠的位置保持不变,分数时间保持不变,再次将sw0拨回去即可继续游戏。 3.方向控制:btn7,btn6,btn5,btn4分别对应着上下左右四个方向。 4.当蛇撞墙时,蛇死,游戏重启。 5.当游戏总时间到时,游戏重启。 6.当老鼠十秒后没有被吃掉将会出现在别的地方。 7.当老鼠被蛇吃掉后将会出现新的老鼠,并且分数将会加一分。 8.当吃鼠分数达到三分时,点阵将会全亮,分数固定显示,剩余时间位熄灭,表示游戏通关,按下reset键可重新开始游戏。三仿真波形及波形分析仿真时的clk_kscan频率为clk_sscan的2倍,clk_kscan的内部分频比为1:100.(1)按下reset键后鼠,蛇的位置初始化Start=0,故蛇的位置没有变墙位置蛇初始位置鼠初始位置(2)蛇的位置右移蛇的位置向右移动Start=1(3)分数和时间的初始化显示初始化时间高位6初始化时间地位0初始化分数0(4)在仿真波形的设置中曾将direction设为“1000”,故蛇的移动方向变为向上,同时也可观察新老鼠的产生蛇向上移动产生新的鼠的坐标(5)在游戏过程中再次按按下reset键将会重启游戏再次复位后蛇鼠坐标重置(6)总得计时时间的变化剩余时间减一四源程序(1)分频模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity div is port(clk:in std_logic; clk_s,clk_k:out std_logic); end entity; architecture div_a of div is signal counter_sscan:integer range 0 to 24999; -分频得2khz时钟 signal counter_kscan:integer range 0 to 49; -分频得1mhz时钟begin div_sscan1:process(clk) begin if clkevent and clk=1 then if counter_sscan=24999 then counter_sscan=0; else counter_sscan=counter_sscan+1; end if; end if; end process div_sscan1;div_sscan2:process(counter_sscan) begin if counter_sscan12499 then -占空比为50% clk_s=1; else clk_s=0; end if; end process div_sscan2; div_kscan1:process(clk) begin if clkevent and clk=1 then if counter_kscan=49 then counter_kscan=0; else counter_kscan=counter_kscan+1; end if ; end if; end process div_kscan1;div_kscan2:process(counter_kscan) begin if counter_kscan25 then clk_k=1; else clk_kclkk,clk_s=clk_sscan,clk_k=clk_kscan);-端口映射 wx=5;wy0=5;wy1=4;wy2=3;wy3=2; decide:process(clk_kscan,reset) begin if reset=1 then -检测reset键 state=0; score=0; moux=3;mouy=4; elsif clk_kscanevent and clk_kscan=1 then if start=1 then state=1; -检测start/pause键 end if; if counter_move= then -内分频,所得频率为一秒(实际分频-时若果计数器的值按照理值去设置所得的时钟频率明显快于一秒,故此处将计-数模值加大为原来的1.5倍) if time_flag=0 then -剩余时间为零 state=0; if mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 or mouyy=wy3) then -判断下个要产生老鼠的位置是否与墙重合 moux=mouxx-1; else moux=mouxx; -进行新老鼠位置的赋值 end if; mouy=mouyy;elsif (sx0=wx and(sy0=wy0 or sy0=wy1 or sy0=wy2 or sy0=wy3) then -蛇撞墙 state=0; if mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 or mouyy=wy3) then moux=mouxx-1; else moux=mouxx; end if; mouy=mouyy; end if; if mousetime=0 then -老鼠剩余时间为零 if (mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 or mouyy=wy3) then moux=mouxx-1; else moux=mouxx; end if; mouy=mouyy; end if; if sx0=moux and sy0=mouy then -老鼠被吃掉,分数加一 score=score+1; if (mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 or mouyy=wy3) then moux=mouxx-1; else moux=mouxx; end if; mouy=mouyy; end if; if score=3 then -得分为3分时游戏通关 state=0; end if; end if; end if; end process decide;random:process(clk_kscan) - 用于产生随机老鼠的进程 begin if clk_kscanevent and clk_kscan=1 then if mcx=100 then mcx=0; else mcx=mcx+1; end if; if mcy=200 then mcy=0; else mcy=mcy+1; end if; mouxx=mcx rem 8; -产生0到7的老鼠的坐标 mouyy=mcy rem 8; end if; end process random; dirc:process(clk_kscan,reset) -方向控制进程 begin if reset=1 then -reset键检测 temp_turnif temp_turn/=2 then temp_turnif temp_turn/=0 then temp_turnif temp_turn/=1 then temp_turnif temp_turn/=3 then temp_turn temp_turn=temp_turn; end case; end if;end process dirc; move:process(clk_kscan,state) begin if state=0then -蛇死后游戏时间,老鼠时间,蛇位置的重置 mousetime=9; timeh=6;timel=0; sx0=3;sy0=0;sx1=2;sy1=0; sx2=1;sy2=0;sx3=0;sy3=0; time_flag=1; -将初始剩余时间标志设为1 elsif clk_kscanevent and clk_kscan=1 then if state=1 and start=1 then -开始键为一时才开始移动 if counter_move= then if mousetime=0 then -老鼠时间的控制 mousetime=9; else mousetime=mousetime-1; end if; if timel=0 and timeh/=0 then -总游戏剩余时间的控制 timel=9; timeh=timeh-1; time_flag=1; elsif timel=0 and timeh=0 then time_flag=0; else timel=timel-1; time_flagif sy0=7 then sy0=sy0-7; else sy0if sy0=0 then sy0=sy0+7; else sy0if sx0=7 then sx0=sx0-7; else sx0if sx0=0 then sx0=sx0+7; else sx0=sx0-1; end if; end case; sx1=sx0; sy1=sy0; sx2=sx1; sy2=sy1; sx3=sx2; sy3=sy2; if sx0=moux and sy0=mouy then -蛇吃鼠后鼠剩余时间的重置 mousetime=9; end if; counter_move=0; else counter_move=counter_move+1; -内分频计数器加一 end if; end if; end if; end process move; show:process(clk_sscan) -数码管和点阵扫描显示进程 begin if clk_sscanevent and clk_sscan=1 then row=; -将所有的行置1,列置0(新实验-板的列为1,行为0时点被点亮) col=; if temp_show=5 then temp_show=0; else temp_show=temp_show+1; end if; if score=3 then -得分为三时保留分数显示,使点阵全亮 col=; row=; temp_light=score; w_light col(moux)=1;row(mouy)=0; -显示老鼠坐标 temp_light=score; w_light col(sx0)=1;row(sy0)=0; -显示蛇头坐标和得分 w_light col(sx1)=1;row(sy1)=0; -显示蛇身第二个坐标 temp_light=timeh; w_light col(sx2)=1;row(sy2)=0; -显示蛇身第三个坐标和时间的高位 w_light col(sx3)=1;row(sy3)=0; -显示蛇身的第四个坐标 temp_light=timel; w_lightcol(wx)=1;row(wy0)=0; -显示时间的低位和墙的位置 w_light=; row(wy1)=0; row(wy2)=0; row(wy3)d_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_light=; end case; end if; end process lightshow; end tancs_a;五元器件清单和资源利用情况 1.元器件系统时钟:CLK重启按键RESET:BTN0开始/暂停按键:SW0方向控制键:BTN7,BTN6,BTN5,BTN4点阵行显示:ROW0ROW7点阵列显示:COL0COL7数码管的段选:AA,AB,AC,AD,AE,AF,AG数码管的位选信号:CAT0-CAT52.资源利用情况六故障及问题分析1.在对整个系统的模块进行划分的时候,没能正确的应用硬件思想来进行规划,而只是简单地将其划分为几个独立的模块,没能顾及各种控制信号的之间的联系,只是想当然的将其在某种情况下进行修改,但是实际上vhdl是不支持不同进程以及不同时钟沿下对同一信号进行修改的,所以后来将程序写完之后又重新进行了大规模的合并和修改,浪费了很多时间。2.对于时序电路的工作机制不是特别熟悉,然后最初决定需要分出几个频率以及决定频率的大小的时候有点不知所措,后来经过一次次实验和比较,最终采取了分出两个频率,再进一步内分频的模式,其实这样做不是很好,这也是由于前面的模块划分不是那么清楚明确而导致的,在以后的学习工作中应尽量避免出现这样的情况。3.对于上电时的初始化问题,最初设想是能够让系统一上电就能使用,而不是一定要先按下reset键之后才能继续往下,但是这一问题到最后也没能解决,因为对于硬件电路来说,他没有一个固定的执行起点,许多操作都是并行执行的,而且那些控制信号的值刚开始是不确定的,所以后来还是选择了用按键实现初始化操作,这一问题是否有好的解决方法还有待于进一步研究。4.蛇移动时的撞墙问题,最初的计划是打算让蛇碰到边界就会死掉,但还来经过多次测试总是存在问题,最后改为蛇移动到边上后还可以从另外一边穿出,不过最后的形式也是经过了很长时间的摸索才最终实现的,最大的收获就是对信号赋值的理解更深入了一步,信号赋值总是在进程结束时才进行,而且并不像软件中的顺序赋值,所以当你要将你修改过的信号作为一个判断条件时要特别小心,很容易出现差错。5.实现倒计时计数值不按照顺序递减,也即在进行if,else请款判断时没有将所有的情况考虑到,这样会产生时间的跳变,后来增加了时间控制标志位,很好的解决了这一问题。6.吃到老鼠后不加分,这个问题也很让人头疼,因为觉得程序里面的判断语句没有什么逻辑错误,而就是不能实现预期的功能,后来经过认真分析应该是与判断语句存放的位置有关,最后将加分这一操作从原来的move进程移到decide这一进程中,解决了这一问题。7.当老鼠时间到后产生新老鼠时,点阵上会闪的很厉害,一会后才会确定老鼠的位置,后来发现主要产生原因是两个进程之间时的同步问题,因为在move进程中对蛇头坐标修改后,当下一个时钟到来前,若蛇头坐标跟老鼠坐标重合时,在decide进程时钟驱动下(刚开始设置的频率比控制蛇移动的时钟频率高很多)会进行多次判断,只要满足蛇头坐标等于老鼠坐标即会改变老鼠的位置,所以会出现老鼠的位置不断变化的情况,而当蛇移动一步后就不满足此条件,鼠的坐标就不会改变了,后来将产生新老鼠的进程和蛇移动的进程时钟同步起来就解决了这一问题。8.方向键的选择,实验过程中对于采用按键和拨码开
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 烟草自媒体管理办法
- 混凝土超方管理办法
- 用地部征地管理办法
- 煤矿供排水管理办法
- 河南超限站管理办法
- 疫情办公区管理办法
- 砂石矿处置管理办法
- 根据修订了管理办法
- 黄冈水库管理办法
- 生鲜经营与管理办法
- 小学数学六年级上册教材培训材料
- GB/T 9009-2011工业用甲醛溶液
- GB/T 29531-2013泵的振动测量与评价方法
- GB/T 10045-2018非合金钢及细晶粒钢药芯焊丝
- GB 34914-2021净水机水效限定值及水效等级
- 中学田径基础校本课程教材
- 河北省邯郸市各县区乡镇行政村村庄村名居民村民委员会明细及行政区划代码
- 城市规划原理课件(完整版)
- 400T汽车吊主臂起重性能表
- 大信审计执业问题解答-存货监盘审计指引
- 西学中试题库及答案
评论
0/150
提交评论