小梅哥的按键思想

01 module key_scan_flctek(clk, rst_n,key_in, key_n);
02
03     inputclk;
04     inputrst_n;
05     inputkey_in;
06     outputreg key_n;
07
08     regtemp;
09     reg[31:0] count;
10     regstate;
11     
12     localparam  MASK_tiME = 1000000;
13     
14     always@(posedge clk or negedge rst_n)
15     begin
16              if(!rst_n)
17                 begin
18                                 state<= 0;
19                                 temp<= 1;
20                                 count<= 0;
21                                 key_n<= 1;
22                       end
23              else
24           case(state)
25                 0 :  begin
26                                          if(key_in== temp)
27                                              state <= 0;
28                                          else  begin
29                                              state <= 1;        
30                                                   temp<= key_in;
31                  end   
32                                 end
33                 1:  begin
34                                if(key_in == temp)
35                                                   if(count < MASK_TIME-1)
36                                                             begin
37                                                                      count<= count + 1;
38                                                                      state<= 1;
39                                                             end
40                                                   else
41                                                             begin
42                                                                      key_n<= temp;
43                                                                      count<= 0;
44                                                                      state<= 0;                                                                                            
45                                                             end
46                                          else
47                   begin
48                                                   temp<= key_in;
49                                                   count <=0;
50                                                   state<= 1;        
51                                          end
52                                          end
53                       endcase            
54     end
55
56 endmodule


计数模块程序

01     modulecount_key(rst_n, key_n, count_key);
02
03     inputkey_n,rst_n;
04     output  reg [19:0] count_key;
05
06 //此处必须以按键状态为时钟不能采用组合逻辑以按键状态为判断条件做判断,
07 //这样的话当按键状态为低电平时计数器会一直计数
08 //而实际的要求是如果按键按下则计一次数相背。
09 always @(posedge key_n or negedge rst_n)
10 begin
11     if(!rst_n)
12                 begin
13                                 count_key= 0;
14                       end
15              else  if((count_key < 20'd999999))
16                                          count_key= count_key + 1;
17              else
18                       count_key= count_key;  
19
20                                          
21 end
22
23     endmodule

二进制转BCD部分(采用“大四加三”法)

给大家来个例子说明一下例如输入的二进制数是8’b1111_1111,经过逐步移位的方法最终得到的BCD码为:12’b1_0101_0101,其对应的十进制百位,十位,个位,分别是:2,5,5.这种移位的方法首先设计者必须清楚的是被转换的二进制数的位宽,和最终转换为BCD码的位宽,由于中间用到一个移位寄存器此移位寄存器的位宽等于被转的二进制数位宽加上最终转换的BCD码的位宽。所以本例中的移位寄存器位宽为20,采用这种方法移位的此处比位修正的次数多一次,即就是最后一次只进行移位操作,而不进行位修正计数(每位所对应的4位BCD码如果大于四必须进行加三操作)。应用这种方法移完即可得到对应的BCD码。本例子的以为过程及修正如下表所示:


二进制转BCD代码部分

01     moduleb_BCD(count_key, data_out);
02
03     input[19:0] count_key;
04     output[23:0] data_out;
05     
06     wire[43:0] shift_reg [19:0];
07     
08     assignshift_reg[19] = {23'b0, count_key, 1'b0};
09     
10     
11  bcd_modify b19(.data_in(shift_reg[19]), .data_out(shift_reg[18]));
12  bcd_modify b18(.data_in(shift_reg[18]), .data_out(shift_reg[17]));
13  bcd_modify b17(.data_in(shift_reg[17]), .data_out(shift_reg[16]));
14     bcd_modify b16(.data_in(shift_reg[16]), .data_out(shift_reg[15]));
15  bcd_modify b15(.data_in(shift_reg[15]), .data_out(shift_reg[14]));
16  bcd_modify b14(.data_in(shift_reg[14]), .data_out(shift_reg[13]));
17  bcd_modify b13(.data_in(shift_reg[13]), .data_out(shift_reg[12]));
18  bcd_modify b12(.data_in(shift_reg[12]), .data_out(shift_reg[11]));
19     bcd_modify b11(.data_in(shift_reg[11]), .data_out(shift_reg[10]));
20  bcd_modify b10(.data_in(shift_reg[10]), .data_out(shift_reg[9]));
21  bcd_modify b9(.data_in(shift_reg[9]), .data_out(shift_reg[8]));
22  bcd_modify b8(.data_in(shift_reg[8]), .data_out(shift_reg[7]));
23  bcd_modify b7(.data_in(shift_reg[7]), .data_out(shift_reg[6]));
24     bcd_modify b6(.data_in(shift_reg[6]), .data_out(shift_reg[5]));
25  bcd_modify b5(.data_in(shift_reg[5]), .data_out(shift_reg[4]));
26  bcd_modify b4(.data_in(shift_reg[4]), .data_out(shift_reg[3]));
27  bcd_modify b3(.data_in(shift_reg[3]), .data_out(shift_reg[2]));
28  bcd_modify b2(.data_in(shift_reg[2]), .data_out(shift_reg[1]));
29     bcd_modify b1(.data_in(shift_reg[1]), .data_out(shift_reg[0]));
30
31
32     assigndata_out = shift_reg[0][43:20];//取出data_out的高24位即为所求的BCD码
33
34     endmodule
01     modulebcd_modify(data_in, data_out);
02
03     input[43:0] data_in;
04     output[43:0] data_out;
05
06     wire[43:0] reg_out;
07
08     bcd_sigle_modifybcd_6(.data_in(data_in[43:40]), .data_out(reg_out[43:40]));
09     bcd_sigle_modifybcd_5(.data_in(data_in[39:36]), .data_out(reg_out[39:36]));
10     bcd_sigle_modifybcd_4(.data_in(data_in[35:32]), .data_out(reg_out[35:32]));
11     bcd_sigle_modifybcd_3(.data_in(data_in[31:28]), .data_out(reg_out[31:28]));
12     bcd_sigle_modifybcd_2(.data_in(data_in[27:24]), .data_out(reg_out[27:24]));
13     bcd_sigle_modifybcd_1(.data_in(data_in[23:20]), .data_out(reg_out[23:20]));
14
15
16     assignreg_out[19:0] = data_in[19:0];  //相当于将每次只做高24位的修正地位不做修正,低20位的数据
17 assign data_out = {reg_out[42:0],1'b0};
18
19     endmodule
01 module bcd_sigle_modify(data_in,data_out);
02
03     input[3:0] data_in;
04     outputreg [3:0] data_out;
05     
06     always@ (data_in)
07     begin
08              if(data_in> 4)
09                data_out = data_in + 3;
10              else
11           data_out = data_in;     
12     end
13     
14 endmodule

数码管显示部分程序

01 module seg_n(clk, rst_n, data_in, sel,seg);
02
03     inputclk;
04     inputrst_n;
05     input[23:0] data_in;
06     outputreg [2:0] sel;
07     outputreg [7:0] seg;
08   
09     wireclk_en;  //数码管显示时钟标志高电平有效
10     reg[31:0] count;
11
12     
13     always@(posedgeclk or negedge rst_n)
14     begin
15              if(!rst_n)   begin
16                       count<= 0;
17              end  
18              elseif(count < 24999)
19                       count<= count + 1'b1;
20              elsebegin
21                 count <= 0;         
22              end  
23     end
24
25     assignclk_en = (count == 24999)? 1'b1 : 1'b0;
26
27//产生片选信号
28     always@(posedgeclk or negedge rst_n)
29     begin
30              if(!rst_n)
31                       sel<= 3'b101;
32              elseif(clk_en)
33              begin        
34                       if((0< sel)&&(sel <= 5))
35                                 sel<= sel- 1'b1;
36                       elsesel <= 3'b101;
37              end  else  
38                       sel<= sel;                           
39     end
40     
41     reg[3:0] data_n;
42//获取所要显示的数据      
43     always@(*)
44     begin
45              if(!rst_n)
46                       data_n<= 24'hfffff0;
47              elsecase(sel)
48                       0:data_n <= data_in [23:20];
49                       1:data_n <= data_in [19:16];
50                       2:data_n <= data_in [15:12];
51                       3:data_n <= data_in [11:8];
52                       4:data_n <= data_in [7:4];
53                       5:data_n <= data_in [3:0];
54                       default:data_n <=0;
55              endcase
56     end
57//进行译码操作
58     always@(*)
59     begin
60              if(!rst_n)
61                       seg<= 8'hff;
62              elsecase(data_n)   
63                                 0:seg = 8'hc0;
64                                 1:seg = 8'hf9;
65                                 2:seg = 8'ha4;
66                                 3:seg = 8'hb0;
67                                 4:seg = 8'h99;
68                                 5:seg = 8'h92;
69                                 6:seg = 8'h82;
70                                 7:seg = 8'hf8;
71                                 8:seg = 8'h80;
72                                 9:seg = 8'h90;
73                          10: seg = 8'h8f;
74                          11: seg = 8'hbf;
75                          12: seg = 8'h89;
76                          13: seg = 8'had;
77                          14: seg = 8'hb7;
78                          15: seg = 8'hff;
79                       endcase   
80     end
81 endmodule

系统顶层程序

module key_seg_top(clk, rst_n, key_in, sel,seg);
         inputclk;
         inputrst_n;
         inputkey_in;
         output[2:0] sel;
         output[7:0] seg;
         
         wirekey_n;
         wire[19:0] count_key;
         wire[23:0] data_in ;
         
         key_scan_flctekkey_scan_flctek_inst(.clk(clk), .rst_n(rst_n), .key_in(key_in),.key_n(key_n));  //该模块主要是用来进行按键检测及按键消抖用的
         
         count_keycount_key_inst(.rst_n(rst_n), .key_n(key_n), .count_key(count_key));//此模块主要是实现按键次数的计数
         
       b_BCDb_BCD_inst(.count_key(count_key), .data_out(data_in)); //此模块主要实现将按键次数的计数值转化为BCD码,然后将转化的数值发送给数码管显示模块
         
         seg_nseg_inst(.clk(clk), .rst_n(rst_n), .data_in(data_in), .sel(sel), .seg(seg));//实现数码管显示模块
endmodule

测试模块程序

`timescale 1ns/1ns
module key_seg_top_tb;
         regclk;
         regrst_n;
         regkey_in;
         wire[2:0] sel;
         wire[7:0] seg;
         key_seg_topkey_seg_top_inst(.clk(clk), .rst_n(rst_n), .key_in(key_in), .sel(sel),.seg(seg));
         initial  begin
           clk = 1;
           rst_n= 0;
           key_in = 1;
           #20.1 rst_n = 1;
           
           
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                 #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                  key_in = 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
                          #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;
           
                   #200
                   key_in= 0;
                  
                   //抬起小于10拍
                   #400
                   key_in= 1;
                   #10
                   key_in= 0;
                   #20
                   key_in= 1;
                   #80
                   key_in= 0;
                  
                   //一直抬起
                   key_in= 1;         
         end
         
         always#10 clk = ~clk;
         
endmodule      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值