1.设计一个十秒的倒计时计时器用于选手看题准备并且设计一个60秒的倒计时用于答题。 2.设计电路实现三人抢答。 3.实现用LCD1602显示当前比赛进行的状态。各个状态如下: (1)抢答前显示开始抢答和该问题为第几个问题(共有5题):“Begin!”“Question-x”。 (2)若在十秒的该抢答时间内无人抢答,显示失败,下一题。“Fail to quiz!“”Next!“。 (3)抢答后显示抢答选手姓名,如:“Respondent”“Zhangsan”。 (4)选手抢到题后该选手指示灯亮,回答完毕或回答时间到熄灭。 (5)若选手在六十秒的回答时间内未完成回答则显示失败。“Failure!“若在有效的十秒内回答完毕则由裁判对回答的正误判断分别显示“Congratulation!+10““Failure!“。如此反复,共进行五次。 (6)当完成竞赛总数(共5题)题目时,显示竞赛结束。“End of the quiz!” 4.设计计分器对选手的得分进行及时的显示。(答对一题得一分,答错或回答超时扣一分) 2 设计分析及系统方案设计 为了实现以上四点设计要求,把总方案分成顶层(top)模块、液晶显示(lcd)模块、液晶控制(lcdcontroller)模块、倒计时(discount)模块、计分(jifen)模块共五个模块。其中倒计时模块和计分模块融合在顶层模块里。 顶层(Top)模块用于对整个电路的逻辑设计和各个状态的转换以及对子模块的调用。 液晶显示(Lcd)模块则用于显示相关字符。需要先把要显示的字符写在程序中备用,并编码。采用译码器的方式调用某串字符。故该模块的输入为需要调用的字符的编码、竞赛进行到第几个问题(共五个)的编码以及时钟等。 液晶控制(lcdcontroller)模块用于对液晶读写显示的驱动。 倒计时(discount)模块用于比赛中的计时。先把50M的频率分成1HZ的频率进行记秒。采用译码器的原理把倒计时显示在对应的数码管上。 计分模块用于实时显示选手的得分。同样采用译码器原理进行数码管的显示。输入为选手的得分。 图2.1 系统框图
3系统以及模块硬件电路设计 3.1系统硬件电路设计 图3.1 按键原理图 该设计共使用7个按键用于实现使能、裁判判决、选手表示等功能。 图3.2 选手对应的灯的原理图 采用排阻接发光二极管接地的方式,当输入为高时灯亮。 图3.3 数码管原理图 该设计共采用了五个共阴极数码管,分别对应于开发板的HEX0 HEX2 HEX4 HEX5 HEX6。前三者用于实时显示选手分数后两者用于显示倒计时。 图3.4 液晶LCD1602原理图 3.2功能管脚定义 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 组合判断选手答案的正误。(都为高则表示真确只有一个为高则错误) | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
| | | | |
4 系统的Verilog HDL设计 4.1.1顶层(Top module) 当主裁判发出开始标志时先判断n(比赛的题目数)是否小于5(题目总数)然后进入十秒的倒计时让选手看题抢答,若有选手在十秒内作答则进入该选手的state进入下一轮10秒的答题倒计时,并判断是否超时,若60秒内选手答题完毕则由裁判判断正确与否以及是否进入下一题,若答题的60秒内选手未答题或者答题超时则失败。若在选手抢答的十秒内没有选手抢答则该题作废由裁判判决进入下一题。
图4.1 顶层状态图 4.1.2 LCD显示 查看液晶1602的手册先行配置相关显示参数确保能够静态显示。在此基础上,对该设计需要现实的字符串先行查找相关的8位二进制代码。考虑到显示的字符串比较多,故选择了定义两个128位(16*8)的寄存器型变量对1602的两行进行数据的存储,然后利用译码器的思想设置了三位的变量调用相关字符串以达到实时显示相关字符串的目的。对于比赛进行到几个项目的显示也是采用相同的先编码存储然后调用的方法实现。 下表为字符与输入编码的对应表。
4.1.3 倒计时(discount) 该设计中有需要两个倒计时,一个用来计时抢答一个用来计时回答,同时需要在一次倒计时结束时生成标志位并且在生成标志位完成一个问题的抢答后需要对标志位进行复位让主模块里的状态循环得以正常进行。该模块采用的仍是对置数的十位和个位进行译码进而显示在相关的数码管上。 4.1.4 计分(jifen) 在每次副裁判宣布进入下一题的下降沿触发判断该上一个问题的得分情况。把计分和主模块写在两个always里面主要是避免主模块里时钟频率太大导致计数不准确的问题。 //////////////////顶层模块代码 - module test7_20(input en,input en_next_ctr,input clk_en,input [2:0]chosen,input [2:0]chosen_over,
- input [1:0]right,output reg [6:0]fenshu_a,output reg [6:0]fenshu_b,output reg [6:0]fenshu_c,
- output reg [6:0]count_down_1,output reg [6:0]count_down_0,output reg led_a,output reg led_b,
- output reg led_c,inout [7:0]lcd_data,output rw,output lcd_en,output lcd_rs,output lcd_on);
- //en使能(按键控制,代表总裁判) en_next_ctr裁判判决是否进入下一题 [2:0]chosen代表三个选手[2:0]chosen_over用于判断选手是否答题完毕
- //[1:0]right用于裁判判断对错 fenshu_a fenshu_b fenshu_c代表选手的分数
- /////////////////////////////////////////////////////////////
- //internal
- reg [2:0]chose,a,b,c;
- reg [2:0]n;
- reg t_an,t_kai,en_next,discount_en_1,t_1,t_first;
- reg [27:0]count;
- ////////////////////////////////////////////////////////////
- always@(posedge clk_en)
- begin
- if(en)
- begin
- if(en_next_ctr==0)
- begin
- en_next<=1;
- //discount_en_1<=0;
- //t_1<=0;
- end
- if(n==3'd5)
- begin
- chose<=3'o1;//显示End of the quiz!
- discount_en_1<=0;
- t_1<=0;
- led_a<=0;
- led_b<=0;
- led_c<=0;
- end
- else begin
- if((en_next==1))
- begin
- discount_en_1<=1;
- t_1<=0;//使能倒计时
- chose<=3'o0;
- end//液晶第一行显示Begin!第二行显示Question-x 其中x 表示第几个问题
- if(t_kai==1)//无人抢答
- begin
- discount_en_1<=0;
- t_1<=0;
- chose<=3'o2;//第一行显示Fail to quiz!第二行显示Next!
- en_next<=0;
- end
- else begin
-
- if(chosen==3'b100)//a
- if(!t_first)//
- begin//
- discount_en_1<=1;
- t_1<=1;
- led_a<=1;
- chose<=3'o3;//显示选手姓名
- if(t_an==1)//回答超时
- begin
- chose<=3'o6;
- en_next<=0;
-
- end
- else if(chosen_over[2]==1)//回答结束
- begin
- t_1<=0;
- discount_en_1<=0;
- if(right==2'b01)//判断正确与否
- begin
- en_next<=0;
- chose<=3'o7;
- // a<=a+1'b1;
- led_a<=0;
- end
- else if(right==2'b10)
- begin
- en_next<=0;
- chose<=3'o6;
- led_a<=0;
- end
- end
- end//
- else//
- begin
- chose<=3'o6;
- en_next<=0;
- discount_en_1<=0;
- t_1<=0;
- end//
-
- else
- if(chosen==3'b010)//b
- begin
- if(!t_first)
- begin
- discount_en_1<=1;
- t_1<=1;
- led_b<=1;
- chose<=3'o4;//显示选手姓名
- if(t_an==1)
- begin
- chose<=3'o6;
- en_next<=0;
-
- end
- else if(chosen_over[1]==1)
- begin
- t_1<=0;
- discount_en_1<=0;
- if(right==2'b01)
- begin
- led_b<=0;
- en_next<=0;
- chose<=3'o7;
- end
- else if(right==2'b10)
- begin
- en_next<=0;
- chose<=3'o6;
- led_b<=0;
- end
- end
- end//
- else//
- begin
- chose<=3'o6;//
- en_next<=0;//
- discount_en_1<=0;
- t_1<=0;
- end//
- end
-
- else
- if(chosen==3'b001)//c
- begin if(!t_first)//
- begin
- discount_en_1<=1;
- t_1<=1;
- led_c<=1;
- chose<=3'o5;//显示选手姓名
- if(t_an==1)
- begin
- chose<=3'o6;
- en_next<=0;
-
- end
- else if(chosen_over[0]==1)
- begin
- t_1<=0;
- discount_en_1<=0;
- if(right==2'b01)
- begin
- en_next<=0;
- chose<=3'o7;
- led_c<=0;
- end
- else if(right==2'b10)
- begin
- en_next<=0;
- chose<=3'o6;
- led_c<=0;
- end
- end
- end
- else
- begin
- chose<=3'o6;
- en_next<=0;
- discount_en_1<=0;
- t_1<=0;
- end
- end
- end//若无选手答题返回继续倒计时并判断
- end
- end
- end
- ////////////////////////////////////////////////
- always@(negedge en_next)//计数比赛进行到第几个问题
- begin
- if(en)
- if(n==5)
- n<=3'd0;
- else
- n<=n+1'b1;
- end
-
-
- //////////////////////////////////////////////
- always@( negedge en_next )//实时显示比赛得分
- begin
- if(en)
- begin
- if(chose==3'o1)
- begin
- a<=3'd0;
- b<=3'd0;
- c<=3'd0;
- end
- else
- if(chose==3'o7)
- case(chosen_over)
- 3'b100:a<=a+1'b1;
- 3'b010:b<=b+1'b1;
- 3'b001:c<=a+1'b1;
-
- endcase
- else if(chose==3'o6)
- case(chosen_over)
- 3'b100:begin
- if(a==0)
- a<=0;
- else
- a<=a-1'b1;
- end
- 3'b010:begin
- if(b==0)
- b<=0;
- else
- b<=b-1'b1;
- end
- 3'b001:begin
- if(c==0)
- c<=0;
- else
- c<=c-1'b1;
- end
- endcase
- end
- end
-
- ////////////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////////////
- reg [3:0]shi,ge;//时钟clk 使能en 输出显示数码管a b///输出tt用于判断是否计时结束
- reg [24:0]count_0;//计数用于分频
- reg out_clk,t_0,t_2;
- //out_clk为1hz的时钟信号
- //该模块的功能为输入时钟和使能进行10秒倒计时
- always@(posedge clk_en)//50M分频--1HZ
- begin
- if(count_0==25'h17d7840)
- begin
- count_0<=25'h0000000;
- out_clk<=!out_clk;
- end
- else
- count_0<=count_0+1'b1;
- end
-
- always@(posedge out_clk)//倒计时
- begin
- if(en)
- case({discount_en_1,t_1})
- 2'd0:begin
- shi<=4'd0;
- ge<=4'd0;
- t_0<=0;
- t_2<=0;
- t_kai<=0;
-
- t_an<=0;
- //t<=0;
- end
- 2'd1:;
- 2'd2:if(t_0==0)
- begin
- shi<=4'd1;
- ge<=4'd0;
- t_0<=1;
- t_first<=0;
- //t_kai<=0;
- end
- else begin
- if(shi==0&&ge==0&&t_0==1)
- t_kai<=1;
- else begin
- if(ge==4'd0)
- begin
- shi<=shi-1'b1;
- ge<=4'd9;
- end
- else ge<=ge-1'b1;
- end
- end
- 2'd3:if(t_2==0)
- begin
- shi<=4'd1;
- ge<=4'd0;
- t_2<=1;
- t_first<=0;
- //t_an<=0;
- end
- else begin
- if(shi==0&&ge==0&&t_2==1)
- begin
- t_an<=1;
- t_first<=1;
- end
- else begin
- if(ge==4'd0)
- begin
- shi<=shi-1'b1;
- ge<=4'd9;
- end
- else ge<=ge-1'b1;
- end
- end
- endcase
- end
-
-
- always@(shi)
- begin
- case(shi)
- 4'd0: count_down_1<=7'b1000000;
- 4'd1: count_down_1<=7'b1111001;
- 4'd2: count_down_1<=7'b0100100;
- 4'd3: count_down_1<=7'b0110000;
- 4'd4: count_down_1<=7'b0011001;
- 4'd5: count_down_1<=7'b0010010;
- 4'd6: count_down_1<=7'b0000010;
- 4'd7: count_down_1<=7'b1111000;
- 4'd8: count_down_1<=7'b0000000;
- 4'd9: count_down_1<=7'b0010000;
- default: count_down_1<=7'b1111111;
- endcase
- end
-
- always@(ge)
- begin
- case(ge)
- 4'd0: count_down_0<=7'b1000000;
- 4'd1: count_down_0<=7'b1111001;
- 4'd2: count_down_0<=7'b0100100;
- 4'd3: count_down_0<=7'b0110000;
- 4'd4: count_down_0<=7'b0011001;
- 4'd5: count_down_0<=7'b0010010;
- 4'd6: count_down_0<=7'b0000010;
- 4'd7: count_down_0<=7'b1111000;
- 4'd8: count_down_0<=7'b0000000;
- 4'd9: count_down_0<=7'b0010000;
- default: count_down_0<=7'b1111111;
- endcase
- end
- always@(a)//显示得分
- begin
- case(a)
- 0:fenshu_a<=7'b1000000;//共五道题每题一分
- 1:fenshu_a<=7'b1111001;
- 2:fenshu_a<=7'b0100100;
- 3:fenshu_a<=7'b0110000;
- 4:fenshu_a<=7'b0011001;
- 5:fenshu_a<=7'b0010010;
- endcase
- end
- always@(b)//显示得分
- begin
- case(b)
- 0:fenshu_b<=7'b1000000;//共五道题每题一分
- 1:fenshu_b<=7'b1111001;
- 2:fenshu_b<=7'b0100100;
- 3:fenshu_b<=7'b0110000;
- 4:fenshu_b<=7'b0011001;
- 5:fenshu_b<=7'b0010010;
- endcase
- end
- always@(c)//显示得分
- begin
- case(c)
- 0:fenshu_c<=7'b1000000;//共五道题每题一分
- 1:fenshu_c<=7'b1111001;
- 2:fenshu_c<=7'b0100100;
- 3:fenshu_c<=7'b0110000;
- 4:fenshu_c<=7'b0011001;
- 5:fenshu_c<=7'b0010010;
- endcase
- end
- //discount(.clk(clk_en),.en(discount_en_1),.a(count_down_1),.b(count_down_0),.tt(t));//调用倒计时模块
- //jifen(.data_in(a),.data_out(fenshu_a));//调用显示数码管计分模块分别显示三位选手的得分
- //jifen(.data_in(b),.data_out(fenshu_b));
- //jifen(.data_in(c),.data_out(fenshu_c));
- lcd (.iCLK(clk_en),.iRST_N(en),.choose(chose),.m(n),.LCD_DATA(lcd_data),
- .LCD_RW(lcd_rw),.LCD_EN(lcd_en),.LCD_RS(lcd_rs),.LCD_ON(lcd_on));//调用LCD模块显示相关的字符串
- endmodule
- //LCD显示模块代码
-
- module lcd ( // Host Side
- iCLK,iRST_N,choose,m,
- // LCD Side
- LCD_DATA,LCD_RW,
- LCD_EN,LCD_RS,LCD_ON);//改模块的功能为实现LCD在不同的抢答状态输出不同的字符串
- //m用于判断是第几个问题 //choose用于选择那个字符串
-
- // Host Side
- input [2:0]choose,m;
- input iCLK,iRST_N;
- // LCD Side
- inout [7:0] LCD_DATA;
- output LCD_RW,LCD_EN,LCD_RS,LCD_ON;
-
- // Internal Wires/Registers
- reg [5:0] LUT_INDEX;
- reg [7:0] LUT_DATA;
- reg [5:0] mLCD_ST;
- reg [17:0] mDLY;
- reg mLCD_Start;
- reg [7:0] mLCD_DATA;
- reg mLCD_RS;
- wire mLCD_Done;
- reg [127:0]lineone,linetwo;//定义两个128位的数据用于存储液晶每一行应该显示的数据128=16*8
-
-
-
-
-
- parameter LCD_INTIAL = 0;
- parameter LCD_LINE1 = 5;
- parameter LCD_CH_LINE = LCD_LINE1+16;
- parameter LCD_LINE2 = LCD_LINE1+16+1;
- parameter LUT_SIZE = LCD_LINE1+32+1;
-
- assign LCD_ON = 1'b1;
- always@(posedge iCLK or negedge iRST_N)
- begin
- if(!iRST_N)
- begin
- LUT_INDEX <= 0;
- mLCD_ST <= 0;
- mDLY <= 0;
- mLCD_Start <= 0;
- mLCD_DATA <= 0;
- end
- else
- begin
- if(LUT_INDEX<LUT_SIZE)
- begin
- case(mLCD_ST)
- 0: begin
- mLCD_DATA <= LUT_DATA[7:0];
- mLCD_Start <= 1;
- mLCD_ST <= 1;
- end
- 1: begin
- if(mLCD_Done)
- begin
- mLCD_Start <= 0;
- mLCD_ST <= 2;
- end
- end
- 2: begin
- if(mDLY<18'h3FFFE)
- mDLY <= mDLY+1;
- else
- begin
- mDLY <= 0;
- mLCD_ST <= 3;
- end
- end
- 3: begin
- if (LUT_INDEX<LUT_SIZE-1)
- LUT_INDEX <= LUT_INDEX+1;
- else
- LUT_INDEX <= LCD_INTIAL+4;
- mLCD_ST <= 0;
- end
- endcase
- end
- end
- end
-
- always
- begin
- case(LUT_INDEX)
- // Initial
- LCD_INTIAL+0: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'h38;//16*2 5*7点阵8位数据端口
- end
- LCD_INTIAL+1: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'h0C;//开显示
- end
- LCD_INTIAL+2: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'h01;//显示清屏
- end
- LCD_INTIAL+3: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'h06;//写或读一个字符后地址指针加一光标加一
- end
- LCD_INTIAL+4: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'h80;//设置数据地址指针
- end
- // Line 1
- LCD_LINE1+0: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[127:120];
- end
- LCD_LINE1+1: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[119:112];
- end
- LCD_LINE1+2: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[111:104];
- end
- LCD_LINE1+3: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[103:96];
- end
- LCD_LINE1+4: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[95:88];
- end
- LCD_LINE1+5: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[87:80];
- end
- LCD_LINE1+6: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[79:72];
- end
- LCD_LINE1+7: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[71:64];
- end
- LCD_LINE1+8: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[63:56];
- end
- LCD_LINE1+9: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[55:48];
- end
- LCD_LINE1+10: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[47:40];
- end
- LCD_LINE1+11: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[39:32];
- end
- LCD_LINE1+12: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[31:24];
- end
- LCD_LINE1+13: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[23:16];
- end
- LCD_LINE1+14: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[15:8];
- end
- LCD_LINE1+15: begin
- mLCD_RS <=1;
- LUT_DATA <= lineone[7:0];
- end
- // Change Line
- LCD_CH_LINE: begin
- mLCD_RS <=0;
- LUT_DATA <= 8'hC0;
- end
- // Line 2
- LCD_LINE2+0: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[127:120];
- end
- LCD_LINE2+1: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[119:112];
- end
- LCD_LINE2+2: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[111:104];
- end
- LCD_LINE2+3: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[103:96];
- end
- LCD_LINE2+4: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[95:88];
- end
- LCD_LINE2+5: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[87:80];
- end
- LCD_LINE2+6: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[79:72];
- end
- LCD_LINE2+7: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[71:64];
- end
- LCD_LINE2+8: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[63:56];
- end
- LCD_LINE2+9: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[55:48];
- end
- LCD_LINE2+10: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[47:40];
- end
- LCD_LINE2+11: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[39:32];
- end
- LCD_LINE2+12: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[31:24];
- end
- LCD_LINE2+13: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[23:16];
- end
- LCD_LINE2+14: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[15:8];
- end
- LCD_LINE2+15: begin
- mLCD_RS <=1;
- LUT_DATA <= linetwo[7:0];
- end
- default: begin
- mLCD_RS <=1;
- LUT_DATA <= 8'h00;
- end
- endcase
- end
-
- always@(choose)//选择液晶输出什么字符串
- begin
- case(choose)
- 3'o0: begin
- lineone<=128'h20_20_20_20_20_42_65_67_69_6E_21_20_20_20_20_20;//Begin!
- case(m)//选择输出问题几
- 0:linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_31_20_20_20;//Question
- 1:linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_32_20_20_20;
- 2:linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_33_20_20_20;
- 3:linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_34_20_20_20;
- 4:linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_35_20_20_20;
- default:linetwo<=128'h20_20_20_20_20_20_20_20_20_20_20_20_20_20_20_20;
- endcase
- end
- 3'o1: begin
- lineone<=128'h45_6E_64_20_6F_66_20_74_68_65_20_71_75_69_7A_21;//End of the quiz!
- linetwo<=128'h20_20_20_20_20_20_20_20_20_20_20_20_20_20_20_20;
- end
- 3'o2: begin
- lineone<=128'h20_46_61_69_6C_20_74_6F_20_71_75_69_7A_21_20_20;//Fail to quiz!
- linetwo<=128'h20_20_20_20_20_4E_65_78_74_21_20_20_20_20_20_20;//Next!
- end
- 3'o3: begin
- lineone<=128'h20_20_20_52_65_73_70_6F_6E_64_65_6E_74_20_20_20;//Zhang san
- linetwo<=128'h20_20_20_5A_68_61_6E_67_20_73_61_6E_20_20_20_20;
- end
- 3'o4: begin
- lineone<=128'h20_20_20_52_65_73_70_6F_6E_64_65_6E_74_20_20_20;
- linetwo<=128'h20_20_20_20_20_4C_69_20_73_69_20_20_20_20_20_20;//Li si
- end
- 3'o5: begin
- lineone<=128'h20_20_20_52_65_73_70_6F_6E_64_65_6E_74_20_20_20;//Wang wu
- linetwo<=128'h20_20_20_20_57_61_6E_67_20_77_75_20_20_20_20_20;
- end
- 3'o6: begin
- lineone<=128'h20_20_20_20_46_61_69_6C_75_72_65_21_20_20_20_20;//Failure!linetwo<=128'h20_20_20_20_20_4F_76_65_72_21_20_20_20_20_20_20;
- linetwo<=128'h20_20_20_20_20_20_20_20_20_20_20_20_20_20_20_20;
- end
- 3'o7: begin
- lineone<=128'h43_6F_6E_67_72_61_74_75_6C_61_74_69_6F_6E_73_21;//Congratulation!
- linetwo<=128'h20_20_20_20_20_20_2B_31_20_20_20_20_20_20_20_20;//+10
- end
- default:begin
- lineone<=128'h20_20_20_20_20_42_65_67_69_6E_21_20_20_20_20_20;//Begin!
- linetwo<=128'h20_20_20_51_75_65_73_74_69_6F_6E_2D_20_20_20_20;//Question
- end
- endcase
- end
-
- lcdcontroller u0 ( // Host Side
- .iDATA(mLCD_DATA),
- .iRS(mLCD_RS),
- .iStart(mLCD_Start),
- .oDone(mLCD_Done),
- .iCLK(iCLK),
- .iRST_N(iRST_N),
- // LCD Interface
- .LCD_DATA(LCD_DATA),
- .LCD_RW(LCD_RW),
- .LCD_EN(LCD_EN),
- .LCD_RS(LCD_RS) );
- endmodule
- lcdcontroller u0 ( // Host Side
- .iDATA(mLCD_DATA),
- .iRS(mLCD_RS),
- .iStart(mLCD_Start),
- .oDone(mLCD_Done),
- .iCLK(iCLK),
- .iRST_N(iRST_N),
- // LCD Interface
- .LCD_DATA(LCD_DATA),
- .LCD_RW(LCD_RW),
- .LCD_EN(LCD_EN),
- .LCD_RS(LCD_RS) );
- endmodule
-
- //LCD控制模块代码
- module lcdcontroller ( // Host Side
- iDATA,iRS,
- iStart,oDone,
- iCLK,iRST_N,
- // LCD Interface
- LCD_DATA,
- LCD_RW,
- LCD_EN,
- LCD_RS );//控制LCD的显示
- // CLK
- parameter CLK_Divide = 16;
-
- // Host Side
- input [7:0] iDATA;
- input iRS,iStart;
- input iCLK,iRST_N;
- output reg oDone;
- // LCD Interface
- output [7:0] LCD_DATA;
- output reg LCD_EN;
- output LCD_RW;
- output LCD_RS;
- // Internal Register
- reg [4:0] Cont;
- reg [1:0] ST;
- reg preStart,mStart;
-
- /////////////////////////////////////////////
- // Only write to LCD, by pass iRS to LCD_RS
- assign LCD_DATA = iDATA;
- assign LCD_RW = 1'b0;
- assign LCD_RS = iRS;
- /////////////////////////////////////////////
-
- always@(posedge iCLK or negedge iRST_N)
- begin
- if(!iRST_N)
- begin
- oDone <= 1'b0;
- LCD_EN <= 1'b0;
- preStart<= 1'b0;
- mStart <= 1'b0;
- Cont <= 0;
- ST <= 0;
- end
- else
- begin
- ////// Input Start Detect ///////
- preStart<= iStart;
- if({preStart,iStart}==2'b01)
- begin
- mStart <= 1'b1;
- oDone <= 1'b0;
- end
- //////////////////////////////////
- if(mStart)
- begin
- case(ST)
- 0: ST <= 1; // Wait Setup
- 1: begin
- LCD_EN <= 1'b1;
- ST <= 2;
- end
- 2: begin
- if(Cont<CLK_Divide)
- Cont <= Cont+1;
- else
- ST <= 3;
- end
- 3: begin
- LCD_EN <= 1'b0;
- mStart <= 1'b0;
- oDone <= 1'b1;
- Cont <= 0;
- ST <= 0;
- end
- endcase
- end
- end
- end
-
- endmodule
复制代码
结论以及结果说明
系统运行在Cyclone II开发板上,程序代码运行在Quartus II6.0上。该设计中抢答时间和回答时间可以根据具体情况进行调整。在计时分频环节把50M的频率分成1HZ的频率时通对需要计数的值进行判定。同样的在LCD显示模块里为了让模块可以正常工作,并且简化显示流程,对比LCD1602的参考手册采用把时钟分成约100HZ 让LCD只需不断地写入指令或数据即可。运行结果可以达到设计效果。
全部资料51hei下载地址: |