zxopenljx 发表于 2020-5-16 14:09:38

按键控制数码管循环显示0-255

一、按键控制数码管循环显示的概念:
就是通过两个按键控制计数器里面的数据的加减,然后把计数器里面的数据转换成十进制,最后通过数码管把这个十进制显示出来。

二、电路原理
       整个电路共有6个模块组成,两个按键检测模块,一个计数模块,一个二进制转十进制模块,一个分频模块以及一个数码管控制模块。按键检测模块主要是用于检测按键有没有被按下以及对被按下的键进行消抖操作。按键消抖的原理是检测它的电平,当检测到低电平后延时5ms-10ms仍有低电平说按键按下稳定,此时即可输出检测信号,这就实现了按键的检测与消抖。当按键模块检测到按键被按下时就会输出一个flag信号,并将此信号传给计数模块。计数模块在接受到flah信号时就对寄存器进行加1或减1操作,当加到255时,就把计数器清零,当减到零时就把寄存器置为255,这样就实现了计数器的循环计数。由于计数器里面的数据是二进制的,所以还要把计数器里的数据输出,传给二进制转十进制模块,进行二进制转十进制。转换得到的数据再传给数码管控制模块,并将数据显示出来。

三、架构图设计:

四、建模与验证:
1. 按键检测模块代码
module key_check (clk, rst_n, key_in, flag);

    input clk;
    input rst_n;
    input key_in;
    outputreg flag;   
   
    reg count;
    reg state;
   
    `define T 50_000_000/100//延时10ms的参数
// `define T 5   //fang zhen shi yong
   
    always@(posedge clk ornegedge rst_n)
    begin
       if(!rst_n)
         begin
                flag <=0;
                count <=0;
                state <=0;
         end
       else
         begin
                case(state)
                     0:begin
                           if(!key_in)
                              begin
                                    if(count <`T-1)
                                        begin
                                          count <= count +1'b1;
                                        end
                                    else
                                        begin
                                           count <=0;
                                          flag <=1;
                                           state <=1;
                                        end
                              end
                            else
                              begin
                                    count <=0;
                                    flag <=0;
                                    state <=0;
                              end
                        end
                        
                  1:begin
                            flag <=0;
                            if(key_in)
                              begin
                                    if(count <`T-1)
                                        count <= count +1'b1;
                                    else
                                        begin
                                           count <=0;
                                           flag <=0;
                                           state <=0;
                                        end
                              end
                            else
                              begin
                                    count <=0;
                                    state <=1;
                              end
                         end
                endcase
         end
    end

endmodule

2. 计数模块代码
module count(clk, rst_n, flag1, flag2, cnt_num);

    input clk;
    input rst_n;
    input flag1, lag2;
    outputreg cnt_num;
   
    always@(posedge clk ornegedge rst_n)
    begin
       if(!rst_n)
         begin
                cnt_num <=8'd0;
         end
       else
         begin
                if(cnt_num <0)
                  cnt_num <=8'd255;
                elseif(cnt_num >255)
                            cnt_num <=8'd0;
                      else
                            if(flag1)
                              cnt_num <= cnt_num +1'b1;
                            else
                              if(flag2)
                                 cnt_num <= cnt_num -1'b1;
                              else cnt_num <= cnt_num;
         end
    end

endmodule

3. 二进制转十进制模块代码
module bin_bcd_2(bin_data, bcd_data);

    input bin_data;
    outputregbcd_data;
   
    always@(*)
    begin
       bcd_data=bin_data%10;
       bcd_data=(bin_data/10)%10;
       bcd_data=(bin_data/100)%10;
    end
   
endmodule

4. 分频模块代码
module devide(clk, rst_n, clk_out);

    input clk;
    input rst_n;
    outputreg clk_out;
   
    parameter HW =24_999;
   
    reg count;

   
    always@(posedge clk ornegedge rst_n)
    begin
       if(!rst_n)
         begin
                clk_out <=0;
                count <=0;
         end
       else
         begin
                if(count < HW -1)
                  count <= count +1'b1;
                else
                  begin
                        count <=0;
                        clk_out <=~clk_out;
                  end
         end   
    end

endmodule

5. 数码管模块代码
module seg_state(clk,rst_n,data_in,sel,seg);

    input clk;
    input rst_n;
    inputdata_in;
    outputreg sel;
    outputreg seg;
   
    reg state;
    reg data_temp;
   
    parameter s0 =2'd0;
    parameter s1 =2'd1;
    parameter s2 =2'd2;
// parameter s3 = 2'd3;
// parameter s4 = 2'd4;
// parameter s5 = 2'd5;
   
    always@(posedge clk ornegedge rst_n)
       begin
         if(!rst_n)
                begin
                  state <= s0;
                  sel <=3'b111;
                  data_temp <=4'd0;
                end
         else
                begin
                  case(state)
                        s0 :
                            begin
                              sel <=3'b011;
                              data_temp <= data_in;
                              state <= s1;                                       
                            end
                        s1 :
                            begin
                              sel <=3'b100;
                              data_temp <= data_in;
                              state <= s2;                              
                           end
                        s2 :
                            begin
                              sel <=3'b101;
                              data_temp <= data_in;
                              state <= s0;                           
                            end
                        default: state <= s0;
                  endcase
                end
       end
      
      
    always@(*)
    begin
       if(!rst_n)
         begin
                seg <=8'b0111_1111;
         end
       else
         begin
                case(data_temp)
//            case (data_in)
                  4'd0: seg <=8'hc0;      //0
                  4'd1: seg <=8'hf9;      //1
                  4'd2: seg <=8'ha4;      //2
                  4'd3: seg <=8'hb0;      //3
                  
                  4'd4: seg <=8'h99;      //4
                  4'd5: seg <=8'h92;      //5
                  4'd6: seg <=8'h82;      //6
                  4'd7: seg <=8'hf8;      //7
                  
                  4'd8: seg <=8'h80;      //8
                  4'd9: seg <=8'h90;      //9
                  4'd10: seg <=8'h88;   //a
                  4'd11: seg <=8'h83;   //b
                  
                  4'd12: seg <=8'hc6;   //c
                  4'd13: seg <=8'ha1;   //d
                  4'd14: seg <=8'h86;   //e
                  4'd15: seg <=8'h8e;   //f
                  
                  default: seg <=8'b0111_1111;
                endcase
         end
    end

endmodule

6. RTL级视图

7. 仿真结果图

总结:在把代码下板后,通过按键可以看到数码管显示的数据,当到了255后加1就变为0,当到了0后减1就是255,这就达到了我们循环显示的目的。本次的设计是一个比较综合的设计,把前面所学的按键,数码管,二进制转十进制都结合了起来。涉及的东西比较的多,过程相对比较多而复杂,但通过分成多个模块来解决问题,就变简单了许多,这就体现了FPGA至顶而下的设计思路。

zxopenljx 发表于 2023-8-31 17:56:02

按键控制数码管循环显示0-255
页: [1]
查看完整版本: 按键控制数码管循环显示0-255