FPGA之动态数码管显示实验

16 篇文章 1 订阅

1.试验任务

  •  完成6位数码管以动态方式从0开始计数,没100ms计数值增加1,当计数值从0增加到999999后重新从0开始计数。

2.硬件原理图

3.程序框图

  • 程序设计思想:

FPGA顶层(top_seg_led)例化了以下两个模块:计数模块(count)以及数码管动态显示模块(seg_led)。实现各模块之间数据的交互。计数模块将计数值通过data端口传递给数码管动态显示模块, 使能信号en使能数码管显示数据, 小数点显示信号point控制小数点的显示,符号信号sign可以让数码管显示负号。

计数模块(count):显示的数字每100ms加“1”。

数码管动态显示模块 (seg_led) : 数码管动态显示模块在数码管上以动态方式显示数值。

module top_seg_led(
    input    sys_clk,
    input    sys_rst_n,

    output [5:0] seg_wei,
    output [7:0] seg_duan 
);

wire [19:0] seg_num;

time_count u_time_count(
        .sys_clk   (sys_clk),
        .sys_rst_n (sys_rst_n),
        .seg_num  (seg_num)
);

seg_led u_seg_led(
  .sys_clk    (sys_clk),
  .sys_rst_n  (sys_rst_n),
  .seg_num    (seg_num),
  .seg_wei    (seg_wei),
  .seg_duan   (seg_duan)
);
endmodule

 

module time_count(
    input    sys_clk,
    input    sys_rst_n,

    output reg [19:0] seg_num
    
);

reg [22:0] time_num;
reg time_flag;

always @(posedge sys_clk or negedge sys_rst_n)begin
      if(!sys_rst_n)begin
        time_num<=23'd0;
        time_flag<=1'b0;
      end

      else begin
           if(time_num<23'd5_000_000)begin
              time_num<=time_num+1'b1;
              time_flag<=1'b0;
           end

           else begin
              time_num <=23'd1; 
              time_flag<=1'b1;  
           end

      end
end




always @(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)begin
       seg_num<=20'd0;  
    end
    else begin
      if(time_flag&&seg_num<20'd1_000_000)
        seg_num<=seg_num+1'b1;

      else if(seg_num==20'd1_000_000)
        seg_num<=20'd0;
      else 
         seg_num<=seg_num;
    end
end
endmodule

 

module seg_led(
    input  sys_clk,
    input  sys_rst_n,

    input      [19:0] seg_num,
    output reg [5:0] seg_wei,
    output reg [7:0] seg_duan
);

wire [23:0] data_num;   //每位数码管需要显示的数

assign data_num[3:0]  =seg_num%10;
assign data_num[7:4]  =seg_num/4'd10%10;
assign data_num[11:8] =seg_num/7'd100%10;
assign data_num[15:12]=seg_num/10'd1000%10;
assign data_num[19:16]=seg_num/14'd10000%10;
assign data_num[23:20]=seg_num/17'd100000;

/
reg [22:0] time_num;
reg time_flag;

always @(posedge sys_clk or negedge sys_rst_n)begin
      if(!sys_rst_n)begin
        time_num<=23'd0;
        time_flag<=1'b0;
      end
      else 
        begin
           if(time_num<23'd100_000)begin
              time_num<=time_num+1'b1;
              time_flag<=1'b0;
           end

           else begin
              time_num <=23'd1; 
              time_flag<=1'b1;  
           end
       end
end
/
reg  [3:0] seg_static;

always @(posedge sys_clk or negedge sys_rst_n)begin
      if(!sys_rst_n)
      seg_static<=4'd0;
      else begin
        if(seg_static<4'd6&&time_flag)
        seg_static<=seg_static+1'b1;
        else  if(seg_static==4'd6)
        seg_static<=4'd0;
        else
         seg_static<=seg_static;    
      end
end


always @(posedge sys_clk or negedge sys_rst_n)begin
      if(!sys_rst_n)begin
         seg_wei  <=6'b000000;
         seg_duan<=8'b1111111;
      end

      else begin
          case(seg_static)
          4'd0:   begin      
         seg_wei  <=6'b111110;
             case (data_num[3:0]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          4'd1:begin      
         seg_wei  <=6'b111101;
             case (data_num[7:4]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          4'd2:begin      
         seg_wei  <=6'b111011;
             case (data_num[11:8]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          4'd3:begin      
         seg_wei  <=6'b110111;
             case (data_num[15:12]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          4'd4:begin      
         seg_wei  <=6'b101111;
             case (data_num[19:16]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          4'd5:begin      
         seg_wei  <=6'b011111;
             case (data_num[23:20]) 
             4'd0 : seg_duan   <= 8'b1100_0000; //显示数字 0 
             4'd1 : seg_duan   <= 8'b1111_1001; //显示数字 1 
             4'd2 : seg_duan   <= 8'b1010_0100; //显示数字 2 
             4'd3 : seg_duan   <= 8'b1011_0000; //显示数字 3 
             4'd4 : seg_duan   <= 8'b1001_1001; //显示数字 4 
             4'd5 : seg_duan   <= 8'b1001_0010; //显示数字 5 
             4'd6 : seg_duan   <= 8'b1000_0010; //显示数字 6 
             4'd7 : seg_duan   <= 8'b1111_1000; //显示数字 7 
             4'd8 : seg_duan   <= 8'b1000_0000; //显示数字 8
             4'd9 : seg_duan   <=  8'b1001_0000;
             endcase
          end
          endcase
      end
end


endmodule

仿真 结果如下:

 

起初调试的时候只有最低为显示自加1,原因为led_static的 计数写的后问题 ,后进行改进

 

PS:补一下上周的实验仿真调试

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
按键计数将结果通过8段数码管显示FPGA设计Verilog逻辑源码Quartus11.0工程文件,FPGA型号为CYCLONE4E系列中的EP4CE6E22C8,可以做为你的学习设计参考。 module key_counter(clk,key,reset,seg_duan,seg_wei); input clk,key,reset; output [7:0] seg_duan; output [2:0] seg_wei; wire clk,key,reset; reg [7:0] seg_duan;//数码管段选 reg [2:0] seg_wei;//数码管位选 reg key_out; parameter s0=2'b00,s1=2'b01,s2=2'b10,s3=2'b11; reg [1:0] state; reg [3:0] key_counter_ge;//按键计数个位 reg [3:0] key_counter_shi;//按键计数十位 reg [3:0] key_counter_bai;//按键计数百位 reg [9:0] div_count;//数码管扫描时钟分频计数 reg clk_scan;//位选时钟 reg [1:0] wei_select;//位选信号 /****************************按键消抖**********************************/ always @(posedge clk) begin case (state) s0: begin key_out<=1'b1; if(key==1'b0) state<=s1; else state<=s0; end s1: begin if(key==1'b0) state<=s2; else state<=s0; end s2: begin if(key==1'b0) state<=s3; else state<=s0; end s3: begin if(key==1'b0) begin key_out<=1'b0; state<=s3; end else begin key_out<=1'b1; state<=s0; end end default: state<=s0; endcase end /****************************按键计数**********************************/ always @(negedge key_out or negedge reset) begin if(!reset) begin key_counter_ge <=4'd0; key_counter_shi<=4'd0; key_counter_bai<=4'd0; end else begin if(!key_out)//判断按键是否按下 begin key_counter_ge<=key_counter_ge+1'b1;//按键计数个位加一 if(key_counter_ge==4'd9) begin key_counter_ge<=4'd0;//个位清零 key_counter_shi<=key_counter_shi+1'b1;//按键计数十位加一 if(key_counter_shi==4'd9) begin key_counter_shi<=4'd0;//十位清零

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值