uart_spi练习

首先PC端通过串口给fpga发一个信息,如01,fpga收到01后,将这个值作为rx3701的寄存器地址,读出01寄存器的值,是68f500,将这个值传送给电脑,同样是通过串口

顶层

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/05/16 15:24:54

// Design Name:

// Module Name: top_uart-spi

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

 

 

module top_uart_spi(

    input clk200,

    input rst_n,

    output tx,

    input rd,

        input                   I_spi_miso  , // SPI串行输入,用来接收从机的数据

    output                  O_spi_sck   , // SPI时钟

    output                  O_spi_cs    , // SPI片选信号

    output                  O_spi_mosi    // SPI输出,用来给从机发送数据

);

 

 

    wire[7:0] datain;

    wire[7:0] rddata;

    wire rdstart;

    wire wrsig;

    wire rdstartplus;

uart_serial uart_top

(.clk200(clk200),

.rst_n(rst_n),

.wrsig(wrsig),

.datain(datain),

.tx(tx),

.rd(rd),

.rddata(rddata),

.rdstart(rdstart),

.rdstartplus(rdstartplus)

    );

 

 

spi_read_id_top spi_top

(

    . I_clk(clk200) , // 全局时钟50MHz

    .I_rst_n(rst_n), // 复位信号,低电平有效

    

    .rddata(rddata),

    .rdstart(rdstart),

 

    // 四线标准SPI信号定义

    .I_spi_miso  (I_spi_miso), // SPI串行输入,用来接收从机的数据

    .O_spi_sck   (O_spi_sck), // SPI时钟

    .O_spi_cs    (O_spi_cs), // SPI片选信号

    .O_spi_mosi  (O_spi_mosi), // SPI输出,用来给从机发送数据        

    .R_spi_pout(datain),

    .wrsig(wrsig),

    .rdstartplus(rdstartplus)

);

endmodule

 

 

Uart部分

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/05/15 09:28:40

// Design Name:

// Module Name: uart_serial

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

 

 

module uart_serial(clk200,rst_n,wrsig,datain,tx,rd,rddata,rdstart,rdstartplus

 

    );

    input clk200;

    input wrsig;

    input rst_n;

    input datain;

    output tx;

output rddata;

output rdstart;

input rd;

output rdstartplus;

    reg tx;

    

     

     reg presult;

 reg rdpresult;

 

     reg paritymode;

 reg rdparitymode;

     reg idle;

 reg rdidle;

     reg[7:0] cnt;

 reg[7:0] rdcnt;

      wire[7:0] datain;

      

  reg[7:0] rddata;

  

 wire clk;

wire rdstartplus;

 

 

reg rdstart;

//初始化

initial

begin

 

 

tx <=1'b1;

 

presult <=1'b0;

paritymode <=1'b0;

idle <=1'b0;

 

rdpresult <=1'b0;

rdparitymode <=1'b0;

rdidle <=1'b0;

 

cnt <=8'b0000_0000;

rdcnt <=8'b0000_0000;

 

rddata <=8'b0000_0000;

rdstart <=1'b0;

end

 

clk_div_uart div(.clk200(clk200),.rst_n(rst_n),.clkout(clk));

 

 

 

//----------------------检测发送命令上升沿---------

 

    

    //  启动串口发送程序

 

 

//------------------------------------------------

 

 

 

//  串口发送程序, 16个时钟发送一个bit

always @(posedge clk  or negedge rst_n )

begin

  if (!rst_n) begin

tx <=1'b1;

          

          presult        <=1'b0;

          paritymode    <=1'b0;

          idle        <=1'b0;

 

  end       

  else if (wrsig)  begin

case(cnt)                 //产生起始位

8'd0: begin

 tx <= 1'b0;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd16: begin

 tx <= datain[0];    //发送数据0位

 presult <= datain[0]^paritymode;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd32: begin

 tx <= datain[1];    //发送数据1位

 presult <= datain[1]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd48: begin

 tx <= datain[2];    //发送数据2位

 presult <= datain[2]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd64: begin

 tx <= datain[3];    //发送数据3位

 presult <= datain[3]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd80: begin

 tx <= datain[4];    //发送数据4位

 presult <= datain[4]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd96: begin

 tx <= datain[5];    //发送数据5位

 presult <= datain[5]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd112: begin

 tx <= datain[6];    //发送数据6位

 presult <= datain[6]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd128: begin

 tx <= datain[7];    //发送数据7位

 presult <= datain[7]^presult;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd144: begin

 tx <= presult;      //发送奇偶校验位

 presult <= datain[0]^paritymode;

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd160: begin

 tx <= 1'b1;         //发送停止位            

 idle <= 1'b1;

 cnt <= cnt + 8'd1;

end

8'd176: begin

 tx <= 1'b1;             

 idle <= 1'b0;       //一帧数据发送结束

end

default: begin

 cnt <= cnt + 8'd1;

end

   endcase

end

  else  begin

tx <= 1'b1;

cnt <= 8'd0;

idle <= 1'b0;

  end

 

end

 

always @(posedge clk)

    begin

             if(rd==1'b0)

               begin

                   rdstart<=1'b1;

                end          

              else if(rdcnt>185)

                  begin

                  rdstart<=1'b0;

 

                  end

              else

                rdstart<=rdstart;

     end

 

    

 

 

always @(posedge clk  or negedge rst_n )

begin

  if (!rst_n) begin

          

  rdpresult        <=1'b0;

  rdparitymode    <=1'b0;

  rdidle            <=1'b0;

  

 

         end

  else if(rdstart)

              begin

                  case(rdcnt)   //读取              

              8'd0: begin                 

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd16: begin

                   rddata[0]<=rd;    //read数据0位

                   rdpresult <= rddata[0]^rdparitymode;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd32: begin

                   rddata[1]<=rd;    //read数据0位

                   rdpresult <= rddata[1]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd48: begin

                   rddata[2]<=rd;    //read数据0位

                   rdpresult <= rddata[2]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd64: begin

                   rddata[3]<=rd;    //read数据0位

                   rdpresult <= rddata[3]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd80: begin

                   rddata[4]<=rd;    //read数据0位

                   rdpresult <= rddata[4]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd96: begin

                   rddata[5]<=rd;    //read数据0位

                   rdpresult <= rddata[5]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd112: begin

                   rddata[6]<=rd;    //read数据0位

                   rdpresult <= rddata[6]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd128: begin

                   rddata[7]<=rd;    //read数据0位

                   rdpresult <= rddata[7]^rdpresult;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd144: begin

                   //if(rdpresult!=rd)    //发送奇偶校验位    

                  //    rddata<=8'b0000_0000;

                   rdidle <= 1'b1;

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd160: begin

                   //if(rd==1)      //read停止位            

                   rdidle <= 1'b1;    

                   rdcnt <= rdcnt + 8'd1;

              end

              8'd176: begin                       

                   rdidle <= 1'b0;       //一帧数据read结束

                  // rdstart<=1'b0;

                    rdcnt <= rdcnt + 8'd1;

                  //  rdstartplus<=1;

              end

              default: begin

                   rdcnt <= rdcnt + 8'd1;

              end

             endcase

              end

          else

              begin

                      rdcnt <= 8'd0;

                      rdidle <= 1'b0;

                      

//                          if(rd==1'b0)

//                       begin

//                           rdstart<=1'b1;

//                        end          

//                      else

//                          begin

//                          rdstart<=rdstart;

//                          end

              end

 

end

 

assign rdstartplus = (!rdidle)&rdstart;

 

endmodule

 

 

 

Uart分频时钟

时钟分出来大概是9600*16Hz

 

 

module clk_div_uart(clk200,rst_n,clkout);

    input clk200;

    input rst_n;

    reg[15:0] cnt;

    output clkout;

    reg clkout;

 initial

    begin

        cnt <=16'd0;

    end

always @(posedge clk200 or negedge rst_n)   

  if (!rst_n) begin

     clkout <=1'b0;

     cnt<=0;

  end     

  else if(cnt == 16'd508) begin //近似50%占空比

    clkout <= 1'b1;

    cnt <= cnt + 16'd1;

  end

  else if(cnt == 16'd1017) begin //200M/(16*9600)

    clkout <= 1'b0;

    cnt <= 16'd0;

  end

  else  cnt <= cnt + 16'd1;

Endmodule

 

 

 

spi读写部分

 

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/05/08 15:44:16

// Design Name:

// Module Name: spi_read_id_top

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

 

 

module spi_read_id_top

(

    input                   I_clk       , // 全局时钟50MHz

    input                   I_rst_n     , // 复位信号,低电平有效

 

 

    // 四线标准SPI信号定义

    input                   I_spi_miso  , // SPI串行输入,用来接收从机的数据

    output                  O_spi_sck   , // SPI时钟

    output                  O_spi_cs    , // SPI片选信号

    output                  O_spi_mosi,    // SPI输出,用来给从机发送数据

    

    

    input rddata,

    input rdstartplus,

    input rdstart,

    output R_spi_pout,

    output wrsig

);

 

wire W_rx_en ;

wire            W_tx_en     ;

wire   [7:0]    W_data_in   ; // 要发送的数据

wire   [7:0]    W_data_out  ; // 接收到的数据

wire            W_tx_done   ; // 发送最后一个bit标志位,在最后一个bit产生一个时钟的高电平

wire            W_rx_done   ; // 接收一个字节完毕(End of Receive)

wire I_spi_miso;

reg             R_rx_en     ;

reg             R_tx_en     ;

reg   [7:0]     R_data_in   ; // 要发送的数据

reg   [3:0]     R_state     ;

wire    O_clk     ;

reg   [7:0]     R_spi_pout  ;

reg   [7:0]    addr  ;

reg[7:0] cntstate=0;

reg wrsig;

 

wire[6:0] rddata;

 

initial

    begin

       wrsig <=1'b0;

    end

   

assign W_rx_en       = R_rx_en           ;

assign W_tx_en       = R_tx_en           ;

assign W_data_in     = R_data_in         ;

 

 

clock_div_spi clkdiv(.clk(I_clk),.clk_sys(O_clk));

    

initial

    begin

      addr<=8'b0000_0000;

      R_state<=3'd0;

    end

    

    

 

always @(posedge O_clk or negedge I_rst_n )

begin

 

    if(!I_rst_n)

        begin

            R_state <= 3'd0 ;

            R_tx_en <= 1'b0 ;

            R_rx_en <= 1'b0 ;

            addr    <=1'b0;

 

        end

    else

        case(R_state)

            3'd0:

                begin

          

                    if(W_tx_done)  

                        begin

                            R_state <= R_state + 1'b1 ;

                            R_data_in   <= 8'h00      ;

                        end

                    else                              

                        begin              

                          wrsig   <= 1'b0;   

                            R_tx_en     <= 1'b1       ;

                            R_data_in   <= 8'b1000_0000+rddata;//读取0位寄存器的数据

                        end                                  

                end

//              3'd1:

//                    begin

//                        if(W_tx_done)  

//                            begin

//                                R_state <= R_state + 1'b1 ;

//                                R_data_in   <= 8'h00      ;

//                            end

//                        else                              

//                            begin                         

//                                R_tx_en     <= 1'b1       ;

//                                R_data_in   <= 8'b0110_1001;

//                            end                                  

//                    end

//              3'd2:

//                          begin

//                              if(W_tx_done)  

//                                  begin

//                                      R_state <= R_state + 1'b1 ;

//                                      R_data_in   <= 8'h00      ;

//                                  end

//                              else                              

//                                  begin                         

//                                      R_tx_en     <= 1'b1       ;

//                                      R_data_in   <= 8'b0000_0101;

//                                  end                                  

//                          end   

//              3'd3:

//                                begin

//                                    if(W_tx_done)  

//                                        begin

//                                            R_state <= R_state + 1'b1 ;

//                                            R_data_in   <= 8'h00      ;

//                                        end

//                                    else                              

//                                        begin                         

//                                            R_tx_en     <= 1'b1       ;

//                                            R_data_in   <= 8'b0000_0000;

//                                        end                                  

//                                end

          3'd1:  // 接收连续6个字节的数据

              begin

              

                   if(W_rx_done)//先读完在写

                      begin

                            wrsig   <= 1'b1;

                            R_state     <= R_state + 1'b1 ;

                            R_spi_pout  <= W_data_out     ;   

                    end

                 else

                     begin

                            wrsig   <= 1'b0;

                          R_tx_en     <= 1'b0       ;

                          R_rx_en     <= 1'b1       ;

                       end    

                end

      3'd2:  // 接收连续6个字节的数据

                    begin

                    

                         if(W_rx_done)

                            begin

                                  wrsig   <= 1'b0;

                                  R_state     <= R_state + 1'b1 ;

                                  R_spi_pout  <= W_data_out     ;   

                          end

                       else

                           begin

                                  wrsig   <= 1'b1;//开始写,写的是第一个字节,而不是这次读到的字节

                                R_tx_en     <= 1'b0       ;

                                R_rx_en     <= 1'b1       ;

                             end    

                      end     

    3'd3:  // 接收连续6个字节的数据

          begin

          

               if(W_rx_done)

                  begin

                        wrsig   <= 1'b0;

                        R_state     <= R_state + 1'b1 ;

                        R_spi_pout  <= W_data_out     ;   

                end

             else

                 begin

                        wrsig   <= 1'b1;//开始写,写的是第二个字节,而不是这次读到的字节

                      R_tx_en     <= 1'b0       ;

                      R_rx_en     <= 1'b1       ;

                   end    

            end    

          3'd4:  // 接收连续6个字节的数据

                                begin

                                     if(cntstate==32)

                                        begin

                                              wrsig   <= 1'b0;

                                               cntstate<=0;

                                               R_state<=R_state+1;

                                      end

                                   else

                                       begin

                                              wrsig   <= 1'b1;//开始写,写的是第三个字节,通过计数器打拍子,打16拍以上才能保证正常

                                           cntstate<=cntstate+1;

 

                                         end    

                                  end      

            3'd5:  //结束

                begin

                     wrsig   <= 1'b0;

 

                    R_tx_en     <= 1'b0       ;

                    R_rx_en     <= 1'b0       ;   

                    

                    if(rdstartplus==1)

                        begin

                        R_state<=3'd0;

                        end

                     else

                            R_state<=R_state;

                            

                    if(addr>108)

                        begin

                          addr<=0;

                         end

                    else

                            begin              

                             addr    <=addr+1;

                          end

                end                   

        endcase     

end

              

 

 

spi_module U_spi_module

(

    .I_clk       (O_clk), // 全局时钟50MHz

    .I_rst_n     (I_rst_n), // 复位信号,低电平有效

    .I_rx_en     (W_rx_en), // 读使能信号

    .I_tx_en     (W_tx_en), // 发送使能信号

    .I_data_in   (W_data_in), // 要发送的数据

    .O_data_out  (W_data_out), // 接收到的数据

    .O_tx_done   (W_tx_done), // 发送最后一个bit标志位,在最后一个bit产生一个时钟的高电平

    .O_rx_done   (W_rx_done), // 接收一个字节完毕(End of Receive)

    

    // 四线标准SPI信号定义

    .I_spi_miso  (I_spi_miso), // SPI串行输入,用来接收从机的数据

    .O_spi_sck   (O_spi_sck), // SPI时钟

    .O_spi_cs    (O_spi_cs), // SPI片选信号

    .O_spi_mosi  (O_spi_mosi) // SPI输出,用来给从机发送数据          

);

 Debug  //

///

 

endmodule

 

Spi读写串并互转子模块

`timescale 1ns / 1ps

//

// Company:

// Engineer:

//

// Create Date: 2020/05/08 14:00:29

// Design Name:

// Module Name: spi_module

// Project Name:

// Target Devices:

// Tool Versions:

// Description:

//

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//

 

 

 

//SPI模块是处于主机和从机之间协调spi通信的模块

module spi_module(

input I_clk, //系统时钟

input I_rst_n, //复位

input I_tx_en, //发送 使能 主机将这个信号输入至本spi模块,spi模块才开始响应"发送数据给从机"这一命令。当I_tx_en为1时主机才能给从机发送数据

input I_rx_en, //接收 使能

input[7:0] I_data_in, //主机要发送给从机的数据

input I_spi_miso, //SPI接口

 

output O_tx_done, //主机给从机发送数据完成的标志位,发送完成后会产生一个高脉冲;

output O_rx_done, //主机从从机接收数据完成的标志位,接收完成后会产生一个高脉冲;

output O_spi_cs, //SPI接口

output O_spi_mosi, //SPI接口

output O_spi_sck, //SPI接口sck

output[7:0] O_data_out //从机将数据发送至本模块,然后本模块发送给主机

);

 

 

wire I_clk; //系统时钟

wire I_rst_n; //复位

wire I_tx_en; //发送 使能 主机将这个信号输入至本spi模块,spi模块才开始响应"发送数据给从机"这一命令。

wire I_rx_en; //接收 使能

wire[7:0] I_data_in; //主机要发送给从机的数据

wire I_spi_miso; //SPI接口

 

reg O_tx_done; //主机给从机发送数据完成的标志位,发送完成后会产生一个高脉冲;

reg O_rx_done; //主机从从机接收数据完成的标志位,接收完成后会产生一个高脉冲;

reg O_spi_cs; //SPI接口

reg O_spi_mosi; //SPI接口

reg O_spi_sck; //SPI接口sck

reg[7:0] O_data_out; //从机将数据发送至本模块,然后本模块发送给主机

 

reg[3:0] R_tx_state;

reg[3:0] R_rx_state;

reg[7:0] data_buf;

 

always@(posedge I_clk or negedge I_rst_n)

begin

if(!I_rst_n)

begin

O_spi_cs <=1'b1; //复位时,取消选中从机

O_rx_done <=1'b0;

O_tx_done <=1'b0;

R_tx_state <=1'b0; //状态回到初态

R_rx_state <=1'b0;

O_data_out <=8'd0;

 

O_spi_mosi  <=1'b0; //

O_spi_sck <=1'b0; //

end

else if(I_tx_en==1)//发射开启

begin

O_spi_cs <=0; //片选CS拉低,选中从机

case(R_tx_state)

 

4'd1, 4'd3 , 4'd5 , 4'd7  ,

4'd9, 4'd11, 4'd13, 4'd15 : //整合奇数状态

begin

O_spi_sck   <= 1'b1 ;

R_tx_state  <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

end

4'd0:

begin

O_spi_mosi <= I_data_in[7] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

end

4'd2:

begin

O_spi_mosi <= I_data_in[6] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

end

4'd4:

begin

O_spi_mosi <= I_data_in[5] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

end

4'd6:

begin

O_spi_mosi <= I_data_in[4] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

 

end

4'd8:

begin

O_spi_mosi <= I_data_in[3] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

 

end

4'd10:

begin

O_spi_mosi <= I_data_in[2] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

 

end

4'd12:

begin

O_spi_mosi <= I_data_in[1] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

O_tx_done   <= 1'b0 ;

 

end

4'd14:

begin

O_spi_mosi <= I_data_in[0] ;

O_spi_sck <= 1'b0 ;

R_tx_state <= R_tx_state+1'b1 ;

 

O_tx_done   <= 1'b1 ;//这里存在疑问///

end

default:

begin

R_tx_state <= 4'd0 ;

end

 

 

endcase

end

else if(I_rx_en==1)

begin

O_spi_cs <=1'b0;

case(R_rx_state)

4'd0, 4'd2 , 4'd4 , 4'd6  ,

4'd8, 4'd10, 4'd12, 4'd14 : //整合

begin

O_spi_sck   <= 1'b0 ;

R_rx_state  <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd1:

begin

O_data_out[7] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd3:

begin

O_data_out[6] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd5:

begin

O_data_out[5] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd7:

begin

O_data_out[4] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd9:

begin

O_data_out[3] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd11:

begin

O_data_out[2] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd13:

begin

O_data_out[1] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b0 ;

 

end

4'd15:

begin

O_data_out[0] <= I_spi_miso ;

O_spi_sck <= 1'b1 ;

R_rx_state <= R_rx_state+1'b1 ;

O_rx_done   <= 1'b1 ;//上跳变脉冲表示读取完成

 

end

default:

begin

R_rx_state <= 4'd0 ;

end

endcase

end

else

begin

O_spi_cs <=1'b1; //复位时,取消选中从机

O_rx_done <=1'b0;

O_tx_done <=1'b0;

R_tx_state <=1'b0; //状态回到初态

R_rx_state <=1'b0;

O_data_out <=8'd0;

 

O_spi_mosi  <=1'b0; //

O_spi_sck <=1'b0; //

end

end

endmodule

 

Spi时钟

为了契合串口使用,把时钟频率调到了很低

module clock_div_spi(clk,clk_sys);

input clk;

output clk_sys;

 

reg clk_sys=0;

reg[25:0] div_counter=0;//

 

always@(posedge clk)

begin

if(div_counter>6000)//5000_0000)

begin

div_counter<=0;

clk_sys<=~clk_sys;

end

else

begin

div_counter<=div_counter+1;

end

end

endmodule

猜你喜欢

转载自blog.csdn.net/qq_41034231/article/details/106177026