赞
踩
在我们的日常开发中,数字显示的领域中用得最多的就是数码管,这篇文章也是围绕数码管的静态显示和动态显示进行一个讲解。
(1)数码管原理图
在对数码管进行相关控制时,其实就是对于8段发光二极管和一个位选信号进行控制,也就是我们熟悉的段选和位选。段选就包括a,b,c,d,e,f,g,h这八个二极管,位选就是选择某个二极管工作的一个简单引脚。
市场上我们常见的数码管有共阴极啊和共阳极两种信号,其外观上没有什么区别,都是通过原理图进行判断和区分,两种数码挂对应的驱动方式也不一样。共阴极是高电平驱动,共阳极是低电平驱动。所谓的共阴极和共阳极实际上就是看公共引脚接在正极还是负极上。
其实在原理图中并没有明确说明是共阴极还是共阳极,我们需要通过SEL位选信号进行判断。在最下面的三极管我们可以看到只有当SELx_T为低电平时三极管才会接通,所以这里通过判断是共阳极,通过低电平触发。
(1)、设计文件
新建seg.v文件,如下:
这里不需要使用任何时序功能,只是简单显示一个数字,直接就用连续赋值进行实现。这里代码过于简单,就不去进行仿真和下板验证了。
- module top(
- output seg_sel,
- output [7:0] seg_dual
- );
-
- assign seg_sel=1'b0;//选择第一个数码管
- assign seg_dual=8'b11_000_000;//数码管显示0
(1)、设计文件
- //分频器
- module seg0(
- input clk,
- input rst_n,
-
- input seg_sel,//位选
- output reg [7:0] seg_dual0//段选
- );
- localparam ZERO = 8'b11100_0000, //共阳极段码
- ONE = 8'b11111_1001,
- TWO = 8'b11010_0100,
- THREE = 8'b11011_0000,
- FOUR = 8'b11001_1001,
- FIVE = 8'b11001_0010,
- SIX = 8'b11000_0010,
- SEVEN = 8'b11111_1000,
- EIGHT = 8'b11000_0000,
- NINE = 8'b11001_0000,
- A = 8'b11000_1000,
- b = 8'b11000_0011,
- c = 8'b11100_0110,
- d = 8'b11010_0001,
- E = 8'b11000_0110,
- f = 8'b11000_1110;
- reg [26:0] cnt;
- wire add_cnt;
- wire end_cnt;
- reg [4:0] flag;
- wire add_flag;
- wire end_flag;
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)
- cnt<=0;
- else if(add_cnt)begin
- if(end_cnt)
- cnt<=0;
- else
- cnt<=cnt+1'b1;
- end
- end
- assign add_cnt=1'b1;
- assign end_cnt=add_cnt && (cnt==50_000_000-1);
-
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)
- flag<=0;
- else if(add_flag)begin
- if(end_flag)
- flag<=0;
- else
- flag<=flag+1'b1;
- end
- end
- assign add_flag=end_cnt;
- assign end_flag=add_flag && (flag==16-1);
-
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)
- seg_dual0<=8'b1111_1111;
- else begin
- case (flag)
- 4'd0:seg_dual0<=ZERO ;
- 4'd1:seg_dual0<=ONE ;
- 4'd2:seg_dual0<=TWO ;
- 4'd3:seg_dual0<=THREE;
- 4'd4:seg_dual0<=FOUR ;
- 4'd5:seg_dual0<=FIVE ;
- 4'd6:seg_dual0<=SIX ;
- 4'd7:seg_dual0<=SEVEN;
- 4'd8:seg_dual0<=EIGHT;
- 4'd9:seg_dual0<=NINE ;
- 4'd10:seg_dual0<=A ;
- 4'd11:seg_dual0<=b ;
- 4'd12:seg_dual0<=c;
- 4'd13:seg_dual0<=d;
- 4'd14:seg_dual0<=E ;
- 4'd15:seg_dual0<=f ;
- default: ;
- endcase
- end
- end
- endmodule
(2)、测试文件
- //定义时间尺度
- `timescale 1ns/1ns
- module seg_tb ;
-
- //输入信号定义
- reg clk;
- reg rst_n;
-
- wire [7:0] seg_dual0;
- wire seg_sel;
- defparam seg0_inst.TIME_1s=500;
- //模块例化
- seg0 seg0_inst(
- /*input */.clk (clk ),
- /*input */.rst_n (rst_n ),
- /*output*/.seg_sel (seg_sel ),
- /*output*/.seg_dual0 (seg_dual0)
- );
- //激励信号产生
- parameter CLK_CLY = 20;
- //时钟
- initial clk=1;
- always #(CLK_CLY/2)clk=~clk;
-
- //复位
- initial begin
- rst_n= 1'b0;
- #(CLK_CLY*3);
- #5;//复位结束避开时钟上升沿
- rst_n= 1'b1;
- end
- endmodule
(3)、波形图仿真
在波形图中我们可以看到段选从8'b11_000_000——8'b11_000_1110,也就是从0——F动态显示。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。