1.設計一個十秒的倒計時計時器用于選手看題準備并且設計一個60秒的倒計時用于答題。 2.設計電路實現三人搶答。 3.實現用LCD1602顯示當前比賽進行的狀態。各個狀態如下: (1)搶答前顯示開始搶答和該問題為第幾個問題(共有5題):“Begin!”“Question-x”。 (2)若在十秒的該搶答時間內無人搶答,顯示失敗,下一題!癋ail to quiz!“”Next!“。 (3)搶答后顯示搶答選手姓名,如:“Respondent”“Zhangsan”。 (4)選手搶到題后該選手指示燈亮,回答完畢或回答時間到熄滅。 (5)若選手在六十秒的回答時間內未完成回答則顯示失敗。“Failure!“若在有效的十秒內回答完畢則由裁判對回答的正誤判斷分別顯示“Congratulation!+10““Failure!“。如此反復,共進行五次。 (6)當完成競賽總數(共5題)題目時,顯示競賽結束!癊nd 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下載地址:
test7_21.zip
(1.64 MB, 下載次數: 25)
2019-7-8 11:34 上傳
點擊文件名下載附件
|