数电综合实验报告-贪吃蛇_第1页
数电综合实验报告-贪吃蛇_第2页
数电综合实验报告-贪吃蛇_第3页
数电综合实验报告-贪吃蛇_第4页
数电综合实验报告-贪吃蛇_第5页
已阅读5页,还剩14页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

1、北 京 邮 电 大 学实验名称: 学 姓 班 学 信息与通信工程一 用一个 88 点阵作为基本显示屏,4 个连续移动的的发光点表示一条蛇,用任意出现的一个亮点表示老鼠,用4 个排成一条线的发光点表示“墙”,用 四个按键控制蛇的运动方向,完成贪食蛇游戏,蛇撞“墙”、边或者游戏时间 到,则游戏结束。(1). 老鼠出现的地方是随机的,在某个地点出现的时间是5秒钟,如果5秒钟之内没有被吃掉,它就会在其它地方随机出现;(2). 用数码管显示得分情况和游戏的剩余时间,每吃掉一只老鼠就加一分。二 采取模块化的设计思想,主要分为控制和显示模块,控制模块主要针对各种控制信号进行控制处理,比如蛇的移动,倒计时,方

2、向控制等,而进行控 制时,控制图形的变化的信号有很多,有外部按键输入,内部时钟驱动,判断 的状态也比较多,蛇的位置,老鼠的位置,墙的位置等,在设计过程中将操作 “串行化”,即利用高速时钟将判断和操作过程分为多个周期完成,简化设计。 而显示模块主要完成鼠,蛇,墙以及分数,剩余时间的显示,而此模块要独立 于显示内容,其内容与控制模块进行修改,这样使两个模块可以独立地进行工 作,具有很好的扩展性和实现性。2. 总体框图鼠4点流程图:否是是否5否是上下左右是是是是否否否MDS 图:starttimeou计分器点阵显示计时器 分频器Start/pause控制模块3.模块设计(1)分频模块:由于实验板上的

3、时钟频率为 50MHZ,相对于电路延时时间来说,频率太高,故需要分频将频率降低来适应器件的反应时间要求;同时用来扫描点阵和数码 管的频率与用来控制的时钟信号频率是不同的,相对而言用来扫描显示的频率 要相对低一些,用来扫描按键和控制的时钟频率要低一些,所以此处将50MHZ 的频率分为1MHZ和 2KHZ,1MHZ的频率用来扫描按键和进行信号控制,2KHZ用 于扫描显示,在控制模块中,又进行了二次分频,用来控制蛇的移动,鼠步的 减少,倒计时时间等,不选择直接在分频模块中将所有的所需时钟频率全部分 出的原因是在不同的进程中可能会对同一控制信号进行修改,所以这样就会出 现多重驱动的问题,然而在进程内部

4、进行二次分频就可以避免出现这种情况。 (2)游戏控制模块:这部分又可细分为四个小的模块:蛇状态判断模块,鼠随机产生模块,方向控制模块,蛇移动及时间控制模块。1. 的情况有:按下reset键,改变开始暂停键的状态,蛇撞墙,总计是时间到,以及游戏通关(即游戏总得分为3 reset键的 优先级最高,当按下 reset 当“start/pause”键状态为“1”的话蛇的状态将会被置成“活( 总时间到,通关都会将蛇的状态置为“死(0)”。2. 鼠随机产生模块:这部分主要完成产生新的老鼠坐标,思路是利用两个不同模值的计数器,分别对 8 取模,获得 0 到 7 之间的两个数作为新老鼠的横纵坐标,同时对产生的

5、新左边进行判断,当和墙的坐标重合时进行修正,此处是将横坐标减一。而新老鼠的产生时刻是总计是时间到,鼠被吃掉,或蛇走十步后,刚开始是把这一部分单独作为一个线程,但是后来由于对鼠的产生标志信号的控制不是很好处理,所以这部分只是负责产生下次新老鼠的位置坐标,而真正的赋值操作在对蛇的控制状态线程里面。3. 方向控制模块:主要对控制蛇移动方向的信号进行修改,敏感信号为 reset键和按键扫描时钟,但 reset 键的优先级较高,当 reset键按下时,方向控制信号将会被设置成默认的向右,而其他四个方向控制键的检测则是在时钟信号的驱动下进行,由于按键扫描时钟频率为 1MHZ,相对较高,所以不会有很大的迟钝

6、感觉。4. 蛇移动和倒计时模块:由于此处设计的蛇移动时间间隔恰好是一秒,和倒计时的时间间隔一样,所以将这两个功能放在了一个进程中,这个进程中同时包含对蛇初始位置,总计时时间,鼠步的初始时间等初始化设置,原因也是为了避免出现双重驱动的问题。此处的时钟信号为 1MHZ,在此线程内部进行了二次分频将其分为 1HZ,用来控制蛇的移动以及时间 计数,在 1HZ 时钟的驱动下进行剩余时间,剩余鼠步,以及蛇位置坐标的修改控制。(3)显示模块:此模块主要完成鼠,墙,蛇,分数,剩余时间的显示,因为要同时显示这几项,故需要进行动态扫描,即在某一时间段内只显示其中一位,程序中用一 个模为六的计数器实现在不同的计数值

7、下显示不同的项,分别如下:T=0 时,扫描老鼠坐标T=1 时,扫描蛇头坐标和右边第一个数码管为 SCORE显示T=2 时,扫描蛇身2 坐标T=3 时,扫描蛇身3 坐标和左边第一个数码管为总计时高位计时显示T=4 时,扫描蛇身4 坐标。T=5 时,扫描墙的坐标和左边第四个数码管为总计时的低位计时显示1.游戏初始化:按下认移动方向,游戏总时间进行初始化设置,此时分数显示为零,时间为六十秒。2.游戏开始和暂停:当初始化之后将sw0拨上去即为开始游戏,拨下来即为暂停,暂停后蛇,鼠的位置保持不变,分数时间保持不变,再次将sw0 拨回去即可继续游戏。3.方向控制:btn7,btn6,btn5,btn44.

8、当蛇撞墙时,蛇死,游戏重启。5.当游戏总时间到时,游戏重启。6.当老鼠十秒后没有被吃掉将会出现在别的地方。7.当老鼠被蛇吃掉后将会出现新的老鼠,并且分数将会加一分。8.当吃鼠分数达到三分时,点阵将会全亮,分数固定显示,剩余时间位熄灭,表示游戏通关,按下 reset键可重新开始游戏。仿真时的 clk_kscan频率为clk_sscan的2倍,clk_kscan的内部分频比为 1:100.(1)按下 reset键后鼠,蛇的位置初始化, 故变(2)蛇的位置右移(3)分数和时间的初始化显示6(4)在仿真波形的设置中曾将 direction上,同时也可观察新老鼠的产生(5)在游戏过程中再次按按下 res

9、et(6)总得计时时间的变化(1)分频模块library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity divisport(clk:instd_logic;clk_s,clk_k:outstd_logic);end entity;architecture div_aofdiv issignal counter_sscan:integerrange0to 24999; -分频得2khz时钟signal counter_kscan:integerrange0to 49;-分频得1mhz时钟begind

10、iv_sscan1:process(clk)beginif clkeventand clk=1thenif counter_sscan=24999 thencounter_sscan=0;elsecounter_sscan=counter_sscan+1;end if;end if;end processdiv_sscan1;div_sscan2:process(counter_sscan)beginif counter_sscan12499 thenclk_s=1;-占空比为50%else clk_s=0;end if;end processdiv_sscan2;div_kscan1:pro

11、cess(clk)beginif clkeventand clk=1thenif counter_kscan=49thencounter_kscan=0;elsecounter_kscan=counter_kscan+1;end if ;end if;end processdiv_kscan1;div_kscan2:process(counter_kscan)beginif counter_kscan25thenclk_k=1;else clk_k=0;end if;end processdiv_kscan2;end div_a;(2)主程序模块library ieee;use ieee.st

12、d_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity Tancsisport(clkk:in std_logic;start:in std_logic;reset:in std_logic;-系统时钟-开始/暂停按键-重启按键direction:in std_logic_vector(3 downto 0); -方向控制按键row:out std_logic_vector(7 downto 0); -点阵的行输出col:out std_logic_vector(7downto0)

13、; -点阵的列输出d_light:outstd_logic_vector(6downto 0); -数码管的段选输出w_light:outstd_logic_vector(5downto 0) -数码管的位选输出);end Tancs;architecturetancs_aof Tancsissignal clk_sscan:std_logic; -用于扫面显示的时钟信号signal clk_kscan:std_logic; -用于按键扫描的时钟信号signal timeh:integerrange0to9; -剩余时间的高位signal timel:integerrange0to9; -剩余

14、时间的低位signal mousetime:integerrange0to 9; -剩余老鼠时间signal score:integerrange0to9; -得分signal temp_show:integerrange0to 5; -用于动态显示的计数器signal temp_light:integerrange0to 9; -用于暂存需要显示的数码的-段码signal temp_turn:integerrange0to 3; -用于方向控制的信号 signalmcx:integer range 0 to 100; -用于随机产生老鼠横坐标的计数器signal mcy:integer ra

15、nge0to 200; -用于随机产生老鼠纵坐标的计数器signal time_flag:std_logic; -剩余时间是否用完的标志位signal counter_move:integerrange0to 1499999; -内分频计数器signal state:std_logic; 为死signal sx0,sy0,sx1,sy1,sx2,sy2,sx3,sy3, -蛇的当前位置坐标wx,wy0,wy1,wy2,wy3, -墙的位置坐标moux,mouy,mouxx,mouyy:integerrange0to7; -暂存下个老鼠的位置坐标componentdiv -原件例化port(cl

16、k:instd_logic;clk_s,clk_k:outstd_logic);end component;-老鼠的当前位置坐标beginu1:div port 口映射wx=5;wy0=5;wy1=4;wy2=3;wy3=2;decide:process(clk_kscan,reset)beginif reset=1then-检测reset键state=0;score=0;moux=3;mouy=4;elsif clk_kscaneventandclk_kscan=1thenif start=1then state=1; -检测start/pause键end if;if counter_mov

17、e=1499999 then-内分频,所得频率为一秒(实际分频-时若果计数器的值按照理值去设置所得的时钟频率明显快于一秒,故此 处将计-数模值加大为原来的1.5倍)if time_flag=0thenstate=0;-剩余时间为零if mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 ormouyy=wy3) then -判断下个要产生老鼠的位置是否与墙重合moux=mouxx-1;else moux=mouxx;-进行新老鼠位置的赋值end if;mouy=mouyy;elsif (sx0=wxand(sy0=wy0or sy0=wy1orsy

18、0=wy2 or sy0=wy3)then-蛇撞墙state=0;if mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 ormouyy=wy3)thenmoux=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 ormouyy=wy3)thenmoux=mouxx-1;else moux=mouxx;end if;mouy=mouyy;

19、end if;if sx0=mouxand sy0=mouythen -老鼠被吃掉,分数加一score=score+1;if (mouxx=wx and(mouyy=wy0 or mouyy=wy1 or mouyy=wy2 ormouyy=wy3)thenmoux=mouxx-1;else moux=mouxx;end if;mouy=mouyy;end if;if score=3then -得分为3分时游戏通关state=0;end if;end if;end if;end processdecide;random:process(clk_kscan)begin- 用于产生随机老鼠的进程i

20、f clk_kscaneventandclk_kscan=1thenif mcx=100thenmcx=0;else mcx=mcx+1;end if;if mcy=200thenmcy=0;else mcy=mcy+1;end if;mouxx=mcxrem8;-产生0到7的老鼠的坐标mouyy=mcyrem8;end if;end processrandom;dirc:process(clk_kscan,reset) -方向控制进程beginif reset=1then-reset键检测temp_turniftemp_turn/=2thentemp_turniftemp_turn/=0th

21、entemp_turniftemp_turn/=1thentemp_turniftemp_turn/=3thentemp_turntemp_turn=temp_turn;end case;end if;end process dirc;move:process(clk_kscan,state)beginif 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; -将初始剩余时间标志设为1elsif clk_ks

22、caneventandclk_kscan=1thenif state=1andstart=1 then-开始键为一时才开始移动if counter_move=1499999 thenif mousetime=0thenmousetime=9;-老鼠时间的控制elsemousetime=mousetime-1;end if;if timel=0and timeh/=0thentimel=9;-总游戏剩余时间的控制timeh=timeh-1;time_flag=1;elsif timel=0and timeh=0thentime_flag=0;elsetimel=timel-1;time_flag

23、ifsy0=7thensy0=sy0-7;else sy0ifsy0=0thensy0=sy0+7;else sy0ifsx0=7thensx0=sx0-7;else sx0ifsx0=0thensx0=sx0+7;else sx0=sx0-1;end if;end case;sx1=sx0;sy1=sy0;sx2=sx1;sy2=sy1;sx3=sx2;sy3=sy2;if sx0=mouxand sy0=mouythenmousetime=9;-蛇吃鼠后鼠剩余时间的重置-内分频计数器加一end if;counter_move=0;else counter_move=counter_move

24、+1;end if;end if;end if;end process move;show:process(clk_sscan)begin-数码管和点阵扫描显示进程if clk_sscaneventandclk_sscan=1thenrow=11111111;-将所有的行置1,列置0(新实验-板的列为1,行为0时点被点亮)col=00000000;if temp_show=5thentemp_show=0;elsetemp_show=temp_show+1;end if;if score=3thencol=11111111;row=00000000;temp_light=score;w_lig

25、htcol(moux)=1;row(mouy)=0; -显示老鼠坐标temp_light=score;w_lightcol(sx0)=1;row(sy0)=0;w_lightcol(sx1)=1;row(sy1)=0; -显示蛇身第二个坐标temp_light=timeh;w_lightcol(sx2)=1;row(sy2)=0;w_lightcol(sx3)=1;row(sy3)=0; -显示蛇身的第四个坐标temp_light=timel;w_lightcol(wx)=1;row(wy0)=0; -显示时间的低位和墙的位置w_light=101111;row(wy1)=0;row(wy2)

26、=0;row(wy3)d_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_lightd_light=0000000;end case;end if;end processlightshow;end tancs_a;系统时钟:CLK重启按键 RESET:BTN0开始/暂停按键:SW0方向控制键:BTN7,BTN6,BTN5,BTN4点阵行显示:ROW0ROW7点阵列显示:COL0COL7数码管的段选:AA,AB,AC,AD,AE,AF,AG数码管的位选信号:CAT0-CAT52.资源利用情况1.在对整个系统的模块进行划

27、分的时候,没能正确的应用硬件思想来进行规划,而只是简单地将其划分为几个独立的模块,没能顾及各种控制信号的 之间的联系,只是想当然的将其在某种情况下进行修改,但是实际上 vhdl 是不支持不同进程以及不同时钟沿下对同一信号进行修改的,所以后来将程序写完 之后又重新进行了大规模的合并和修改,浪费了很多时间。2.对于时序电路的工作机制不是特别熟悉,然后最初决定需要分出几个频率以及决定频率的大小的时候有点不知所措,后来经过一次次实验和比较, 最终采取了分出两个频率,再进一步内分频的模式,其实这样做不是很好,这 也是由于前面的模块划分不是那么清楚明确而导致的,在以后的学习工作中应 尽量避免出现这样的情况

28、。3.对于上电时的初始化问题,最初设想是能够让系统一上电就能使用,而不是一定要先按下 reset键之后才能继续往下,但是这一问题到最后也没能解决,因为对于硬件电路来说,他没有一个固定的执行起点,许多操作都是并 行执行的,而且那些控制信号的值刚开始是不确定的,所以后来还是选择了用 按键实现初始化操作,这一问题是否有好的解决方法还有待于进一步研究。4.蛇移动时的撞墙问题,最初的计划是打算让蛇碰到边界就会死掉,但还来经过多次测试总是存在问题,最后改为蛇移动到边上后还可以从另外一边 穿出,不过最后的形式也是经过了很长时间的摸索才最终实现的,最大的收获 就是对信号赋值的理解更深入了一步,信号赋值总是在进

29、程结束时才进行,而 且并不像软件中的顺序赋值,所以当你要将你修改过的信号作为一个判断条件 时要特别小心,很容易出现差错。5.实现倒计时计数值不按照顺序递减,也即在进行 if,else请款判断时没有将所有的情况考虑到,这样会产生时间的跳变,后来增加了时间控制标志 位,很好的解决了这一问题。6.吃到老鼠后不加分,这个问题也很让人头疼,因为觉得程序里面的判断语句没有什么逻辑错误,而就是不能实现预期的功能,后来经过认真分析应 该是与判断语句存放的位置有关,最后将加分这一操作从原来的 move 进程移到decide 这一进程中,解决了这一问题。7.当老鼠时间到后产生新老鼠时,点阵上会闪的很厉害,一会后才会确定老鼠的位置,后来发现主要产生原因是两个进程之间时的同步问题,因为在move 进程中对蛇头坐标修改后,当下一个时钟到来前,若蛇头坐标跟老鼠坐标重合时,在decide进程时钟驱动下(刚开始设置的频率比控制蛇移动的时钟频率高很多)会进行多次判断,只要满足蛇头坐标等于老鼠坐标即会改变老鼠的位置,所以会出现老鼠的位置不断变化的情况,而当蛇移动一步后就不满足此条件,鼠的坐标就不会改变了,后来将产生新老鼠的进程和蛇移动的进程时钟同步起来就解

温馨提示

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

评论

0/150

提交评论