注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
jiajie270的个人空间 https://home.eeworld.com.cn/space-uid-422029.html [收藏] [复制] [分享] [RSS]
日志

按键加减数码管显示

已有 1992 次阅读2017-5-16 18:34 |个人分类:FPGA| false

//自己写的一个通过按键,控制数码管显示数据0-99的程序

主要练习:按键状态判断,按键消抖,哪一个按键按下判断,数码管扫描,数码管显示

module test_key3(CLK,RSTn,key_in,SEG_DATA,SEG_SEL);

 

input CLK;

input RSTn;

input [1:0]key_in;

output [7:0]SEG_DATA;

output [1:0]SEG_SEL;

 

reg [1:0]key_in_r;

wire [1:0]key_in_or;

 

//按键消抖

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   key_in_r<=2'b11;

         else

                   key_in_r<=key_in;

end

 

assign key_in_or=key_in_r^key_in;  //用于判断是否有按键变化

 

parameter T20MS=20'd1000_000;                   //20MS用于按键消抖

reg [19:0]counter2;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   counter2<=20'd0;

         else if(counter2==T20MS || key_in_or)  //计时满20ms或者有按键变化时counter2清零

                                     counter2<=20'd0;

                            else

                                     counter2<=counter2+20'b1;

end

 

reg [1:0]key_s;

reg [1:0]key_s_n;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   key_s<=2'b11;

         else

                   key_s<=key_s_n;

end

 

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   key_s_n<=2'b11;

         else if(counter2==T20MS)

                            key_s_n<=key_in;

                            else

                            key_s_n<=key_s_n;                   //开始时此处写成了key_s_n<=key_s造成错误

end

 

parameter T10MS=20'd500_000;                      //10MS用于数码管扫描

reg [19:0]counter;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   counter<=20'd0;

         else if(counter==T10MS)

                                     counter<=20'd0;

                            else

                                     counter<=counter+20'b1;

end

 

reg t;

always @(posedge CLK or negedge RSTn)                //t用于数码管扫描

begin

         if(!RSTn)

                   t<=1'b0;

         else if(counter==T10MS)

                                     t<=~t;

end

 

reg [6:0]counter1;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   counter1<=7'd0;

         else if(counter1==7'd100)

                                     counter1<=7'd0;

                            else if(counter1==7'd127)

                                                        counter1<=7'd99;

                                               else case({key_s,key_s_n})               //{key_s,key_s_n}用于判断是哪一个按键发生了按下或者放开的操作

                                                                 4'b1110:counter1<=counter1+7'd1;

                                                                 4'b1101:counter1<=counter1-7'd1;

                                                                 default:counter1<=counter1;

                                                                 endcase

end

 

reg [3:0]ge;

reg [3:0]shi;

 

always @(posedge CLK or negedge RSTn)                //用于计算数据位

begin

         if(!RSTn)

                   begin

                            ge<=4'b0;

                            shi<=4'b0;

                   end

         else

                   begin

                            ge<=counter1%10;

                            shi<=counter1/10;

                   end

end

 

reg [7:0]ge_SEG_DATA;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   ge_SEG_DATA<=8'hc0;

         else case(ge)

                   4'd0:ge_SEG_DATA<=8'hc0;

                   4'd1:ge_SEG_DATA<=8'hf9;

                   4'd2:ge_SEG_DATA<=8'ha4;

                   4'd3:ge_SEG_DATA<=8'hb0;

                   4'd4:ge_SEG_DATA<=8'h99;

                   4'd5:ge_SEG_DATA<=8'h92;

                   4'd6:ge_SEG_DATA<=8'h82;

                   4'd7:ge_SEG_DATA<=8'hf8;

                   4'd8:ge_SEG_DATA<=8'h80;

                   4'd9:ge_SEG_DATA<=8'h90;

                   default:ge_SEG_DATA<=8'hff;

                            endcase

end

 

reg [7:0]shi_SEG_DATA;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

                   shi_SEG_DATA<=8'hc0;

         else case(shi)

                   4'd0:shi_SEG_DATA<=8'hc0;

                   4'd1:shi_SEG_DATA<=8'hf9;

                   4'd2:shi_SEG_DATA<=8'ha4;

                   4'd3:shi_SEG_DATA<=8'hb0;

                   4'd4:shi_SEG_DATA<=8'h99;

                   4'd5:shi_SEG_DATA<=8'h92;

                   4'd6:shi_SEG_DATA<=8'h82;

                   4'd7:shi_SEG_DATA<=8'hf8;

                   4'd8:shi_SEG_DATA<=8'h80;

                   4'd9:shi_SEG_DATA<=8'h90;

                   default:shi_SEG_DATA<=8'hff;

                     endcase

end

 

reg [1:0]rSEG_SEL;

reg [7:0]rSEG_DATA;

always @(posedge CLK or negedge RSTn)

begin

         if(!RSTn)

         begin

                   rSEG_SEL<=2'b01;

                   rSEG_DATA<=8'hc0;

         end

         else case(t)

                            1'b0:begin

                                               rSEG_SEL<=2'b01;

                                               rSEG_DATA<=ge_SEG_DATA;

                                       end

                            1'b1:begin

                                               rSEG_SEL<=2'b10;

                                               rSEG_DATA<=shi_SEG_DATA;

                                       end

                            default:begin

                                                        rSEG_SEL<=2'b11;

                                                        rSEG_DATA<=8'hff;

                                                        end

                            endcase

end

 

assign SEG_DATA=rSEG_DATA;

assign SEG_SEL=rSEG_SEL;

 

endmodule

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章