资源描述
可编程器件和应用课程设计汇报
姓 名: XXX
学 号: XXXXXXXXXX
专业班级: 信息XXX
题 目: 数字式竞赛抢答器
指导老师:
一、绪论
背景:
伴随电子技术发展,可编程逻辑器件(PLD)出现,使得电子系统设计者利用EDA(电子设计自动化)软件,就能够独立设计自己专用集成电路(ASIC)器件。可编程逻辑器件是一个半导体集成器件半成品。在可编程逻辑器件芯片中按一定方法(阵列形式或单元阵列形式)制作了大量门、触发器等基础逻辑器件,对这些基础器件合适地连接,就能够完成某个电路或系统功效。
数字式竞赛抢答器控制系统是工厂、学校和电视台等单位举行多种智力竞赛等娱乐活动中常常使用关键基础设备之一。现在设计抢答器方法很多,比如用传统PCB板设计、用PIC设计或用单片机设计。而用Verilog能够愈加紧速、灵活地设计出符合多种要求抢答器,优于其它设计方法,使设计过程达成高度自动化。本文介绍4路数字式竞赛抢答器基于Verilog语言、以EDA技术作为开发手段、采取CPLD(复杂可编程逻辑器件)作为控制关键设计而成。和传统设计相比较,不仅简化了接口和控制,也提升了系统整体性能和工作可靠性,含有电路简单、成本低廉、操作方便、灵敏可靠等优点。
意义:
数字式竞赛抢答器作为一个电子产品,早已广泛应用于多种智力和知识竞赛场所,但现在所使用抢答器存在分立元件使用较多,造成每路成本偏高,而现代电子技术发展要求电子电路朝数字化、集成化方向发展,所以设计出数字化全集成电路多路抢答器是现代电子技术发展要求。
二、实现方案
设计要求:
1、设计一个可容纳4组参赛数字式抢答器,每组设一个按钮,供抢答使用。
2、抢答器含有第一信号判别和锁存功效,使除第一抢答者外按钮不起作用。
3、设置一个主持人“复位”按钮。
4、主持人复位后,开始抢答,第一信号判别锁存电路得到信号后,有指示灯显示抢答组别,扬声器发出2~3秒音响。
5、设置一个计分电路,每组开始预置5分,由主持人记分,答对一次加1分,答错一次减1分。
6、设置犯规电路,对超时答题(比如1分钟)组别鸣笛示警,并由组别显示电路显示出犯规组别,该轮该选手退出,由裁判员重新发令,其它人再抢答。
设计方案:
此设计问题可分为第一信号判别、锁存模块,答题计时电路模块,计分电路模块和扫描显示模块四部分。
第一信号判别锁存模块关键是正确判定出第一抢答者并将其锁存,在得到第一信号后,将输入端封锁,使其它组抢答信号无效,能够用触发器或锁存器实现。设置抢答按钮K1、K2、K3、K4,主持人复位信号judge,蜂鸣器驱动信号buzzout。judge=0时,第一信号判别、锁存电路、答题计时电路复位,在此状态下,若有抢答按钮按下,鸣笛示警并显示犯规组别;judge=1时,开始抢答,由第一信号判别锁存电路形成第一抢答信号,进行组别显示,控制蜂鸣器发出声响,并开启答题计时电路,若计时时间到,主持人复位信号还没有按下,则由蜂鸣器发出犯规示警声。
计分电路是一个相对独立模块,采取十进制加/减计数器、数码管数码扫描显示,设置复位信号Reset、加减分信号add_min,加减分状态键key_state,Reset=0时全部得分回到起始分(5分),且加、减分信号无效;Reset=1时,由第一信号判别、锁存电路输出信号选择进行加减分组别,当key_state=1时,按一次add_min,第一抢答组加1分;当key_state=0时,每按一次add_min,则减1分。以下为每个模块设计过程。
三、程序及仿真
/******************************************************************
顶层模块信号定义:
clk:基按时钟输入信号;k1,k2,k3,k4:抢答按钮输入信号;seg:数码管段输出引脚;
sl:数码管位输出引脚;add_min:加减分按键;key_state:加减分模式选择按键;
reset:初始5分设置键信号;judge:裁判员抢答开始键信号;o5:超时信号;
o1、o2、o3、o4:抢答组别LED显示输出信号;buzz:示警输出信号;******************************************************************/
module
qiangdaqi(clk,k1,k2,k3,k4,seg,sl,add_min,key_state,reset,judge,o1,o2,o3,o4,o5,buzz,vg,sel);
input clk,k1,k2,k3,k4,add_min,key_state,reset,judge;
output[7:0] seg; output[3:0] sl; output reg sel; output o1,o2,o3,o4,o5,vg; output buzz;
reg [3:0] vg=0010; wire o1,o2,o3,o4; wire[3:0] s1,s2,s3,s4;
/* 模块引用 */
sel Q1(clk,k1,k2,k3,k4,judge,o1,o2,o3,o4,o5,buzz); //调用抢答信号锁存显示电路
count Q2(clk,o1,o2,o3,o4,add_min,key_state,reset,s1,s2,s3,s4); //调用计分电路
dled Q3(seg,sl,s1,s2,s3,s4,clk); //调用数码管显示电路
endmodule
/****************************************************************
信号锁存电路信号定义:
CLK:时钟信号;K1、K2、K3、K4、K5、K6:抢答按钮信号;
out1、out2、out3、out4、out5、out6:抢答LED显示信号;
judge:裁判员抢答开始信号;buzzout:示警输出信号;flag:答题是否超时标志;
****************************************************************/
module sel(clk,k1,k2,k3,k4,judge,out1,out2,out3,out4,out5,buzzout);
input clk,k1,k2,k3,k4,judge; output out1,out2,out3,out4,out5,buzzout;
reg out1,out2,out3,out4,out5,block,buzzout; reg[32:0] count;
reg[27:0] counter; reg flag;
always@(posedge clk )
begin counter=counter+1; //裁判员发开始抢答信号,初始指示灯灭,蜂鸣器禁声
if(!judge) begin {out1,out2,out3,out4,out5,block}<=6'b111110;
count=0; flag=0; end
else begin if(!k1) //第一组别按键是否按下
begin if(!block)
begin out1=0; //点亮第一组别指示灯
block=1; //封锁别组抢答信号
count=1; //第一组已按下按钮,可开启答题计时器
end end
else if(!k2) //第二组别按键是否按下
begin if(!block)
begin out2=0; block=1;count=1; end
end
else if(!k3) //第三组别按键是否按下
begin if(!block)
begin out3=0; block=1; count=1; end
end
else if(!k4) //第四组别按键是否按下
begin if(!block)
begin out4=0; block=1; count=1; end
end
end /*答题计时开始,并判定是否答题超时*/
if(count!=0)
begin if(count==32'hc11e7a00) //假如答题时间到了1分钟,亮犯规灯
begin count=0; out5<=0; flag=1'b1; end
else begin count=count+1; end
end
end ////蜂鸣器发声
always@(counter[7])
if(flag==1) buzzout=!(counter[11]&counter[22]&counter[27]);
else buzzout=1'b0;
endmodule
/**************************************************************
去键盘抖动信号定义:
clkin:基按时钟输入信号;
clkout:周期为20ms信号输出;
*************************************************************/
module f_1M(clkin,clkout);
Input clkin; output clkout;
reg clkout; reg[18:0] count;
always @(negedge clkin)
if(count==19'd500000)
begin count<=19'd000000; clkout<=~clkout; end
else count<=count+1'b1;
endmodule
/**************************************************************
计分电路信号定义:
clk:时钟信号;c1,c2,c3,c4:抢答组别输入信号;add_min:加减分按钮;
key_state:加减分标志按钮;reset:初始5分设置信号;
count1:第一组得分输出;count2:第二组得分输出;
count3:第三组得分输出;count4:第四组得分输出;
*************************************************************/
module count(clk,c1,c2,c3,c4,add_min,key_state,reset,count1,count2,count3,count4);
input clk,c1,c2,c3,c4,add_min,key_state,reset; output[3:0] count1,count2,count3,count4;
reg[3:0] count1,count2,count3,count4; wire clk0; reg keyout;
f_1M f_1Ma(clk,clk0); //引用取得20毫秒子模块
always @(negedge clk0)
keyout=add_min;
always @(posedge keyout) //依据对应组别加减分
begin if(!reset) //初始化各组起始分数
{count1,count2,count3,count4}=16'h5555;
if(!key_state) // key_state为低电平,选组别减分模式
begin if(!c1) //第一组别减1分,最高分为10分,最低分为0分
begin if(count1!=4'b0000) count1=count1-1; end
if(!c2) //第二组别减1分,最高分为10分,最低分为0分
begin if(count2!=4'b0000) count2=count2-1; end
if(!c3) //第三组别减1分,最高分为10分,最低分为0分
begin if(count3!=4'b0000) count3=count3-1; end
if(!c4) //第四组别减1分,最高分为10分,最低分为0分
begin if(count4!=4'b0000) count4=count4-1; end
end else // key_state为高电平,选组别加分模式
begin if(!c1) //第一组别加分,最高分为10分,最低分为0分
begin if(count1>9) count1=0;
else count1=count1+1; end
if(!c2) //第二组别加分,最高分为10分,最低分为0分
begin if(count2>9) count2=0;
else count2=count2+1; end
if(!c3) //第三组别加分,最高分为10分,最低分为0分
begin if(count3>9) count3=0;
else count3=count3+1; end
if(!c4) //第四组别加分,最高分为10分,最低分为0分
begin if(count4>9) count4=0;
else count4=count4+1; end end end
endmodule
/******************************************************************
数码管显示电路信号定义:
clk:时钟信号;seg:数码管段输出引脚;sl:数码管位输出引脚;
score1:第一组得分输入;score2:第二组得分输入;
score3:第三组得分输入;score4:第四组得分输入;
******************************************************************/
module dled (seg,sl,score1,score2,score3,score4,clk,vg);
output[7:0] seg; output[3:0] sl; output reg [3:0] vg=0010;
input clk; input[3:0] score1,score2,score3,score4;
reg[7:0] seg_reg; //定义数码管段输出寄存器
reg[3:0] sl_reg; //定义数码管位输出寄存器
reg[3:0] disp_dat; //定义显示数据寄存器
reg[16:0] count; //定义计数器寄存器
always@(posedge clk) //定义clock信号上升沿触发
begin count=count+1; //计数器值加1
end
always@(count[14:13]) //定义显示数据触发事件
begin case(count[14:13]) //选择扫描显示数据
2'h0:disp_dat=score1; //在个位数码管上显示第一组别分数值
2'h1:disp_dat=score2; //在十位数码管上显示第二组别分数值
2'h2:disp_dat=score3; //在百位数码管上显示第三组别分数值
2'h3:disp_dat=score4; //在千位数码管上显示第四组别分数值
endcase
case(count[14:13]) //选择数码管显示位
2'h0:sl_reg=4'b1110; //选择个位数码管
2'h1:sl_reg =4'b1101; //选择十位数码管
2'h2:sl_reg =4'b1011; //选择百位数码管
2'h3:sl_reg =4'b0111; //选择千位数码管
endcase end
always@(disp_dat) //显示数据解码过程
begin
case(disp_dat)
4'h0:seg_reg=8'h3f; //显示数据0
4'h1:seg_reg=8'h06; //显示数据1
4'h2:seg_reg=8'h5b; //显示数据2
4'h3:seg_reg=8'h4f; //显示数据3
4'h4:seg_reg=8'h66; //显示数据4
4'h5:seg_reg=8'h6d; //显示数据5
4'h6:seg_reg=8'h7d; //显示数据6
4'h7:seg_reg=8'h07; //显示数据7
4'h8:seg_reg=8'h7f; //显示数据8
4'h9:seg_reg=8'h6f; //显示数据9
4'ha:seg_reg=8'h77; //显示数据a
4'hb:seg_reg=8'h7c; //显示数据b
4'hc:seg_reg=8'h39; //显示数据c
4'hd:seg_reg=8'h51; //显示数据d
4'he:seg_reg=8'h79; //显示数据e
4'hf:seg_reg=8'h71; //显示数据f
endcase end
assign seg=seg_reg; //输出数码管解码结果
assign sl=sl_reg; //输出数码管选择
endmodule
管脚分配图以下:
四、总结
1、打开Quartus II软件,对该工程文件进行编译处理,若在编译过程中发觉错误,找出并更正错误直至成功为止。
2、将CCIT CPLD/FGPA JTAG下载电缆两端分别接到PC机和CCIT CPLD/FGPA试验仪上,再打开工作电源,实施下载命令把程序下载到CCIT CPLD/FGPA试验仪EPM1270T144C5N器件中,经过K1~K4抢答按键按下后,由裁判员根答题情况,经过控制add_min和key_state这两个键实现加减分操作,这么大家就能够看到数码管上分数和LED四盏小灯改变。
五、心得体会
经过此次课程设计,我学会了综合应用键盘、LED小灯、蜂鸣器、LED数码管等外围接口进行产品设计,掌握了键盘、LED小灯、蜂鸣器、LED数码管等外围接口Verilog语言编程和多种外围接口灵活利用。培养了CPLD综合开发能力、试验仿真及下载技能和互帮互助同学关系,在多种其它能力上也全部有了提升。更关键是,经过此次课设反复修改验证及完成,我们学会了很多学习方法,而这是以后最实用,真是感到受益匪浅。即使结束了,也留下了很多遗憾,因为时间紧缺和很多课业繁忙,并没有做到最好,不过,最起码我们没有放弃,并努力实现它。相信以后我们会以愈加主动地态度对待我们学习、对待我们生活。我们激情永远不会结束,相反,我们会愈加努力,努力去填补缺点,发展优点,充实自己!
展开阅读全文