微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > SPI总线的verilog实现

SPI总线的verilog实现

时间:12-14 来源:互联网 点击:
SPI一共4个线:

*)SCK 串行时钟线:时钟信号

*)MISO 主机输入/从机输出线;

*)MOSI 主机输出/从机输入线;

*)CS 片选那个从机进行通信。

无应答机制

一定要搞清楚从设备是上升沿还是下降沿接受数据。

时钟极性:一根线上比如:主的SDO和从的SDI时钟极性相反,也就是如果主SDO是上升沿有效,那么从SDI下降沿有效。

时钟相位为0:第一个跳变沿数据采样,所以时钟前采样,时钟后输出;

时钟相位为1:第二个跳变沿数据采样,所以时钟前输出,时钟后采样。

一般使用0模式。

管脚SS非为判断主从的标志,SS非为低为从,高为主。

IP可划分为:硬IP,软IP,和两者之间的固IP

SPI

module spi_mosi(rst,clk,rd,wr,datain,spics,spiclk,spido,spidi,dataout);

input rst;//置位信号,低有效

input clk;//时钟信号

input rd;//接受数据命令

input wr;//发送数据命令

input spidi;//SPI数据输入信号

input [7:0] datain;//待发送数据~输入

output spics;//SPI片选信号

ouput spiclk;//SPI时钟信号

output spido;//SPI数据输出信号

output [7:0] dataout;//待接受数据~输出

reg spics;

reg spiclk;

reg spido;

reg [7:0] dstate,dsend,dataout,dreceive;

reg [1:0] spistate;

parameter idle = 2b00;

parameter send_data=2b01;

parameter receive_data=2b10;

initial

begin

spics<=1b1;

spiclk<=1b1;

spido<=1b1;

end

always @(posedge clk)

begin

if(!rst)

begin

spistate<=idle;

spics<=1b1;

spiclk<=1b1;

spido<=1b1;

dstate<=8d0;

end

else

begin

case(spistate)

2b00:

begin

if((wr==1b0)&&(rd==1b1))//发送数据转换

begin

spistate<=send_data;

dstate<=8d0;

dsend<=datain;

end

else if((wr==1b1)&&(rd==1b0))//接受数据转换

begin

spistate<=receive_data;

dstate<=8d0;

end

else

begin

spistate<=idle;

dstate<=8d0;

end

end

2b01://发送数据状态

begin

case(state)

8d0://产生片选信号有效

begin

spics<=1b0;

spiclk<=1b1;

spicdo<=1b1;

dstate<=8d1;

8d1:

begin

spics<=1b0;

spiclk<=1b1;

spido<=1b1;

dstate<=8d2;

end

8d2:

begin

spics<=1b0;

spiclk<=1b0;

spido<=1b1;

dstate<=8d3;

end

8d3:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[7];//发送数据最高位

dstate<=8d4;

end

8’d4:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[7];

dstate<=8d5;

end

8d5:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[6];

dstate<=8d6;

end

8d6:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[6];

dstate<=8d7;

end

8d7:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[5];

dstate<=8d8;

end

8d8:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[5];

dstate<=8d9;

end

8d9:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[4];

dstate<=8d10;

end

8d10:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[4];

dstate<=8d11;

end

8d11:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[3];

dstate<=8d12;

end

8d12:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[3];

dstate<=8d13;

end

8d13:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[2];

dstate<=8d14;

end

8d14:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[2];

dstate<=8d15;

end

8d15:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[1];

dstate<=8d7;

end

8d16:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[1];

dstate<=8d17;

end

8d17:

begin

spics<=1b0;

spiclk<=1b0;

spido<=dsend[0];

dstate<=8d18;

end

8d18:

begin

spics<=1b0;

spiclk<=1b1;

spido<=dsend[0];

dstate<=8d19;

end

8d19:

begin

spics<=1b1;

spiclk<=1b1;

spido<=1b1;

dstate<=8d20;

end

8d20:

begin

spics<=1b1;

spiclk<=1b1;

spido<=1b1

dstate<=8d0;

spistate<=idle;

end

default

begin

spics<=1b1;

spiclk<=1b1;

spido<=1b1;

spistate<=idle;

end

endcase

end

2b10://接受数据状态

begin

case(dstate)//片选信号有效

begin
case (dstate) //片选信号有效
8d0:
begin
spics <= 1b0;
spiclk <= 1b1;
spido <= 1b1;
dstate <= 8d1;
end
8d1:
begin
spics <= 1b0;
spiclk <= 1b1;
spido <= 1b1;
dstate <= 8d2;
end
8d2:
begin
spics <= 1b0;
spiclk <= 1b0;
spido <= 1b1;
dstate <= 8d3;
end
8d3:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d4;
end
8d4:
begin
spics <= 1b0;
spiclk <= 1b0; //紧接着上升沿的下降沿数据被读取
dreceive[7] <= spidi; //接收数据最高位
dstate <= 8d5;
end
8d5:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d6;
end
8d6:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[6] <= spidi;
dstate <= 8d7;
end
8d7:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d8;
end
8d8:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[5] <= spidi;
dstate <= 8d9;
end
8d9:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d10;
end
8d10:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[4] <= spidi;
dstate <= 8d11;
end
8d11:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d12;
end
8d12:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[3] <= spidi;
dstate <= 8d13;
end
8d13:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d14;
end
8d14:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[2] <= spidi;
dstate <= 8d15;
end
8d15:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d16;
end
8d16:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[1] <= spidi;
dstate <= 8d17;
end
8d17:
begin
spics <= 1b0;
spiclk <= 1b1;
dstate <= 8d18;
end
8d18:
begin
spics <= 1b0;
spiclk <= 1b0;
dreceive[0] <= spidi; //接收数据最低位
dstate <= 8d19;
end
8d19:
begin
spics <= 1b0;
spiclk <= 1b1;
spido <= 1b1;
dstate <= 8d20;
dataout<= dreceive;
end
8d20:
begin
spics <= 1b1; //片选信号无效
spiclk <= 1b1;
spido <= 1b1;
dstate <= 8d0;
spistate <= idle;
end

endcase
end
default:
begin
spics <= 1b1;
spiclk <= 1b1;
spido <= 1b1;
spistate <= idle;
end
endcase //对应上面的发送数据情形
end //对应上面的RST没有按下的情形
end //对应最上面的always@(posedge clk)
endmodule

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top