1、 北京邮电大学 数电实验综合课题设计与实现 实验名称:拔河游戏机 班级:2008211132 序号 :11 姓名:杨光熙 学号:08210874 目录 1. 设计课题的任务要求 3
2、 2. 系统设计 3 3. 仿真波形及波形分析 12 4. 源程序 15 5. 功能说明 31 6. 实验元器件清单及资源利用情况 32 7. 实验故障及问题分析 32 8. 实验总结 33 ****************设计课题的任务要求***************** 一、基本任务: 用7 个发光二极管排列成一行,模拟拔河过程。游戏开始时只有中间的发光二极管点亮,作为拔河的中心线。用按键来模拟拔河队员,按下键表示用力,根据甲乙双方按键的快慢
3、与多少,决定亮点移动的方向。移到任一方终端二极管时,该方获胜,该方记分牌自动加分,然后开始下一局的比赛。比赛采用五局三胜制,甲乙双方各自记分。当记分牌清零后,重新开始下一场拔河比赛。 1、设置“比赛开始”按键,实现一对一拔河; 2、设置复位键,按下后比分清零,双方重新开始比赛; 3、一场比赛结束时演奏一首欢快的曲子; 二、提高要求: 1、甲乙双方可选一到多个队员进行比赛; 2、自拟其它功能。 ***********************系统设计******************** 【设计思路】 1、10秒倒计时的实现: 电路接1M晶振的时钟,从10秒开始计时。
4、用变量us计算时钟个数,用present_state显示点阵的当前状态,每1M个时钟,修改一次变量num的值,用num控制8x8点阵显示的数字。从而实现10秒倒计时。并且设置开始键”reset”,按下后重新开始计时。 2、10秒倒计时的显示: 采用逐列扫描的方式,对行像素分别编码,利用人眼色觉暂留效应,以1MHZ的频率扫描列,点阵上就会出现稳定的数字。 3、拔河游戏的实现: Ⅰ、当倒计时到0秒时,游戏才能正常显示; Ⅱ、设置游戏开始键”start”,实现一对一拔河。按下按键后游戏开始,点亮第4 个发光二极管(拔河的中心点),双方的比分清零; Ⅲ、用两个按键”player1”、”
5、player2”代表比赛的甲乙双方。甲方每按” player 1”键10次,亮点向左移动一点;乙方每按” player 2”键10次,亮点向右移动一点。当亮点到达最左边(第一个点),甲方胜利;反之,亮点到达最右边(第七个点),乙方胜利。 Ⅳ、当有一方胜利后,蜂鸣器发声。 4、各个模块功能: Ⅰ、绳子显示模块:输入为两路脉冲信号,对两路脉冲分别记数,然后解码后控制LED灯亮灭的位置; Ⅱ、计分模块:每当LED灯移动到LED0或者LED6时,产生一个下降沿信号,然后七段数码管的计数器增加,然后将当前的所胜得局数显示在七段数码管上; Ⅲ、乐曲模块:在每局比赛结束后,即产生下降沿信号后,
6、播放乐曲; Ⅳ、开关及复位控制:比赛开始前需要将“start”设置为1,否则按键信号输入不起作用;当比赛结束后或者在比赛过程中,按下“start”则状态返回到最初的起始状态; Ⅴ、控制电路:在LED灯移动到最左边或者最右边时,产生一个控制信号,使计数器停止计数,使乐曲播放,并将此信号作为七段数码管使能端的输入信号。 【总体框图】 ASM图: 开始 start是否为1 触发记时器(1秒) no,循环检测 yes 检测参赛者是否有按键脉冲 no,循环
7、检测 1秒时间到 判断是否到最左或者最右 对两路脉冲分别进行计数,存于count1、coun2 yes 蜂鸣 锁定count1,count2 译码,控制LED灯显示位置,并清零count1,count2 yes 在七段数码管上显示 胜利局数加一
8、 判断是否有一方胜利
9、 no 将灯状态锁定,显示也不变 yes 检测复位键是否按下 no,继续返回 yes,计分器清零 MDS图: start=0 Wait start=1 LED
10、4(中间灯)
count2>count1 count1>count2
灯右移
count2>count1 count1 11、
Victory=3
检测复位键
BT4=1 计分器清零
【分块设计】
计时进程:
数据处理进程:
显示控制进程:
【点阵设计】
1、点阵列管脚信号编码:
其中col的编码从右到左依次是点阵列管脚1-8的输入信号,即给要显示的列管脚输入低电平,其他管脚为 12、高电位。
2、点阵行管脚信号编码
比如数
字4的点阵行编码为:
case c is
when 1=>row<="00000000";
when 2=>row<="00000000";
when 3=>row<="00001100";
when 4=>row<="0001010 13、0";
when 5=>row<="00100100";
when 6=>row<="01111111";
when 7=>row<="00000100";
when 8=>row<="00000000";
end case;
其中row的编码从右到左依次是点阵行管脚1-8的输入信号,即在显示的某列时,输入该列相应的行编码,显示的行输入高电平,反之输入低电平。
3、发光二极管信号编码:
其中led的编码从右到左依次是发光二极管1-8的输入信号,即给要亮的灯输入高电平,其他灯为低电位。
**************** 14、仿真波形及波形分析*******************
1、 倒计时电路的仿真:由于频率太高,不易仿真,以下的仿真假设每8us为倒计时的1s,即8个时钟改变一次显示的数字。
从10开始倒计时,点阵列管脚从左到右进行扫描,依次赋值为低电平。同时对该列的行管脚进行编码赋值,以较高的频率进行重复扫描,便可以显示相应的数字。由于恰好是从左往右扫描的,所以可以在以上的仿真波形比较明显的看出显示的数字(第一幅波形显示的是10~7,第二幅波形显示的是7~4,第三幅波形中显示的是4~0)。倒计时到0后,点阵就一直显示数字0。且拔河 15、游戏机不工作,8盏灯都不亮,蜂鸣器不响。
2.拔河游戏机的仿真:电路板上共有8盏灯,游戏中现使用前7盏。
从以上的仿真波形中可以看到,当player2一直在赢的时候,代表它的三盏灯逐渐转移,知道达到终点,即点亮的灯(拔河的中心点)到达最左边的第一盏灯时(甲方胜利),播放音乐,表示其胜出。
上图表示,当player2赢了一局之后,有”start”复位,如果player2还是一直赢,代表它的等继续相继转移,知道终点。这是一个循环过程。
上图表示,当player2赢了一局之后,有”start”复位,如果复位后,双方都没有按键,则中点一直保持在原 16、状态,不发生偏移。
***********************源程序**********************
【顶层模块】
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity bahe is
port(
player1,player2:in std_logic; --玩家1,2输入
clk_in:in std_logic; --clk_in(1MHZ)
reset:in std_logic; --重置键
17、 row : out std_logic_vector(7 downto 0);
col : out std_logic_vector(7 downto 0);
led:out std_logic_vector(7 downto 0); --绳子
cats:out std_logic_vector(6 downto 0); --比分
q:out std_logic_vector(5 downto 0); --数码管控制
mus:out std_logic); --蜂鸣输出
end bahe;
architecture body_bahe of 18、bahe is
component division --分频模块
port(
clk_in:in std_logic; --1MHZ输入
clk_100,clk_5,clk_1:out std_logic);--100HZ,5Hz,1HZ
end component;
component count --计数模块
port(
clk_1:in std_logic; --1HZ输入
sw:in std_logic; --状态开关
player1,player2:in std_l 19、ogic; --选手输入
sum1,sum2:out std_logic_vector(4 downto 0)); --计数结果输出
end component;
component cmp --比较模块
port(
clk_100:in std_logic; --100hz
clk_1:in std_logic; --1hz
sw:out std_logic; --状态开关输出
reset:in std_logic; --重置
start:in std_logic; --开始
sum1, 20、sum2:in std_logic_vector(4 downto 0);--计数结果输入
music_begin:out std_logic; --音乐
record1,record2:out std_logic_vector(1 downto 0);--比分输出
lights:out std_logic_vector(2 downto 0)); --拔河绳子显示
end component;
component music --音乐模块
port(
reset:in std_logic; 21、 --重置
clk:in std_logic; --1MHz
clk_5:in std_logic; --5hz
music_begin:in std_logic; --音乐开始
mus:out std_logic);
end component;
component decode --译码模块
port(
clk_in:in std_logic; --1mHZ
record1,record2:in std_logic_vector(1 downto 0); - 22、比分输入
lights:in std_logic_vector(2 downto 0); --拔河绳子输入
led:out std_logic_vector(7 downto 0); --输出到LED
q:buffer std_logic_vector(5 downto 0); --数码管控制
cats:out std_logic_vector(6 downto 0) --数码管显示比分
);
end component;
component daojishi --倒计时模块
port(
clk_in,clk_1, 23、reset:in std_logic;
row : out std_logic_vector(7 downto 0);
col : out std_logic_vector(7 downto 0);
start: out std_logic
);
end component;
--分频器输出
signal clk_100,clk_5,clk_1:std_logic; --时钟信号
--计数器输出
signal sum1,sum2:std_logic_vector(4 downto 0); --计数结果
--比较器输出 24、
signal sw:std_logic; --状态开关
signal record1,record2:std_logic_vector(1 downto 0); --比分
signal lights:std_logic_vector(2 downto 0); --绳子
signal music_begin:std_logic;
--解码器输出
signal tmp_led:std_logic_vector(7 downto 0); --LED显示
signal tmp_q:std_logic_vector(5 downto 0); --数码管控制
25、
signal tmp_cat:std_logic_vector(6 downto 0); --数码管显示比分
--倒计时器输出
signal tmp_start:std_logic;
begin
cats<=tmp_cat;
q<=tmp_q;
led<=tmp_led;
div: division port map(clk_in=>clk_in,clk_100=>clk_100,clk_5=>clk_5,clk_1=>clk_1);
cnt: count port map(
clk_1=>clk_1,sw=>sw,p 26、layer1=>player1,player2=>player2,
sum1=>sum1,sum2=>sum2);
com: cmp port map(
clk_100=>clk_100,clk_1=>clk_1,sw=>sw,reset=>reset,
start=>tmp_start,sum1=>sum1,sum2=>sum2,music_begin=>music_begin,
record1=>record1,record2=>record2,lights=>lights);
dec: decode port map(
27、
clk_in=>clk_in,record1=>record1,record2=>record2,
lights=>lights,led=>tmp_led,q=>tmp_q,cats=>tmp_cat);
mu: music port map(
reset=>reset,clk=>clk_in,clk_5=>clk_5,
music_begin=>music_begin,mus=>mus);
dao: daojishi port map(
clk_in=>clk_in,clk_1=>clk_1,reset=>r 28、eset,
start=>tmp_start,col=>col,row=>row);
end body_bahe;
【比较模块】
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity cmp is
port(clk_100:in std_logic; --100HZ输入
clk_1:in std_logic; --1HZ输入
reset:in std_logic; --重置
s 29、tart:in std_logic; --开始
sum1,sum2:in std_logic_vector(4 downto 0); --计数输入
record1,record2:out std_logic_vector(1 downto 0); --比分输出
music_begin:out std_logic; --音乐开始
sw:out std_logic; --状态输出
lights:out std_logic_vector(2 downto 0)); --绳子状态
end cmp;
ar 30、chitecture body_cmp of cmp is
signal tmp_record1:std_logic_vector(1 downto 0); --比分
signal tmp_record2:std_logic_vector(1 downto 0);
signal tmp:std_logic_vector(2 downto 0); --绳子状态
signal tmp_sta:std_logic; --状态
signal s1,s2:std_logic_vector(4 downto 0); --计数
begin
31、record1<=tmp_record1;
record2<=tmp_record2;
lights<=tmp;
sw<=tmp_sta;
process(clk_100) --判断比赛状态
begin
if(start='1') then
if(clk_100'event and clk_100='1') then
tmp_sta<='1';
end if;
end if;
if(clk_100'event and clk_100='1') then --任意比分到3,比赛 32、结束,开始播放音乐
if(tmp_record1="11" or tmp_record2="11") then
tmp_sta<='0';
music_begin<='1';
end if;
if(tmp="001" or tmp="111") then --绳子到头,进入等待状态
tmp_sta<='0';
end if;
if(reset='1') then --复位,状态归零
tmp_sta<='0';
music_begin<='0';
end 33、if;
end if;
end process;
s1<=sum1;
s2<=sum2;
process(clk_1,reset) --控制绳子移位
begin
if(reset='1') then
tmp<="100"; --绳子初始状态为100
tmp_record1<="00";
tmp_record2<="00";
else
if(clk_1'event and clk_1='1') then
if(tmp_st 34、a='1') then
if(s1>s2) then tmp<=tmp-'1'; --绳子左移
elsif(s1=s2) then tmp<=tmp; --绳子保持原状
else tmp<=tmp+'1'; --绳子右移
end if;
else
if(tmp="001") then --绳子到左尽头,左计分器加1
tmp_record1<=tmp_record1+'1';
tmp<="100";
elsif(tmp="111") then 35、 --绳子到右尽头,右记分器加1,
tmp_record2<=tmp_record2+'1';
tmp<="100";
end if;
end if;
end if;
end if;
end process;
end body_cmp;
【计数模块】
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity count is
port(clk_1:in std_logi 36、c; --1HZ输入
sw:in std_logic; --状态判断输入
player1,player2:in std_logic; --选手输入
sum1,sum2:out std_logic_vector(4 downto 0)); --计数输出
end count;
architecture body_count of count is
signal p1,p2:std_logic_vector(4 downto 0); --计数输出
begin
sum1<=p1;
sum2<=p2;
37、
process(player1,player2,sw,clk_1)
begin
if(sw='1') then --处于比赛状态
if(clk_1='0') then
if(player1'event and player1='1') then
p1<=p1+'1';
end if;
if(player2'event and player2='1') then
p2<=p2+'1';
end if;
else
p1<="00000";
p 38、2<="00000";
end if; --比赛状态结束
else p1<="00000";
p2<="00000";
end if;
end process;
end body_count;
【倒计时模块】
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity daojishi is
port(clk_1,clk_in,reset: in std_logic;
row : out std_ 39、logic_vector(7 downto 0);
col : out std_logic_vector(7 downto 0);
start : out std_logic);
end daojishi;
architecture body_daojishi of daojishi is
type state is (s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);
signal present_state:state:=s10;
signal num:std_logic_vector(2 downto 0):="00 40、0";
begin
p3:process(clk_in)
begin
if clk_in'event and clk_in='1' then
if num="101" then num<="000";
else num<=num+1;
case present_state is
when s9=>
case num is
when "000"=> col<="11111111"; row<="11111 41、111";
when "001"=> col<="11011111"; row<="01110100";
when "010"=> col<="11101111"; row<="01010100";
when "011"=> col<="11110111"; row<="01010100";
when "100"=> col<="11111011"; row<="01111100";
when others=> col<="00000000"; 42、row<="00000000";
end case;
when s8=>
case num is
when "000"=> col<="11111111"; row<="11111111";
when "001"=> col<="11011111"; row<="01111100";
when "010"=> col<="11101111"; row<="0101 43、0100";
when "011"=> col<="11110111"; row<="01010100";
when "100"=> col<="11111011"; row<="01111100";
when others=> col<="00000000"; row<="00000000";
end case;
when s7=>
case num is
44、 when "000"=> col<="11111111"; row<="11111111";
when "001"=> col<="11011111"; row<="01000000";
when "010"=> col<="11101111"; row<="01000000";
when "011"=> col<="11110111"; row<="01000000";
when "100"=> col<="11111011"; row<="011 45、11100";
when others=> col<="00000000"; row<="00000000";
end case;
when s6=>
case num is
when "000"=> col<="11111111"; row<="11111111";
when "001"=> col<="11011111"; row<="01111100";
46、 when "010"=> col<="11101111"; row<="01010100";
when "011"=> col<="11110111"; row<="01010100";
when "100"=> col<="11111011"; row<="01011100";
when others=> col<="00000000"; row<="00000000";
end case;
47、
when s5=>
case num is
when "000"=> col<="11111111"; row<="11111111";
when "001"=> col<="11011111"; row<="01110100";
when "010"=> col<="11101111"; row<="01010100";
when "011"=> col<="11110111"; row<="01010100";
48、
when "100"=> col<="11111011"; row<="01011100";
when others=> col<="00000000"; row<="00000000";
end case;
when s4=>
case num is
when "000"=> col<="11111111"; row<="11111111";
49、 when "001"=> col<="11011111"; row<="01110000";
when "010"=> col<="11101111"; row<="00010000";
when "011"=> col<="11110111"; row<="00010000";
when "100"=> col<="11111011"; row<="01111100";
when others=> col<="00000000"; row<="00000000" 50、
end case;
when s3=>
case num is
when "000"=> col<="11111111"; row<="11111111";
when "001"=> col<="11011111"; row<="01010100";
when "010"=> col<="11101111"; row<="01010100";






