新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > SPI總線的verilog實現

SPI總線的verilog實現

作者: 時間:2016-12-14 來源:網絡 收藏
SPI一共4個線:

*)SCK 串行時鐘線:時鐘信號

本文引用地址:http://butianyuan.cn/article/201612/329837.htm

*)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;//發(fā)送數據命令

input spidi;//SPI數據輸入信號

input [7:0] datain;//待發(fā)送數據~輸入

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))//發(fā)送數據轉換

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://發(fā)送數據狀態(tài)

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];//發(fā)送數據最高位

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://接受數據狀態(tài)

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 //對應上面的發(fā)送數據情形
end //對應上面的RST沒有按下的情形
end //對應最上面的always@(posedge clk)
endmodule



關鍵詞: SPI總線verilo

評論


技術專區(qū)

關閉