zoukankan      html  css  js  c++  java
  • Verilog HDL SPI通信——写

    module spi_write(
        input clk,            //system clock:50M
        input rst,        
        output reg cs,        //chip select
        output sck,            //chip clock:50K
        input din,            //DO
        output reg dout,    //DI
        input wflag,        //write enable
        input[7:0] data
    );
    
    //general chip clock:50K
    /*reg temp;
    reg[9:0] count;
    always@(posedge clk or posedge rst)
        if(rst) begin count <= 10'd0; temp <= 1'b0; end
        else
            begin
                count <= count+1'b1;
                if(count == 10'd999) begin temp <= 1'b1; count <= 10'd0; end
                else if(count == 10'd499) temp <= 1'b0;
            end
    assign sck = temp;
    
    `define    high (count == 10'd999)            // 时钟上升沿
    `define    low (count == 10'd499)*/        // 时钟下降沿
    reg temp;
    reg[9:0] count;
    always@(posedge clk or posedge rst)
        if(rst) 
            begin
                count <= 10'd0;
                temp <= 1'b0;
            end
        else if(count >= 10'd500)
            begin
                count <= 10'd0;
                temp <= ~temp;
            end
        else count <= count+1'b1;
    
    assign sck = temp;
        
    //capture posedge and negedge of sck
    reg sck_m;
    wire high;        // 时钟上升沿
    wire low;        // 时钟下降沿
    always@(posedge clk or posedge rst)
        if(rst) sck_m <= 1'b0;
        else sck_m <= sck;
    assign high = ~sck_m & sck;
    assign low = sck_m & ~sck;
    
    
    //load
    reg[7:0] data_medium;
    reg[5:0] wstate;
    always@(negedge clk or posedge rst)
        begin
            if(rst) 
                begin
                    wstate <= 6'b0;
                    cs <= 1'b0;
                    dout <= 1'b0;
                end
            else 
                begin
                    case(wstate)
                        6'd0: begin
                                if(wflag)
                                    begin
                                        data_medium <= data;
                                        wstate <= 6'd1;
                                        cs <= 1'b1;
                                        dout <= 1'b0;
                                    end
                                else
                                    begin
                                        wstate <= 6'd0;
                                        cs <= 1'b0;
                                        dout <= 1'b0;
                                    end
                              end
                        6'd1: begin
                                
                                if(low) begin wstate <= 6'd2; dout <=1'b1; cs <= 1'b1; end        // 先执行写使能命令,高位在前,低位在后
                                else    begin wstate <= 6'd1; end                                //SB=1
                              end
                              
                        6'd2: begin
                                if(low) begin wstate <= 6'd3; dout <=1'b0; cs <= 1'b1; end        //OP1=0
                                else    begin wstate <= 6'd2; end
                              end
                              
                        6'd3: begin
                                if(low) begin wstate <= 6'd4; dout <=1'b0; cs <= 1'b1; end        //OP0=0
                                else    begin wstate <= 6'd3; end
                              end
                              
                        6'd4: begin
                                if(low) begin wstate <= 6'd5; dout <=1'b1; cs <= 1'b1; end        //A6=1
                                else    begin wstate <= 6'd4; end
                              end
                              
                        6'd5: begin
                                if(low) begin wstate <= 6'd6; dout <=1'b1; cs <= 1'b1; end        //A5=1
                                else    begin wstate <= 6'd5; end
                              end
                              
                        6'd6: begin
                                if(low) begin wstate <= 6'd7; dout <=1'b1; cs <= 1'b1; end        //A4=1
                                else    begin wstate <= 6'd6; end
                              end
                              
                        6'd7: begin
                                if(low) begin wstate <= 6'd8; dout <=1'b1; cs <= 1'b1; end        //A3=1
                                else    begin wstate <= 6'd7; end
                              end
                              
                        6'd8: begin
                                if(low) begin wstate <= 6'd9; dout <=1'b1; cs <= 1'b1; end        //A2=1
                                else    begin wstate <= 6'd8; end
                              end
                              
                        6'd9: begin
                                if(low) begin wstate <= 6'd10; dout <=1'b1; cs <= 1'b1; end        //A1=1
                                else    begin wstate <= 6'd9; end
                              end
                              
                        6'd10: begin
                                if(low) begin wstate <= 6'd11; dout <=1'b1; cs <= 1'b1; end        //A0=1
                                else    begin wstate <= 6'd10; end
                              end
                              
                        6'd11: begin
                                if(low) begin wstate <= 6'd12; dout <= 1'b0;cs <= 1'b0; end        // 先停一个周期,将CS 拉低,再进行写操作(Address)
                                else    begin wstate <= 6'd11; end                                
                              end
                              
                        6'd12: begin
                                if(low) begin wstate <= 6'd13; dout <=1'b1; cs <= 1'b1; end        //SB=1
                                else    begin wstate <= 6'd12; end
                              end
                              
                        6'd13: begin
                                if(low) begin wstate <= 6'd14; dout <=1'b0; cs <= 1'b1; end        //OP1=0
                                else    begin wstate <= 6'd13; end
                              end
                              
                        6'd14: begin
                                if(low) begin wstate <= 6'd15; dout <=1'b1; cs <= 1'b1; end        //OP0=1
                                else    begin wstate <= 6'd14; end
                              end
                              
                        6'd15: begin
                                if(low) begin wstate <= 6'd16; dout <=1'b0; cs <= 1'b1; end        //A6=0
                                else    begin wstate <= 6'd15; end
                              end      
                              
                        6'd16: begin
                                if(low) begin wstate <= 6'd17; dout <=1'b0; cs <= 1'b1; end        //A5=0
                                else    begin wstate <= 6'd16; end
                              end
                              
                        6'd17: begin
                                if(low) begin wstate <= 6'd18; dout <=1'b0; cs <= 1'b1; end        //A4=0
                                else    begin wstate <= 6'd17; end
                              end
                              
                        6'd18: begin
                                if(low) begin wstate <= 6'd19; dout <=1'b0; cs <= 1'b1; end        //A3=0
                                else    begin wstate <= 6'd18; end
                              end
                              
                        6'd19: begin
                                if(low) begin wstate <= 6'd20; dout <=1'b1; cs <= 1'b1; end        //A2=1
                                else    begin wstate <= 6'd19; end
                              end
                              
                        6'd20: begin
                                if(low) begin wstate <= 6'd21; dout <=1'b0; cs <= 1'b1; end        //A1=0
                                else    begin wstate <= 6'd20; end
                              end
                              
                        6'd21: begin
                                if(low) begin wstate <= 6'd22; dout <=1'b1; cs <= 1'b1; end        //A0=1
                                else    begin wstate <= 6'd21; end
                              end
                              
                        6'd22: begin
                                if(low) begin wstate <= 6'd23; dout <=data[7]; cs <= 1'b1; end  // 开始写入数据:器件数据在上升沿更新,FPGA要在下降沿写出
                                else    begin wstate <= 6'd22; end                            // D7
                              end
                              
                        6'd23: begin
                                if(low) begin wstate <= 6'd24; dout <=data[6]; cs <= 1'b1; end    //D6
                                else    begin wstate <= 6'd23; end
                              end
                              
                        6'd24: begin
                                if(low) begin wstate <= 6'd25; dout <=data[5]; cs <= 1'b1; end    //D5
                                else    begin wstate <= 6'd24; end
                              end
                              
                        6'd25: begin
                                if(low) begin wstate <= 6'd26; dout <=data[4]; cs <= 1'b1; end    //D4
                                else    begin wstate <= 6'd25; end
                              end
                              
                        6'd26: begin
                                if(low) begin wstate <= 6'd27; dout <=data[3]; cs <= 1'b1; end    //D3
                                else    begin wstate <= 6'd26; end
                              end
                              
                        6'd27: begin
                                if(low) begin wstate <= 6'd28; dout <=data[2]; cs <= 1'b1; end    //D2
                                else    begin wstate <= 6'd27; end
                              end
                              
                        6'd28: begin
                                if(low) begin wstate <= 6'd29; dout <=data[1]; cs <= 1'b1; end    //D1
                                else    begin wstate <= 6'd28; end
                              end
                              
                        6'd29: begin
                                if(low) begin wstate <= 6'd30; dout <=data[0]; cs <= 1'b1; end    //D0
                                else    begin wstate <= 6'd29; end
                              end
                              
                        6'd30: begin                                                                                
                                if(low)    begin wstate <= 6'd31; dout <= 1'b0;cs <= 1'b0; end            // 数据写完,停止一个周期,拉低CS
                                else    begin wstate <= 6'd30; end    
                               end
                               
                        6'd31: begin
                                if(low) begin wstate <= 6'd32; cs <= 1'b1; end    //拉高CS,读DO状态,看其是否忙
                                else    begin wstate <= 6'd31; end
                              end
                              
                        6'd32: begin
                                if(din == 1'b1) begin wstate <= 6'd33; cs <= 1'b0; end    //若忙,停在此状态继续检测    
                                else            begin wstate <= 6'd32; cs <= 1'b1; end
                              end
                              
                        6'd33: begin
                                if(low) begin wstate <= 6'd34; cs <= 1'b0; end    //数据写完,停止一个周期
                                else    begin wstate <= 6'd33; end
                              end
                              
                        6'd34: begin
                                if(low) begin wstate <= 6'd35; dout <= 1'b1; cs <= 1'b1; end    //当写操作完成后,为了保护数据,对器件进行擦/写禁止指令
                                else    begin wstate <= 6'd34; end
                              end
                              
                        6'd34: begin
                                if(low) begin wstate <= 6'd35; dout <= 1'b0; cs <= 1'b1; end    //OP=1
                                else    begin wstate <= 6'd34; end
                              end
                              
                        6'd35: begin
                                if(low) begin wstate <= 6'd36; dout <= 1'b0; cs <= 1'b1; end    //OP=2
                                else    begin wstate <= 6'd35; end
                              end
                              
                        6'd36: begin
                                if(low) begin wstate <= 6'd37; dout <= 1'b0; cs <= 1'b1; end    //A6
                                else    begin wstate <= 6'd36; end
                              end    
                              
                        6'd37: begin
                                if(low) begin wstate <= 6'd38; dout <= 1'b0; cs <= 1'b1; end    //A5
                                else    begin wstate <= 6'd37; end
                              end
                              
                        6'd38: begin
                                if(low) begin wstate <= 6'd39; dout <= 1'b1; cs <= 1'b1; end    //A4
                                else    begin wstate <= 6'd38; end
                              end
                              
                        6'd39: begin
                                if(low) begin wstate <= 6'd40; dout <= 1'b1; cs <= 1'b1; end    //A3
                                else    begin wstate <= 6'd39; end
                              end    
                              
                        6'd40: begin
                                if(low) begin wstate <= 6'd41; dout <= 1'b1; cs <= 1'b1; end    //A2
                                else    begin wstate <= 6'd40; end
                              end    
                              
                        6'd41: begin
                                if(low) begin wstate <= 6'd42; dout <= 1'b1; cs <= 1'b1; end    //A1
                                else    begin wstate <= 6'd41; end
                              end        
                              
                        6'd42: begin
                                if(low) begin wstate <= 6'd43; dout <= 1'b1; cs <= 1'b1; end    //A0
                                else    begin wstate <= 6'd42; end
                              end
                              
                        6'd43: begin
                                if(low) begin wstate <= 6'd44; dout <= 1'b0; end    //over
                                else    begin wstate <= 6'd43; end
                              end
                              
                        6'd44: begin
                                if(low) begin wstate <= 6'd0; cs <= 1'b0; end    //cs  down
                                else    begin wstate <= 6'd44; end
                              end
                    
                    endcase
                        
                end
        end
        
    endmodule
  • 相关阅读:
    Unity3d Platformer Pro 2D游戏开发框架使用教程
    程序员如何学习一门新的编程语言
    走进函数式编程
    1001. Exponentiation高精度运算总结
    Kindle PaperWhite3 越狱和PDF插件的安装
    Unity3d中的PlayerPrefs游戏存档API的扩展
    程序员学习路线和学习书单
    1000. A+B Problem
    Mac端SVN工具CornerStone详解
    Unity3d粒子系统详解
  • 原文地址:https://www.cnblogs.com/Mungbohne/p/4386910.html
Copyright © 2011-2022 走看看