小梅哥Xilinx FPGA学习笔记18—SPI接口的74HC595驱动数码管实验

分析:

对于74HC595芯片,该芯片在位移时钟信号SRCLK的上升沿将串行输入数据SER(DIO)移入内部的寄存器。因此我们需要保证DIO上的数据在SRCLK上升沿前后一段时间内保持稳定

因此,FPGA要在SRCLK的下降沿改变DIO的值,在上升沿取到的就一定是稳定的值

数据锁存器时钟信号RCLK只需要在16位数据都移入之后给一个高电平,锁存即可

3.3V驱动,取SRCLK最大频率为12.5MHz,周期80ns

先移入的数据在高位输出

因此,应当先传第二片的seg,再传第一片的sel

顺序为seg7-0,sel7-0

设计文件:
`timescale 1ns / 1ps

module HC595_Driver(
    Clk,
    Reset_n,
    SEG,
    SEL,
    DIO,
    RCLK,
    SRCLK
    );
   input Clk;
   input Reset_n;
   input [7:0]SEL;
   input [7:0]SEG;
   output reg DIO;
   output reg RCLK;
   output reg SRCLK; 
   
   parameter CLOCK_FREQ = 50_000_000;
   parameter SRCLK_FREQ = 12_500_000; 
   parameter MCNT = CLOCK_FREQ/(SRCLK_FREQ * 2 ) - 1; //用SRCLK的半个周期进行分析,有助于找到对应的高/低电平,上升沿下降沿
   
    reg[29:0]div_cnt;
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
       div_cnt <= 0;
    else if(div_cnt == MCNT)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'd1; 
                    
    reg[4:0]cnt; //传输16位数据,32个高低电平,2的5次方,需要5位
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        cnt <= 0;
    else if(div_cnt == MCNT)
        cnt <= cnt +1'd1;    //每一个上升沿/下降沿都对应一个cnt值,用case语句使得不同时刻做不同的任务
        
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)begin
     DIO <= 1'd0;
     SRCLK <= 1'd0; 
     RCLK <= 1'd0;
     
    end
    else begin
        case(cnt)
            0:begin DIO <= SEG[7]; SRCLK <= 1 'd0; RCLK <= 1'd1; end //每个下降沿都要传输一次数据,总共有16个下降沿,把16个数据都能够移位寄存;每一轮的开始也是上一轮的结束,RCLK高电平锁存
            1:begin                SRCLK <= 1'd1; RCLK <= 1'd0; end
            2:begin DIO <= SEG[6]; SRCLK <= 1'd0; end
            3:begin                SRCLK <= 1'd1; end
            4:begin DIO <= SEG[5]; SRCLK <= 1'd0; end
            5:begin                SRCLK <= 1'd1; end
            6:begin DIO <= SEG[4]; SRCLK <= 1'd0; end
            7:begin                SRCLK <= 1'd1; end
            8:begin DIO <= SEG[3]; SRCLK <= 1'd0; end
            9:begin                SRCLK <= 1'd1; end
           10:begin DIO <= SEG[2]; SRCLK <= 1'd0; end
           11:begin                SRCLK <= 1'd1; end
           12:begin DIO <= SEG[1]; SRCLK <= 1'd0; end
           13:begin                SRCLK <= 1'd1; end 
           14:begin DIO <= SEG[0]; SRCLK <= 1'd0; end
           15:begin                SRCLK <= 1'd1; end
           16:begin DIO <= SEL[7]; SRCLK <= 1'd0; end
           17:begin                SRCLK <= 1'd1; end
           18:begin DIO <= SEL[6]; SRCLK <= 1'd0; end
           19:begin                SRCLK <= 1'd1; end
           20:begin DIO <= SEL[5]; SRCLK <= 1'd0; end
           21:begin                SRCLK <= 1'd1; end
           22:begin DIO <= SEL[4]; SRCLK <= 1'd0; end
           23:begin                SRCLK <= 1'd1; end
           24:begin DIO <= SEL[3]; SRCLK <= 1'd0; end
           25:begin                SRCLK <= 1'd1; end
           26:begin DIO <= SEL[2]; SRCLK <= 1'd0; end
           27:begin                SRCLK <= 1'd1; end
           28:begin DIO <= SEL[1]; SRCLK <= 1'd0; end
           29:begin                SRCLK <= 1'd1; end
           30:begin DIO <= SEL[0]; SRCLK <= 1'd0; end
           31:begin                SRCLK <= 1'd1; end
       endcase
     end    
            
   
endmodule
仿真文件:
`timescale 1ns / 1ps

module HC595_Driver_tb();
    reg Clk;
    reg Reset_n;
    reg [7:0]SEG;
    reg [7:0]SEL;
    wire DIO;
    wire RCLK;
    wire SRCLK;
    
    HC595_Driver HC595_Driver(
        .Clk(Clk),
        .Reset_n(Reset_n),
        .SEG(SEG),
        .SEL(SEL),
        .DIO(DIO),
        .RCLK(RCLK),
        .SRCLK(SRCLK)

    );
     
    initial Clk = 1;
    always#10 Clk = ~Clk;
    
    initial begin
    Reset_n = 0;
    SEL = 8'b0000_0001;
    SEG = 8'b0101_0101;
    #201
    Reset_n = 1;
    #5000;
    SEL = 8'b0000_0010;
    SEG = 8'b1010_1010;
    #5000;
    SEL = 8'b1010_0101;
    SEG = 8'b0000_1101;
    #5000;
    $stop;
    end
 
endmodule
波形图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值