基于 FPGA 的三线制数码管显示(动态)

开发环境:硬件 小梅哥的AC620 fpga EP4CE10F17C8N
EDA开发软件 Quartus II 13.0

由于静态显示每一个数码管均需要独立的数据线,因此硬件电路比较复杂,成本较高,很少使用 。常用选亮数码管采用动态扫描显示,所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
基于 FPGA 的三线制数码管显示(动态)_第1张图片
以驱动8位8段为例,如果直接用fpga管脚直接去驱动数码管至少也得要16 个 IO 进行驱动, 显然很浪费管脚资源。74HC595在单片机系统中常用的芯片之一他的作用就是把串行的信号转为并行的信号,常用在各种数码管以及点阵屏的驱动芯片, 使用74HC595可以节约单片机mcu的io口资源,用3个io就可以控制8个数码管的引脚,他还具有一定的驱动能力,可以免掉三极管等放大电路,所以这块芯片是驱动数码管的神器.应用非常广泛。由于一片 74HC595 只能实现 8 位数据的串并转换,因此使用 2 片 74HC595 芯片级联实现。一片用作位选,另一片用作段选。
基于 FPGA 的三线制数码管显示(动态)_第2张图片
基于 FPGA 的三线制数码管显示(动态)_第3张图片

三线驱动电路

只需三个管脚即可实现驱动。电路设计分为两个部分:数码管驱动模块和74hc595驱动模块。
基于 FPGA 的三线制数码管显示(动态)_第4张图片

数码管驱动模块

基于 FPGA 的三线制数码管显示(动态)_第5张图片
基于 FPGA 的三线制数码管显示(动态)_第6张图片
每位数码管能显示0~F16个字符,所以每个数码管数据为4位,总共就是32位分为8组由八选一多路器输入,将fpga50M主频时钟分频产生1K的扫描时钟,让位选由0000_0001 -> 0000_0010 -> 0000_0100 -> … ->1000_0000 -> 0000_0001, 8路多路器依次对应选择输出数据给译码器译码后输出段选数据,就可以实现第一个数码管显示(其他7个熄灭)…实现第八个数码管显示(其他7个熄灭),第一个数码管显示(其他7个熄灭)循环显示,由于循环的频率很快,人眼看上去就是八个数码管同时显示八个字符数字。

74hc595驱动模块

基于 FPGA 的三线制数码管显示(动态)_第7张图片在这里插入图片描述
SHCP: 移位寄存器的时钟输入,当接收到上升沿时移位寄存器内部数据整体后移;
STCP: 数据存储寄存器时钟输入,当检测到上升沿时使能数据存储寄存器,将芯片接收到的数据输出到Q0~Q7 ,可以将其理解为锁存信号,当数据发送给芯片完成后对该引脚发送上升沿;
595高速移位时钟频率Fmax>25MHz,二分频后作为sh_cp移位寄存器时钟。注意时钟产生的方法:最好用序列机的方式计数更好;如果另外单独产生一个作为时钟信号的质量并不好,而且此时钟连接多个寄存器,使时钟可能到达每个寄存器的时间都不一样,由于此系统要求并不高,影响不会很大。

整体模块框图

基于 FPGA 的三线制数码管显示(动态)_第8张图片

调试过程

一个简单的状态机也可以实现74HC595 模块接口时序设计:前十六个时钟脉冲将8位段选数据8位位选数据送入移位寄存器,第十七个脉冲时钟给st_cp一个上升沿,芯片接收到的数据输出

always@(posedge SH_CP or negedge rst_n)
在这里插入图片描述
但是发现刚好每个上升沿才发送数据,采集数据不准确,改为下降沿后刚好在上升沿数据已经稳定了:
always@(negedge SH_CP or negedge rst_n)

在这里插入图片描述
状态机代码


 always@(negedge SH_CP or negedge rst_n)
 if(!rst_n)begin
  DS <= 0;
  ST_CP <= 0;
  state <= 5'd0;
 end
 else if(en)
 begin
  case(state)
   5'd0:begin ST_CP <= 0;    state <= 5'd1 ;end
   5'd1:begin DS <= Data[15];state <= 5'd2 ;end
   5'd2:begin DS <= Data[14];state <= 5'd3 ;end
   5'd3:begin DS <= Data[13];state <= 5'd4 ;end
   5'd4:begin DS <= Data[12];state <= 5'd5 ;end
   5'd5:begin DS <= Data[11];state <= 5'd6 ;end
   5'd6:begin DS <= Data[10];state <= 5'd7 ;end
   5'd7:begin DS <= Data[9] ;state <= 5'd8 ;end
   5'd8:begin DS <= Data[8] ;state <= 5'd9 ;end
   5'd9:begin DS <= Data[7] ;state <= 5'd10;end
    5'd10:begin DS <= Data[6] ;state <= 5'd11;end
    5'd11:begin DS <= Data[5] ;state <= 5'd12;end
    5'd12:begin DS <= Data[4] ;state <= 5'd13;end
    5'd13:begin DS <= Data[3] ;state <= 5'd14;end
    5'd14:begin DS <= Data[2] ;state <= 5'd15;end
    5'd15:begin DS <= Data[1] ;state <= 5'd16;end
    5'd16:begin DS <= Data[0] ;state <= 5'd17;end
    5'd17:begin ST_CP <= 1;    state <= 5'd0 ;end
    endcase
 end 

新建一个verligo hdl文件,在顶层连接两个模块,注意每个模块设计好后都要用进行仿真验证。
综合没有错误后我们可以查看rtl视图以及状态图

rtl视图及状态图

基于 FPGA 的三线制数码管显示(动态)_第9张图片
基于 FPGA 的三线制数码管显示(动态)_第10张图片
为了更便捷地进行板级调试,使用Qusrtus 自带的的 In system sources andprobes editor(ISSP)调试工具,测试数码管可以用其提供的源。

调试演示戳我

源码下载

你可能感兴趣的:(FPGA)