北邮数电综合实验简易猜数字游戏机的设计与实现.docx
- 文档编号:7880911
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:26
- 大小:1.01MB
北邮数电综合实验简易猜数字游戏机的设计与实现.docx
《北邮数电综合实验简易猜数字游戏机的设计与实现.docx》由会员分享,可在线阅读,更多相关《北邮数电综合实验简易猜数字游戏机的设计与实现.docx(26页珍藏版)》请在冰豆网上搜索。
北邮数电综合实验简易猜数字游戏机的设计与实现
数电综合实验
题目:
简易猜数字游戏机的设计与实现
姓名孙尚威
学院电子工程学院
专业电子信息科学与技术
班级2013211202
学号2013210849
班内序号04
指导教师孙丹丹
2015年11月
摘要:
通过分析题目要求以及实际生活中猜数字游戏机的操作方式,在以Atmel EMP1270T144C5 芯片为核心,拥有按键、点阵、数码管和蜂鸣器等外设的实验板上设计并实现了简易猜数字游戏机。
采用模块化设计思路在Quartus II软件中利用VHDL语言实现模块化电路设计,利用自顶而下的设计思路实现系统整体搭建,并利用Quartus II 软件功能进行仿真和分析。
最终下载到实验板上可流畅运行,无明显逻辑错误,在完成实验要求的基础上,实现了随机数/手动设置数字模式切换功能,led灯提示游戏进行状态等拓展功能。
一、游戏规则简述
通常由两个人玩,一方出数字,另一方猜。
出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。
通过4*4键盘进行4位数字输入,在按下确定键后由猜数字人在规定时间内猜对之前输入的4位数字,过程中系统会给出提示XAYB(A前面的数字表示位置正确的数的个数, B前的数字表示数字正确而位置不对的数的个数。
例:
正确答案为2134,而猜的人猜5314,则是1A2B,其中有一个4的位置对了,记为1A,而1和3这三个数字对了,而位置没对,因此记为2B,合起来就是1A2B)。
接着猜的人再根据出题者的XAYB继续猜,直到猜中即4A0B为止。
二、实验要求
基本要求:
(1)设置游戏机开关以及复位键。
(2)数字设置:
通过4*4键盘进行4位数字输入,在数码管(DISP0~DISP3)上显示当前所输入的数字。
通过设置确定键(BTN1键)进行锁定,此时数码管上的数值消失,同时用点阵开始倒计时,即:
初始状态点阵全亮,然后从右上角开始,由右到左、由下到上逐点逐排依次熄灭,间隔时间为1s,共计64s。
(3)猜数字:
可以通过4*4键盘进行4位数字输入进行猜数字,且每输入一位数字在数码管(DISP0~DISP3)上显示当前所输入的数字,按确定键(BTN2键)进行确认,此时要根据输入的这组数字给出XAYB。
(4)若数字正确则显示猜数字成功,点阵显示“☺”笑脸;若输入数字错误系统仍然处于猜数字状态,点阵显示“X”,并用蜂鸣器报警。
(5)若到点阵全灭时(64s结束)仍未猜出正确数字,游戏失败,点阵显示“囧”。
提高要求:
(1)若数字正确则显示猜数字成功,用蜂鸣器播放一段乐曲。
(2)一键产生4位随机数字。
三、总体设计思路
功能流程图:
四、 功能模块的设计和实现
系统共通过8个模块实现,分别是:
游戏控制(状态机)、分频器、键盘模块、点阵显示模块、数码管显示、倒计时模块、随机数生成器、音乐播放这8个模块实现的,具体设计如下。
(1)游戏控制模块(ssw)
1. 模块设计思路
使用状态机进行编写,共计7个状态分别是:
空闲(idle)、设定数字(set_number)、猜数字(guess_number)、比较判断(compare)、正确(smile)、错误(false)、倒计时结束(jiong)。
各状态间通过外接按键以及其他模块传递过来的控制信号进行转移。
在不同的状态下输出不同的状态标志信号对后续模块进行控制。
状态转移图如图
2. 外部接口设计
设计输入端口:
时钟信号clk_scan:
STD_LOGIC,频率2KHz;
复位信号reset:
STD_LOGIC,使状态机复位到空闲(idle)状态;
开始信号start :
STD_LOGIC,使状态由空闲(idle)状态转移到设定数字
(set_number)状态,开始游戏;
设置数字保存set_save:
STD_LOGIC,使状态由设定数字(set_number)转移到
猜数字(guess_number)状态,保存设置数字;
猜数字保存guess_save:
STD_LOGIC,使状态由猜数字(guess_number)转移到
比较判断(compare)状态,进行状态转移判断;
猜数字正确信号win:
STD_LOGIC,使状态由比较判断(compare)状态转移到
正确(smile)状态,输出笑脸信号给点阵和音乐信号给音乐播放
模块;
猜数字错误信号wrong:
STD_LOGIC,使状态由比较判断(compare)状态转移
到错误(false)状态,输出X信号给点阵和报警信号给音乐播放
模块;
显示等待信号done:
STD_LOGIC,使状态由错误(false)状态转移到猜数字
(guess_number)状态;
倒计时结束信号time_over:
STD_LOGIC,使状态由猜数字(guess_number)状
态转移到倒计时结束(jiong)状态,输出囧信号给点阵;
设计输出端口:
当前状态机信号state_flag:
STD_LOGIC_VECTOR(3downto0),输出不同状态下
状态机标志,方便后续模块对当前状态做正确判断和调用,同时
作为led输出,提示当前状态;
蜂鸣器状态信号bee:
STD_LOGIC_VECTOR(1DOWNTO0),输出不同状态下
蜂鸣器产生不同声音的信号;
点阵显示信号display:
INTEGERRANGE0TO4,输出不同判断结果状态下点阵
显示标志,控制点阵模块显示不同图形。
3、关键代码
p1:
PROCESS(start,set_save,guess_save,reset,time_over,done,win,wrong,state)
--changenext_state4
BEGIN
next_state<=state;
IFreset='1'THENnext_state<=idle;
ELSE
CASEstateIS
WHENidle=>
IFstart='1'THENnext_state<=setnum;
ELSEnext_state<=idle;
ENDIF;
WHENsetnum=>
IFset_save='1'THEN
next_state<=guessnum;
ELSEnext_state<=setnum;
ENDIF;
WHENguessnum=>
IFguess_save='1'THEN
next_state<=compare;
ELSIFtime_over='1'THEN
next_state<=jiong;
ELSEnext_state<=guessnum;
ENDIF;
WHENcompare=>
--IFdone='1'THEN
IFwin='1'THEN
next_state<=smile;
ELSIFwrong='1'THEN
next_state<=false;
--ENDIF;
ELSEnext_state<=compare;
ENDIF;
WHENsmile=>
IFstart='1'THEN
next_state<=idle;
ELSEnext_state<=smile;
ENDIF;
WHENjiong=>
IFstart='1'THEN
next_state<=idle;
ELSEnext_state<=jiong;
ENDIF;
WHENfalse=>
IFtime_over='0'anddone='1'THEN
next_state<=guessnum;
ELSEnext_state<=false;
ENDIF;
WHENOTHERS=>next_state<=idle;
ENDCASE;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk_scan)
BEGIN
IFclk_scan'eventANDclk_scan='1'THEN
CASEstateIS
WHENidle=>
state_flag<="1000";
display<=4;
bee<="00";
WHENsetnum=>
state_flag<="0100";
display<=4;
bee<="00";
WHENguessnum=>
state_flag<="0010";
display<=0;
bee<="00";
WHENcompare=>
state_flag<="0001";
display<=4;
bee<="00";
WHENsmile=>
state_flag<="1111";
display<=2;
bee<="11";
WHENjiong=>
state_flag<="0111";
display<=1;
bee<="00";
WHENfalse=>
state_flag<="0011";
display<=3;
bee<="01";
WHENOTHERS=>
state_flag<="1000";
display<=4;
bee<="00";
ENDCASE;
state<=next_state;
ENDIF;
ENDPROCESSp2;
endarch;
4、仿真图及说明
(2)分频模块(div)
1. 模块设计思路
对实验板上25MHz时钟进行分频,分别输出2KHz,10Hz,1Hz。
为其他模块提供合适的时钟。
2. 外部接口设计
设计输入端口:
时钟输入clk:
STD_LOGIC,实验板上待分频的高频时钟信号;
设计输出端口:
时钟输出clk_scan:
STD_LOGIC,输出2KHz信号,为显示模块提供扫描时钟;
时钟输出clk_10hz:
STD_LOGIC,输出10Hz信号,为音乐模块提供频率时钟;
时钟输出clk_count:
STD_LOGIC,输出1Hz信号,为倒计时模块提供时钟;
3、关键代码
P1:
PROCESS(clk)
BEGIN
IFclk'eventANDclk='1'THEN
IFtmp1=24999THEN
tmp1<=0;clktmp1<=notclktmp1;
ELSE
tmp1<=tmp1+1;
ENDIF;
ENDIF;
ENDPROCESSP1;
P2:
PROCESS(clk)
BEGIN
IFclk'eventANDclk='1'THEN
IFtmp2=12499999THEN
tmp2<=0;clktmp2<=notclktmp2;
ELSE
tmp2<=tmp2+1;
ENDIF;
ENDIF;
ENDPROCESSP2;
P3:
PROCESS(clk)
BEGIN
IFclk'eventANDclk='1'THEN
IFtmp3=1249999THEN
tmp3<=0;clktmp3<=notclktmp3;
ELSE
tmp3<=tmp3+1;
ENDIF;
ENDIF;
ENDPROCESSP3;
clk_scan<=clktmp1;
clk_count<=clktmp2;
clk_10hz<=clktmp3;
ENDa;
(3)键盘模块(key)
1. 模块设计思路
判断键盘中有无按键按下是通过行先送入扫描信号,然后从列线读取状态后得到的。
其方法是依次给行线送低电平,检查列线的输入。
如果列线信号全为高电平,则代表低电平信号所在的行中无键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交叉点有键按下。
2. 外部接口设计
设计输入端口:
时钟输入clk_scan:
STD_LOGIC,输入2KHz信号,为键盘模块提供扫描时钟;
当前状态机信号state_flag:
STD_LOGIC_VECTOR(3downto0),输入当前状态下
状态机标志,在不同状态下键入不同的值;
扫描信号key_row:
STD_LOGIC_VECTOR(3downto0),依次给行线送低电平;
设计输出端口:
键值信号key1:
STD_LOGIC_VECTOR(6DOWNTO0),输出简直信号给数码管
显示模块;
检查列线scan_out:
:
STD_LOGIC_VECTOR(3downto0),如果列线信号全为高电
平,则代表低电平信号所在的行中无键按下;如果列线有输入为低电
平,则低电平信号所在的行和出现低电平的列的交叉点有键按下。
3、关键代码
p1:
PROCESS(clk_scan)--scan
BEGIN
IFclk_scan'eventANDclk_scan='1'THEN
CASEscanIS
WHEN"1110"=>scan<="0111";
WHEN"0111"=>scan<="1011";
WHEN"1011"=>scan<="1101";
WHEN"1101"=>scan<="1110";
WHENOTHERS=>scan<="0111";
ENDCASE;
scan_out<=scan;
ENDIF;
ENDPROCESSp1;
p2:
PROCESS(clk_scan)--keyin
BEGIN
IFclk_scan'eventANDclk_scan='1'THEN
--ifstate_flag="1000"orstate_flag="1111"then
--key1<="0000000";
--endif;
CASEkey_rowIS
WHEN"0111"=>
CASEscanIS
WHEN"0111"=>key1<="1110111";--a
WHEN"1011"=>key1<="0110000";--1
WHEN"1101"=>key1<="1101101";--2
WHEN"1110"=>key1<="1111001";--3
WHENOTHERS=>NULL;
ENDCASE;
WHEN"1011"=>
CASEscanIS
WHEN"0111"=>key1<="0011111";--b
WHEN"1011"=>key1<="0110011";--4
WHEN"1101"=>key1<="1011011";--5
WHEN"1110"=>key1<="1011111";--6
WHENOTHERS=>NULL;
ENDCASE;
WHEN"1101"=>
CASEscanIS
WHEN"0111"=>key1<="1001110";--c
WHEN"1011"=>key1<="1110000";--7
WHEN"1101"=>key1<="1111111";--8
WHEN"1110"=>key1<="1111011";--9
WHENOTHERS=>NULL;
ENDCASE;
WHEN"1110"=>
CASEscanIS
WHEN"0111"=>key1<="0111101";--d
WHEN"1011"=>key1<="0000001";--
WHEN"1101"=>key1<="1111110";--0
WHEN"1110"=>key1<="0000001";--
WHENOTHERS=>NULL;
ENDCASE;
WHENOTHERS=>NULL;
ENDCASE;
ENDIF;
ENDPROCESSp2;
(4)键盘模块(key)
1. 模块设计思路
判断键盘中有无按键按下是通过行先送入扫描信号,然后从列线读取状态后得到的。
其方法是依次给行线送低电平,检查列线的输入。
如果列线信号全为高电平,则代表低电平信号所在的行中无键按下;如果列线有输入为低电平,则低电平信号所在的行和出现低电平的列的交叉点有键按下。
2. 外部接口设计
设计输入端口:
时钟输入clk_scan:
STD_LOGIC,输入2KHz信号,为点阵模块提供扫描时钟;
当前状态机信号state_flag:
STD_LOGIC_VECTOR(3downto0),输入当前状态下
状态机标志,在不同状态下键入不同的值;
倒计时清零信号count_clear:
STD_LOGIC,倒计时模块清零;
设计输出端口:
倒计时结束信号time_over:
STD_LOGIC,倒计时结束后将结束信号传递给状态
机模块切换状态;
倒计时count_down:
inout:
INTEGERRANGE0TO64,64s倒计时,同时将当
前倒计时状态传递给点阵显示模块。
3、关键代码
PROCESS(clk_count)
BEGIN
IFcount_clear='1'THEN
count_down<=0;time_over<='0';
--ENDIF;
ELSIFstate_flag="0010"THEN
IFclk_count'eventANDclk_count='1'THEN
IFcount_down=64THEN
time_over<='1';count_down<=0;
ELSEcount_down<=count_down+1;
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
(5)点阵显示模块(dot_led)
1. 模块设计思路
LED点阵显示由8*8共64个发光二极管组成。
控制时,分别控制阳极8个行控制口和阴极8个列控制口。
显示时,向阳极送字模,向阴极送选通信号。
送出一行的字模,再送选通信号,再送第二行的字模和选通信号,循环扫描8次,就可以在一块点阵上显示一个字符。
2. 外部接口设计
设计输入端口:
时钟输入clk_count:
STD_LOGIC,输入1Hz信号,为倒计时模块提供扫描时钟;
点阵显示信号display:
INTEGERRANGE0TO4,输入不同判断结果状态下点阵
显示标志,控制点阵模块显示不同图形。
设计输出端口:
点阵行输出dot_led_row:
STD_LOGIC_VECTOR(7downto0)
点阵列输出dot_led_col:
STD_LOGIC_VECTOR(7downto0)
3、关键代码
PROCESS(clk_scan)--displayled
BEGIN
IFclk_scan'eventANDclk_scan='1'THEN
IFdisplay=1THEN
CASEled_rowIS
WHEN"10111111"=>led_row<="01111111";led_col<="11111111";
WHEN"11011111"=>led_row<="10111111";led_col<="10011001";
WHEN"11101111"=>led_row<="11011111";led_col<="10100101";
WHEN"11110111"=>led_row<="11101111";led_col<="11000011";
WHEN"11111011"=>led_row<="11110111";led_col<="10111101";
WHEN"11111101"=>led_row<="11111011";led_col<="10100101";
WHEN"11111110"=>led_row<="11111101";led_col<="10100101";
WHEN"01111111"=>led_row<="11111110";led_col<="11111111";
WHENOTHERS=>led_row<="01111111";led_col<="11111111";
ENDCASE;
(6)点阵显示模块(dot_led)
1. 模块设计思路
将已经设置的四位数字和猜的四位数字进行循环比较,得出XAYB中X、Y值,并在数码管上进行显示。
根据状态标志符的不同显示以输入的四位数字。
2. 外部接口设计
设计输入端口:
时钟输入clk_scan:
STD_LOGIC,输入2KHz信号,为数码管模块提供扫描时钟;
键值信号key1:
STD_LOGIC_VECTOR(6DOWNTO0),输入已键入四位数字的
数码管译码信号;
键值信号key2:
STD_LOGIC_VECTOR(6DOWNTO0),输入随机生成的四位数
字的数码管译码信号;
当前状态机信号state_flag:
STD_LOGIC_VECTOR(3downto0),输入当前状态下
状态机标志,在不同状态下显示不同的输入值;
模式选择信号mode:
STD_LOGIC,通过拨码开关选择设置的四位数字是认为输
入的还是随机生成模式
设计输出端口:
猜数字正确信号win:
STD_LOGIC,使状态机模块由比较判断(compare)状态
转移到正确(smile)状态,输出笑脸信号
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 北邮数电 综合 实验 简易 数字 游戏机 设计 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)