FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static

文章目录

  • 数码管静态显示seg_595_static
    • 实验原理
    • 74HC595
    • 实验框图、波形图与代码原理

数码管静态显示seg_595_static

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数一般分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管(多一个小数点显示)。

实验原理

八段数码管是一个八字型数码管,分为八段:a、b、c、d、e、f、g、dp,其中dp为小数点,每一段即为一个发光二极管,这样的八段我们称之为段选信号。数码管常用的有10根管脚,每一段有一根管脚,另外两根管脚为一个数码管的公共端,两根互相连接。
FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第1张图片

数码管分为共阳极数码管和共阴极数码管。共阳极数码管就是把发光二极管的正极连接在一起作为一个引脚,负极分开。相反的,共阴极数码管就是把发光二极管的阴极连接在一起作为一个引脚,正极分开。这两者的区别在于,公共端是连接到地还是高电平,对于共阳极数码管需要给对应段低电平才会使其点亮,而对于共阴极数码管则需要 给其高电平才会点亮。本次实验使用的是共阳极数码管,也就是说给对应段低电平才会被点亮。给不同的段点亮可显示0~f的值。
FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第2张图片

二进制段码右边为高位左边为低位。我们只要点亮相应的段码,就能显示我们需要显示的内容。

段式数码管工作方式有两种:静态显示和动态显示。静态显示的特点是每个数码管的段选必须接一个8位数据线来显示字形,显示字形可一直保持,直到送入新字形码为止。
FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第3张图片

74HC595

FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第4张图片

引脚名 引脚编号 引脚功能
Q0—Q7 15,1—7 并行数据输出
GND 8 电源地
Q7S 9 串行数据输出
10 主复位(低电平有效)
SHCP 11 移位寄存器时钟输入
STCP 12 存储寄存器时钟输入
13 输出使能输入(低电平有效)
DS 14 串行数据输入
VCC 16 电源电压

该芯片有个并行的数据输出,同时芯片的输入是串行数据,也就是说我们使用一个串行输入口就可以并行输出八个输入的串行数据。最先输入的数据会被移位到最后位进行输出。

总结一下74HC595的使用步骤:

  1. 首先把要传输的数据通过引脚DS输入到74HC595中。
  2. 产生SHCP时钟,将DS上的数据串行移入移位寄存器。
  3. 产生STCP时钟,将移位寄存器里的数据送入存储寄存器。
  4. 将引脚置为低电平,存储寄存器的数据会在Q0—Q7并行输出,同时并行输出的数据会被锁存起来。

实验框图、波形图与代码原理

控制六位数码管实现000000、111111到FFFFFF每隔0.5s循环显示。
FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第5张图片

模块名称 功能描述
seg_static 静态数码管驱动模块
hc595_ctrl 74HC595控制模块
seg_595_static 数码管静态显示顶层模块

接下来各个模块分别讨论
FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第6张图片

cnt计数器每0.5s技术到最大值,同时产生cnt_flag标志信号用于控制数码管字符的跳转。sel:数码管的位选信号。我们是显示六个数码管,直接给其全点亮即可。seg:数码管的段选信号,给其相应段码点亮显示num里的值即可。

该模块的参考代码

module  seg_static
#(
    parameter   CNT_MAX=25'd24_999_999

)
(
    input   wire    sys_clk     ,
    input   wire    sys_rst_n   ,
                                
    output  reg     [5:0]   sel ,
    output  reg     [7:0]   seg 
    
);
reg     [24:0]  cnt;
reg     [3:0]   data;
reg             cnt_flag;

always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=25'd0;
    else    if(cnt==CNT_MAX)
                cnt<=25'd0;
            else    
                cnt<=cnt+25'd1;
                
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n==1'b0)   
        cnt_flag<=1'b0;
    else    if(cnt==CNT_MAX-25'd1)
                cnt_flag<=1'b1;
            else
                cnt_flag<=1'b0;
                
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n==1'b0)   
        data<=4'd0;
    else    if((data==4'd15)&&(cnt_flag==1'b1))
                data<=4'd0;
            else    if(cnt_flag==1'b1)
                    data<=data+4'd1;
                    else    
                    data<=data;

always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n==1'b0)  
        sel<=6'b000_000;
    else    sel<=6'b111_111;
    
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n==1'b0) 
        seg<=8'hc0;
    else    case(data)
            4'd0:seg<=8'hc0;
            4'd1:seg<=8'hf9;
            4'd2:seg<=8'ha4;
            4'd3:seg<=8'hb0;
            4'd4:seg<=8'h99;
            4'd5:seg<=8'h92;
            4'd6:seg<=8'h82;
            4'd7:seg<=8'hf8;
            4'd8:seg<=8'h80;
            4'd9:seg<=8'h90;
            4'd10:seg<=8'h88;
            4'd11:seg<=8'h83;
            4'd12:seg<=8'hc6;
            4'd13:seg<=8'ha1;
            4'd14:seg<=8'h86;
            4'd15:seg<=8'h8e;
            default:seg<=8'hff;
            endcase
endmodule

FPGA学习日志——74hc595驱动的数码管静态显示seg_595_static_第7张图片

sys_clk 1bit Input 系统时钟,频率50MHz
sys_rst_n 1bit Input 复位信号,低有效
sel 6bit Input 数码管位选信号
seg 8bit Input 数码管段选信号
stcp 1bit Output 存储寄存器时钟
shcp 1bit Output 移位寄存器时钟
ds 1bit Output 串行数据
oe 1bit Output 输出使能,低有效

本实验我们使用系统时钟(50MHz)四分频得到的shcp时钟(12.5MHz)去进行驱动,而stcp时钟是在我们串行输入14位数 码管之后拉高的,其频率远远小于shcp,所以这里我们只要确定shcp的频率即可,至于oe信号我们一直让其拉低即可。

该部分代码

module  hc595_ctrl
(
    input   wire    sys_clk     ,
    input   wire    sys_rst_n   ,
    input   wire    [5:0]   sel ,
    input   wire    [7:0]   seg ,
    
    output  reg     ds          ,
    output  reg     shcp        ,
    output  reg     stcp        ,
    output  wire     oe          
);
wire    [13:0]     data ;
reg     [1:0]      cnt  ;
reg     [3:0]      cnt_bit;
 
assign  data={seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel[5],sel[4],sel[3],sel[2],sel[1],sel[0]};

always@(posedge sys_clk or negedge  sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=2'd0;
    else    if(cnt==2'd3)
            cnt<=2'd0;
            else
            cnt<=cnt+2'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt_bit<=4'b0;
    else    if((cnt_bit==4'd13)&&(cnt==2'd3))
            cnt_bit<=4'b0;
            else    if(cnt==2'd3)
                    cnt_bit<=cnt_bit+4'd1;
                    else
                    cnt_bit<=cnt_bit;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
    ds<=1'b0;
    else    if(cnt==2'd0)
            ds<=data[cnt_bit];
            else
            ds<=ds;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
    shcp<=1'b0;
    else    if(cnt==2'd2)
            shcp<=1'd1;
            else   if(cnt==2'd0) 
                    shcp<=1'd0;
                    else    
                    shcp<=shcp;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
    stcp<=1'd0;
    else    if((cnt_bit==4'd0)&&(cnt==2'd0))
            stcp<=1'd1;
            else    if((cnt_bit==4'd0)&&(cnt==2'd2))
                    stcp<=1'd0;
                    else
                    stcp<=stcp;
                    
            
assign oe=1'b0;
            

endmodule

顶层模块代码

module  seg_595_static
(
    input   wire    sys_clk     ,
    input   wire    sys_rst_n   ,
    
    output  wire    ds          ,
    output  wire    shcp        ,
    output  wire    stcp        ,
    output  wire    oe          

);

wire    [5:0]   sel ;
wire    [7:0]   seg ;

seg_static
#(
    .CNT_MAX(25'd24_999_999)

)
seg_static_inst
(
   .sys_clk    (sys_clk   ),
   .sys_rst_n  (sys_rst_n ),
                
   .sel        (sel       ),
   .seg        (seg       )
    
);

hc595_ctrl  hc595_ctrl_inst
(
    .sys_clk     (sys_clk     ),
    .sys_rst_n   (sys_rst_n   ),
    .sel         (sel         ),
    .seg         (seg         ),

    .ds          (ds          ),
    .shcp        (shcp        ),
    .stcp        (stcp        ),
    . oe         ( oe         ) 
);
endmodule

仿真代码

`timescale  1ns/1ns
module  tb_seg_595_static();

reg     sys_clk     ;
reg     sys_rst_n   ;

wire    ds          ;
wire    shcp        ;
wire    stcp        ;
wire     oe         ;


initial 
    begin   
        sys_clk=1'b0    ;
        sys_rst_n<=1'b0  ;
        #20
        sys_rst_n<=1'b1  ;
  
    end
always #10 sys_clk=~sys_clk;

seg_595_static  seg_595_static_inst
(
    .sys_clk    (sys_clk  ),
    .sys_rst_n  (sys_rst_n),
   
    .ds         (ds       ),
    .shcp       (shcp     ),
    .stcp       (stcp     ),
    .oe         (oe       )

);
endmodule

你可能感兴趣的:(FPGA学习日志,fpga开发,学习)