集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 1072|回复: 7

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

[复制链接]
zxopenljx 发表于 2020-5-16 14:09:38 | 显示全部楼层 |阅读模式
一、按键控制数码管循环显示的概念:
就是通过两个按键控制计数器里面的数据的加减,然后把计数器里面的数据转换成十进制,最后通过数码管把这个十进制显示出来。

二、电路原理
       整个电路共有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[31:0] 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[7:0] 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[7:0] bin_data;
    outputreg[11:0]bcd_data;
   
    always@(*)
    begin
       bcd_data[3:0]=  bin_data%10;
       bcd_data[7:4]=(bin_data/10)%10;
       bcd_data[11:8]=(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[15:0] 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;
    input[11:0]data_in;
    outputreg[2:0] sel;
    outputreg[7:0] seg;
   
    reg[1:0] state;
    reg[3:0] 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[11:8];
                                state <= s1;                                       
                            end
                        s1 :
                            begin
                                sel <=3'b100;
                                data_temp <= data_in[7:4];
                                state <= s2;                              
                           end
                        s2 :
                            begin
                                sel <=3'b101;
                                data_temp <= data_in[3:0];
                                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至顶而下的设计思路。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
 楼主| zxopenljx 发表于 2023-8-31 17:56:02 | 显示全部楼层
按键控制数码管循环显示0-255
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-11-27 18:50 , Processed in 0.063564 second(s), 23 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表