设为首页收藏本站淘宝杂货铺

从F到0 - From F to 0

 找回密码
 注册已关闭
搜索
查看: 1040|回复: 4
收起左侧

Quartus Verilog HDL/FPGA 驱动两片级联74HC595与8位动态扫描数码管 演示16进制的累加

[复制链接]
发表于 2022-2-2 08:33:23 | 显示全部楼层 |阅读模式
main.png
  1. module main(
  2.         input clk,
  3.         output reg SHCP,
  4.         output reg STCP,
  5.         output reg DS
  6. );

  7. parameter fosc = 50000000;                                //晶振频率
  8. parameter hc595_num = 2;                                //595级联数量
  9. parameter hc595_clkhz = 1000000;                //595移位频率 1Mhz
  10. parameter hc595_bit = hc595_num * 8;//595级联数*8 (位数)
  11. reg [hc595_bit-1:0] hc595_dat;                //修改该寄存器的值 会实时发送到595
  12. reg [hc595_bit-1:0] hc595_ram;                //595数据缓存容器 防止数据错乱
  13. reg [31:0] hc595_i = 0;                                        //595分频用
  14. reg [31:0] hc595_bpc = 0;                                //595位指针

  15. always @(posedge clk) begin                        //74HC595驱动
  16.         hc595_i = hc595_i + 1;
  17.         if(hc595_i >= fosc/hc595_clkhz/2) begin
  18.                 hc595_i = 0;
  19.                 SHCP = !SHCP;
  20.                 if(SHCP) begin
  21.                         if(hc595_bpc == 0) begin
  22.                                 hc595_ram = hc595_dat;
  23.                         end
  24.                         DS = hc595_ram[hc595_bit-hc595_bpc-1];
  25.                         STCP = (hc595_bpc != hc595_bit-1);
  26.                         hc595_bpc = hc595_bpc + 1;
  27.                         if(hc595_bpc >= hc595_bit) begin
  28.                                 hc595_bpc = 0;
  29.                         end
  30.                 end
  31.         end
  32. end

  33. function [7:0] display;                        //16进制数码管段码查询
  34.         input [3:0] hex;
  35.         begin
  36.         case(hex)
  37.                 4'h0:display = 8'h3F;
  38.                 4'h1:display = 8'h06;
  39.                 4'h2:display = 8'h5B;
  40.                 4'h3:display = 8'h4F;
  41.                 4'h4:display = 8'h66;
  42.                 4'h5:display = 8'h6D;
  43.                 4'h6:display = 8'h7D;
  44.                 4'h7:display = 8'h07;
  45.                 4'h8:display = 8'h7F;
  46.                 4'h9:display = 8'h6F;
  47.                 4'hA:display = 8'h77;
  48.                 4'hB:display = 8'h7C;
  49.                 4'hC:display = 8'h39;
  50.                 4'hD:display = 8'h5E;
  51.                 4'hE:display = 8'h79;
  52.                 4'hF:display = 8'h71;        
  53.         endcase
  54.         end
  55. endfunction

  56. parameter seg_hz = 10000;                        //数码管扫描频率 10Khz
  57. reg [31:0] seg_i = 0;
  58. reg [2:0] seg_j = 0;
  59. reg [7:0] seg_k;
  60. reg [31:0] seg_l;
  61. reg [31:0] seg_hex = 0;                                //修改该寄存器的值 会实时显示到数码管

  62. always @(posedge clk) begin                //数码管动态扫描
  63.         seg_i = seg_i + 1;
  64.         if(seg_i >= fosc/seg_hz) begin
  65.                 seg_i = 0;
  66.                         seg_j <= seg_j + 1'b1;
  67.                         if(seg_j == 0) begin
  68.                                 seg_l = seg_hex;
  69.                         end
  70.                         case(seg_j)
  71.                                 0:seg_k=display(seg_l[31:28]);
  72.                                 1:seg_k=display(seg_l[27:24]);
  73.                                 2:seg_k=display(seg_l[23:20]);
  74.                                 3:seg_k=display(seg_l[19:16]);
  75.                                 4:seg_k=display(seg_l[15:12]);
  76.                                 5:seg_k=display(seg_l[11:8]);
  77.                                 6:seg_k=display(seg_l[7:4]);
  78.                                 7:seg_k=display(seg_l[3:0]);        
  79.                                 default:seg_k=0;
  80.                         endcase
  81.                 //共阴或共阳 如果显示不正确 请修改以下两行代码
  82.                 hc595_dat[15:8] = seg_k;                                //位码
  83.                 hc595_dat[7:0] = ~(1'b1 << seg_j);        //段码
  84.         end
  85. end

  86. reg [31:0] tmp_m = 0;
  87. always @(posedge clk) begin                //数码管值 1毫秒+1
  88.         tmp_m = tmp_m + 1'b1;
  89.         if(tmp_m >= fosc/1000) begin
  90.                 tmp_m = 0;
  91.                 seg_hex = seg_hex + 1'b1;
  92.         end
  93. end

  94. endmodule
复制代码

相关帖子

您需要登录后才可以回帖 登录 | 注册已关闭

本版积分规则

QQ|手机版|Archiver|从F到0 ( 蒙ICP备17002595号-1 )
蒙公网安备15010402000325号

腾讯云安全认证

GMT+8, 2024-4-27 07:20 , Processed in 1.203069 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表