赞
踩
对于 spi 通讯协议,相比较于 IIC ,可以说 spi 快很多,而且 spi 是可以全双工的,具有单独的发送线路和接收线路,我们从它的时序来进行分析吧。
从图中我们可以看到有一个是使能信号 SS ,空闲是高电平,当使能时为低电平,只有拉低时数据才能进行发送和接收。
还有 CLK 时钟信号, spi 就是通过时钟信号的跳变来进行读取数据,时钟信号有两种模式,在 0 模式下,时钟信号空闲为低电平,在 1 模式下,时钟信号空闲为高电平。
因为 spi 是全双工的,所以有两个数据线,分别是 MOSI 和 MISO ,I 和 O 分别代表 input 和 output ,这样就很好记哪个是数据发送,呢个是数据接收了。数据线也有两个模式,在 0 模式下在第一个时钟跳变沿读取数据,第二个时钟跳变沿改变数据,而在 1 模式下是第一个时钟条边沿改变数据,第二个时钟跳变沿读取数据。
通过时钟两种模式和数据发送接收的两种模式就可以组成四种模式,又因为 FPGA 可以作为主机或者从机,所以一共有八种模式,接下来我会详细讲解这四种模式对于 FPGA 的实现。
module spi_tx( //定义spi发送模块。 input Clk, //定义系统时钟信号。 input Reset_n, //定义复位信号。 input [7:0]spi_Data, //定义需要发送数据,由上层模块输入数据。 input spi_En, //定义发送使能信号。 output reg spi_Clk, //定义spi时钟信号。 output reg spi_TXD, //定义spi数据发送信号。 output reg spi_done //定义发送完成使能信号。 ); reg [7:0]cnt_Clk; //定义一个八位计数器,用来对系统时钟分频来控制spi时钟频率。 parameter MAX_CLK = 8'd1; //定义分频大小。 wire clk_done; //定义spi时钟半个周期使能信号。 reg [4:0]cnt_state; //定义一个5位寄存器来记录发送数据状态。 parameter MAX_STATE = 5'd16; //定义最大状态。 always @(posedge Clk or negedge Reset_n) begin //定义系统时钟分频计数器。 if (!Reset_n) //复位清零。 cnt_Clk <= 8'd0; else if (!spi_En) begin //使能有效时,spi时钟才工作,取反是因为低电平有效。 if (MAX_CLK <= cnt_Clk) //计满清零。 cnt_Clk <= 8'd0; else //否则加一。 cnt_Clk <= cnt_Clk + 1'b1; end else //使能无效清零。 cnt_Clk <= 8'd0; end assign clk_done = (cnt_Clk == MAX_CLK); //每计满一次使能一次。 always @(posedge Clk or negedge Reset_n) begin //定义状态变换信号。 if (!Reset_n) //复位清零。 cnt_state <= 5'd0; else if (!spi_En) begin //使能有效状态才可以增加。 if (MAX_STATE <= cnt_state) //计满清零。 cnt_state <= 5'd0; else if (clk_done) //系统时钟分频计数器计满加一。 cnt_state <= cnt_state + 1'b1; else //否则不变。。 cnt_state <= cnt_state; end else //使能无效清零。 cnt_state <= 5'd0; end always @(posedge Clk or negedge Reset_n) begin //定义数据发送模块。 if (!Reset_n) begin //复位清零,数据位在空闲时为高阻态。 spi_Clk <= 1'b0; spi_TXD <= 1'bz; end else if (!spi_En) begin //使能有效。 case (cnt_state) //更据状态来赋值。 0: begin spi_Clk <= 1'b0; spi_TXD <= spi_Data[0]; end //初始状态令时钟低电平,将数据最低位0位发送到数据信号上。 1: spi_Clk <= 1'b1; //时钟上升沿读取数据,下同。 2: begin spi_Clk <= 1'b0; spi_TXD <= spi_Data[1]; end //时钟下降沿将改变数据,下同。 3: spi_Clk <= 1'b1; 4: begin spi_Clk <= 1'b0; spi_TXD <= spi_Data[2]; end 5: spi_Clk <= 1'b1; 6: begin spi_Clk <= 1'b0; spi_TXD <= spi_Data[3]; end 7: spi_Clk <= 1'b1; 8: begin spi_Clk <=
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。