Verliog采用SPI协议与单片机沟通

Heather ·
更新时间:2024-11-13
· 926 次阅读

FPGA采用SPI协议与单片机沟通

单片机与FPGA沟通方式有很多种,只要规定好协议后,做到通信是完成没问题的。
首先先将FPGA的SPI实现…SPI协议不做追溯了。
闲话不多说,先付代码、

module SPILED( input clk, input rst_n, input SCK, input CS_N, input MOSI, output reg MISO, output reg [7:0]rxd_data, output rxd_flag, output reg led0, output reg led1, output reg led2, output reg led3 ); //-----------------capture sck side---------// reg sck_r0,sck_r1; wire sck_n,sck_p; reg [7:0]txd_data; initial txd_data[7:0] <= 8'd11; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin sck_r0 <= 1'b1; //sck of the idle state is high sck_r1 <= 1'b1; end else begin sck_r0 <= SCK; sck_r1 <= sck_r0; end end assign sck_n = (~sck_r0 & sck_r1)? 1'b1:1'b0; //capture the sck negedge assign sck_p = (~sck_r1 & sck_r0)? 1'b1:1'b0; //capture the sck posedge

从机如何读数据

//---------------spi_slaver read data---------// reg rxd_flag_r; reg [2:0]rxd_state; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rxd_data <= 1'b0; rxd_flag_r <= 1'b0; rxd_state <= 1'b0; end else if(sck_n&&!CS_N) begin case(rxd_state) 3'd0:begin rxd_data[7]<=MOSI; rxd_flag_r <= 1'b0; rxd_state <= 3'd1; end 3'd1:begin rxd_data[6]<=MOSI; rxd_state <= 3'd2; end 3'd2:begin rxd_data[5]<=MOSI; rxd_state <= 3'd3; end 3'd3:begin rxd_data[4]<=MOSI; rxd_state <= 3'd4; end 3'd4:begin rxd_data[3]<=MOSI; rxd_state <= 3'd5; end 3'd5:begin rxd_data[2]<=MOSI; rxd_state <= 3'd6; end 3'd6:begin rxd_data[1]<=MOSI; rxd_state <= 3'd7; end 3'd7:begin rxd_data[0]<=MOSI; rxd_flag_r <= 1'b1; rxd_state <= 3'd0; end default: ; endcase end end

中间穿插用灯指示一下。

always@(posedge clk ) begin led0 <= rxd_data[0]; led1 <= rxd_data[1]; led2 <= rxd_data[2]; led3 <= rxd_data[3]; end

从机发送数据

//--------------------capture spi_flag posedge-------------------------------- reg rxd_flag_r0,rxd_flag_r1; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rxd_flag_r0 <= 1'b0; rxd_flag_r1 <= 1'b0; end else begin rxd_flag_r0 <= rxd_flag_r; rxd_flag_r1 <= rxd_flag_r0; end end assign rxd_flag = (~rxd_flag_r1 & rxd_flag_r0)? 1'b1:1'b0; //capture rxd_flag_r posedge //---------------------spi_slaver send data--------------------------- reg [2:0] txd_state; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin txd_state <= 1'b0; end else if(sck_p && !CS_N) begin case(txd_state) 3'd0:begin MISO <= txd_data[7]; txd_state <= 3'd1; end 3'd1:begin MISO <= txd_data[6]; txd_state <= 3'd2; end 3'd2:begin MISO <= txd_data[5]; txd_state <= 3'd3; end 3'd3:begin MISO <= txd_data[4]; txd_state <= 3'd4; end 3'd4:begin MISO <= txd_data[3]; txd_state <= 3'd5; end 3'd5:begin MISO <= txd_data[2]; txd_state <= 3'd6; end 3'd6:begin MISO <= txd_data[1]; txd_state <= 3'd7; end 3'd7:begin MISO <= txd_data[0]; txd_state <= 3'd0; end default: ; endcase end end endmodule

以上都是FPGA端的,当时写的单片机的软件SPI,注意时序边沿对应。当然软件SPI通信效率很低,但是谁让单片机硬件SPI总出错呢。
需要软件SPI的,请私信吧,这里不写了。


作者:没脑子的人



spi 沟通 单片机

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章