• FPGA学习—数码管显示


    FPGA学习——数码管显示



    结构框架

    数码管动态显示采用了人眼暂存的原理,即时分复用,在数码管实现动态显示。
    整个实验设计流程框架如下图所示:
    在这里插入图片描述


    一、硬件设计

    开发板采用共阳极数码管,即低电平点亮。
    在这里插入图片描述

    二、verilog编写

    1.计数器

    本实验准备设计一个定时器,6为数码管显示24小时制的时间,所以编写一个计数模块。

    module counter_10
    #(
      parameter	COUNT = 4'd9
    	)
    (
      input             clk,
      input             rst_n,
      input             en,
      input             clr,
      
      output  reg[3:0]  count,
      output  reg       t
      );
      
    always@(posedge clk or negedge rst_n)
    begin 
     if(rst_n == 1'b0)
      begin
    	count <= 4'd0;
    	t <= 1'b0;
      end
     else if(clr == 1'b1)
      begin
    	count <= 4'd0;
    	t <= 1'b0;
      end 
     else if(en== 1'b1)
      if(count == COUNT)
        begin
    	  count <= 4'd0;
    	  t <= 1'b1;
        end 
      else
    	begin
    	  count <= count + 4'd1;
    	  t <= 1'b0;
        end
     else
    	begin
    	 count <= count;
    	 t <= 1'b0;
      end 
    		
    end
    	
    endmodule
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    改变变量COUNT的数值,可实现不同模的计数器。

    2.译码模块

    module seg_decoder
    (
    	input		[3:0]	bin_data,
    	output	reg	[7:0]	seg_data
    );
    
    always@(*)
    begin
    	case(bin_data)
    		4'd0:seg_data <= 8'b1100_0000;
    		4'd1:seg_data <= 8'b1111_1001;
    		4'd2:seg_data <= 8'b1010_0100;
    		4'd3:seg_data <= 8'b1011_0000;
    		4'd4:seg_data <= 8'b1001_1001;
    		4'd5:seg_data <= 8'b1001_0010;
    		4'd6:seg_data <= 8'b1000_0010;
    		4'd7:seg_data <= 8'b1111_1000;
    		4'd8:seg_data <= 8'b1000_0000;
    		4'd9:seg_data <= 8'b1001_0000;
    		4'ha:seg_data <= 8'b1000_1000;
    		4'hb:seg_data <= 8'b1000_0011;
    		4'hc:seg_data <= 8'b1100_0110;
    		4'hd:seg_data <= 8'b1010_0001;
    		4'he:seg_data <= 8'b1000_0110;
    		4'hf:seg_data <= 8'b1000_1110;
    		default:seg_data <= 8'b1111_1111;
    	endcase
    end
    
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    将计数器的十进制数按照译码准则转换为8位二进制,控制数码管的段选位。

    3.数码管扫描模块

    module seg_scan
    #(
    	parameter SCAN = 13'd4999,
    	parameter SEG  = 3'd5)
    (
    	input				clk,
    	input				rst_n,
    	input		[7:0]	seg_data0,
    	input		[7:0]	seg_data1,
    	input		[7:0]	seg_data2,
    	input		[7:0]	seg_data3,
    	input		[7:0]	seg_data4,
    	input		[7:0]	seg_data5,
    	
    	output	reg[5:0]	seg_sel,
    	output	reg[7:0]	seg_data
    	);
    reg [12:0]	timer;
    reg [2:0]	seg;
    	
    always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
    	timer <= 13'd0;
    else if(timer == SCAN)
    	timer <= 13'd0;
    else
    	timer <= timer + 13'd1;
    	
    always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
    	seg <= 3'd0;
    else if(seg == SEG && timer == SCAN)
    	seg <= 3'd0;
    else if(timer == SCAN)
    	seg <= seg + 3'd1;
    	
    always@(posedge clk or negedge rst_n)
    if(rst_n == 1'b0)
    	begin
    		seg_sel <= 6'b0000_00;
    		seg_data <= 8'b0000_0000;
    	end
    else 
    	case(seg)
    		3'd0:
    			begin 
    				seg_sel <= 6'b0111_11;
    				seg_data <= seg_data0;
    			end
    		3'd1:
    			begin 
    				seg_sel <= 6'b1011_11;
    				seg_data <= seg_data1;
    			end
    		3'd2:
    			begin 
    				seg_sel <= 6'b1101_11;
    				seg_data <= seg_data2;
    			end
    		3'd3:
    			begin 
    				seg_sel <= 6'b1110_11;
    				seg_data <= seg_data3;
    			end
    		3'd4:
    			begin 
    				seg_sel <= 6'b1111_01;
    				seg_data <= seg_data4;
    			end
    		3'd5:
    			begin 
    				seg_sel <= 6'b1111_10;
    				seg_data <= seg_data5;
    			end
    		default:
    			begin
    				seg_sel <= 6'b1111_11;
    				seg_data <= 8'b1111_1111;
    			end
    	endcase
    	
    endmodule
    		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    扫描时间间隔设为0.01ms,人眼无法捕捉0.01ms的变化,进而实现6位数码管”同时“显示。

    4.顶层模块

    module seg_test
    #(
    	parameter	SCAN = 13'd4999,
    	parameter   SEG = 3'd5,
    	parameter	BAUD = 32'd49999999
    )
    (
    	input				clk,
    	input				rst_n,
    	
    	output	[5:0]	seg_sel,
    	output	[7:0]	seg_data
    );
    
    wire 		t0,t1,t2,t3,t4,t5;
    wire[3:0]	count0,count1,count2,count3,count4,count5;
    wire[7:0]	seg_data0,seg_data1,seg_data2,seg_data3,seg_data4,seg_data5;
    
    reg t;
    reg[25:0]	timer;
    
    always@(posedge clk or negedge rst_n)
    	if(rst_n == 1'b0)
    	begin
    		timer <= 26'd0;
    		t <= 1'b0;
    	end
    	else if(timer == BAUD)
    	begin
    		timer <= 26'd0;
    		t <= 1'b1;
    	end
    	else
    	begin
    		timer <= timer + 1'd1;
    		t <= 1'b0;
    	end			
    
    counter_10
    #(
      .COUNT(9)
    	)counter_10_0
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t),
      .clr		(1'b0),
                
      .count	(count0),
      .t		(t0)
      );
      
    counter_10
    #(
      .COUNT(5)
    	)counter_10_1
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t0),
      .clr		(1'b0),
                
      .count	(count1),
      .t		(t1)
      );
      
    counter_10
    #(
      .COUNT(9)
    	)counter_10_2
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t1),
      .clr		(1'b0),
                
      .count	(count2),
      .t		(t2)
      );
      
     counter_10
    #(
      .COUNT(5)
    	)counter_10_3
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t2),
      .clr		(1'b0),
                
      .count	(count3),
      .t		(t3)
      );
      
     counter_10
    #(
      .COUNT(3)
    	)counter_10_4
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t3),
      .clr		(1'b0),
                
      .count	(count4),
      .t		(t4)
      );
      
       counter_10
    #(
      .COUNT(2)
    	)counter_10_5
    (
      .clk		(clk),
      .rst_n	(rst_n),
      .en		(t4),
      .clr		(1'b0),
                
      .count	(count5),
      .t		(t5)
      );
      
    seg_decoder	seg_decoder_0
    (
    	.bin_data(count0),
    	.seg_data(seg_data0)
    );
    seg_decoder	seg_decoder_1
    (
    	.bin_data(count1),
    	.seg_data(seg_data1)
    );
    seg_decoder	seg_decoder_2
    (
    	.bin_data(count2),
    	.seg_data(seg_data2)
    );
    seg_decoder	seg_decoder_3
    (
    	.bin_data(count3),
    	.seg_data(seg_data3)
    );
    seg_decoder	seg_decoder_4
    (
    	.bin_data(count4),
    	.seg_data(seg_data4)
    );
    seg_decoder	seg_decoder_5
    (
    	.bin_data(count5),
    	.seg_data(seg_data5)
    );
    
    seg_scan
    #(
    	.SCAN(SCAN),
    	.SEG (SEG)
    )seg_scan
    (
    	.clk		(clk),
    	.rst_n		(rst_n),
    	.seg_data0	(seg_data0),
    	.seg_data1	(seg_data1),
    	.seg_data2	(seg_data2),
    	.seg_data3	(seg_data3),
    	.seg_data4	(seg_data4),
    	.seg_data5	(seg_data5),
    	
    	.seg_sel	(seg_sel),
    	.seg_data	(seg_data)
    	);
    	
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173

    实验结果

    在这里插入图片描述

  • 相关阅读:
    钡铼技术有限公司R40路由器工业4G让养殖环境监控更高效
    Leetcode 135. 分发糖果
    最简最快了解RPC核心流程
    Spring boot:解决@RequestBody失效问题:传入的实体类为NULL
    Redis 学习笔记
    lintcode 1840 · 矩阵还原【中等 vip 二维前缀和数组】
    http2分片流内容整合呈现方法
    2022金九银十 —— 招聘有感,给各位测试同学的一些建议
    编译丨迅为iTOP4412开发板Makefile编译
    循环结构:for循环,while循环,do-while,死循环
  • 原文地址:https://blog.csdn.net/m0_51390088/article/details/126300006