概述
SPI = Serial Peripheral Interface,是串行外圍設(shè)備接口,是一種高速,全雙工,同步的通信總線。
優(yōu)點(diǎn)
支持全雙工
支持高速
協(xié)議支持字長(zhǎng)不限于8bit,可以根據(jù)應(yīng)用靈活選擇消息字長(zhǎng)。
硬件連接簡(jiǎn)單
缺點(diǎn)
相比I2C多兩條線
沒有尋址機(jī)制,只能靠片選選擇不同的設(shè)備
沒有回應(yīng)ACK機(jī)制,主設(shè)備不知道消息發(fā)送是否成功
典型應(yīng)用僅支持單主控
硬件結(jié)構(gòu)
信號(hào)定義
SCK
:Serial Clock,時(shí)鐘信號(hào),由主設(shè)備產(chǎn)生。
MOSI
:Master Output,Slave Input 主發(fā)從收信號(hào)。在片選信號(hào)有效時(shí),數(shù)據(jù)由高位到低位,在時(shí)鐘的上升沿依次發(fā)送給從設(shè)備。
MISO
:Master Input,Slave Output 主收從發(fā)信號(hào),在片選信號(hào)有效時(shí),數(shù)據(jù)由高位到低位,在時(shí)鐘的上升沿依次發(fā)送給主設(shè)備。
SS/CS
:Slave Select 片選信號(hào),低有效,由主設(shè)備控制。即只有片選信號(hào)為預(yù)先規(guī)定的使能信號(hào)時(shí),對(duì)應(yīng)的芯片操作才有效,這使得在同一總線上連接多個(gè)SPI設(shè)備成為可能。
電路連接
單個(gè)主設(shè)備和單個(gè)從設(shè)備:
單個(gè)主設(shè)備和多個(gè)從設(shè)備,通過用多個(gè)片選信號(hào)或者菊花鏈的形式完成。
傳輸模式
通過設(shè)置相關(guān)控制寄存器,SPI可以有四種傳輸模式。
1、時(shí)鐘空閑時(shí)的電平為高或低。
2、數(shù)據(jù)采樣發(fā)生在時(shí)鐘(SCK)的上/下邊沿。
將以上兩種情況兩兩組合,即可得四種傳輸模式。
數(shù)據(jù)在時(shí)鐘上升沿或下降沿時(shí)改變,在緊接著的下降沿或上升沿被讀取,完成一位數(shù)據(jù)傳輸,輸入與輸出原理相近。這樣通過至少8次時(shí)鐘信號(hào)的改變(上升沿和下降沿為一次),就可以完成8位數(shù)據(jù)的傳輸。如下圖所示。
標(biāo)準(zhǔn)SPI讀
片選→讀指令→地址→數(shù)據(jù)讀出
標(biāo)準(zhǔn)SPI寫
片選→寫指令→地址→數(shù)據(jù)寫入
Verilog代碼解析
本文以SPI Master控制器為例來(lái)對(duì)Verilog源碼進(jìn)行分析,參考資料為《VERILOG HDL應(yīng)用程序設(shè)計(jì)實(shí)例精講》。
1、時(shí)鐘分頻模塊,將原始時(shí)鐘進(jìn)行四分頻,過程較為簡(jiǎn)單,不再詳述。
module clkdiv(clk,clkout); input clk; output clkout; reg [1:0]cnt=2'd0; reg clkout=1'b0; always @(posedge clk)begin if(cnt==2'd1)begin clkout<=1'b1; cnt<=cnt+2'd1; end else if(cnt == 2'd3)begin clkout<=1'b0; cnt<=2'd0; end else begin cnt<=cnt+2'd1; end end endmodule
2、SPI發(fā)送數(shù)據(jù)部分,在spiclk的上升沿完成數(shù)據(jù)的傳輸。spics為片選信號(hào),低有效;spido為輸出的數(shù)據(jù);dstate為FSM變量。dsend為待傳送數(shù)據(jù),其中部分?jǐn)?shù)據(jù)過程重復(fù),代碼中僅保留首尾數(shù)據(jù)的傳輸過程。
begin case (dstate) 8'd0: begin spics <= 1'b0; spiclk <= 1'b1; spido <= 1'b1; dstate <= 8'd1; end 8'd1: begin spics <= 1'b0; spiclk <= 1'b1; spido <= 1'b1; dstate <= 8'd2; end 8'd2: begin spics <= 1'b0; spiclk <= 1'b0; spido <= 1'b1; dstate <= 8'd3; end 8'd3: begin spics <= 1'b0; spiclk <= 1'b1; spido <= dsend[7]; dstate <= 8'd4; end 8'd4: begin spics <= 1'b0; spiclk <= 1'b0; spido <= dsend[7]; dstate <= 8'd5; end …… 8'd17: begin spics <= 1'b0; spiclk <= 1'b1; spido <= dsend[0]; dstate <= 8'd18; end 8'd18: begin spics <= 1'b0; spiclk <= 1'b0; spido <= dsend[0]; dstate <= 8'd19; end 8'd19: begin spics <= 1'b0; spiclk <= 1'b1; spido <= 1'b1; dstate <= 8'd20; end 8'd20: begin spics <= 1'b0; spiclk <= 1'b1; spido <= 1'b1; dstate <= 8'd0; spistate <= idle; end endcase end default: begin spics <= 1'b1; spiclk <= 1'b1; spido <= 1'b1; spistate <= 2'b00; end endcase end
可以看到當(dāng)片選信號(hào)spics為低有效時(shí),數(shù)據(jù)在spiclk的上升沿按順序被發(fā)送至SPI總線上,數(shù)據(jù)信號(hào)spido與輸入數(shù)據(jù)相對(duì)應(yīng),SPI Master發(fā)送時(shí)序得到驗(yàn)證。
3、SPI接收數(shù)據(jù)部分,參數(shù)定義與2一樣,其中部分?jǐn)?shù)據(jù)過程重復(fù),代碼中僅保留首尾數(shù)據(jù)的傳輸過程。在時(shí)鐘的下降沿進(jìn)行數(shù)據(jù)的接收。
begin case (dstate) 8'd0: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd1; end 8'd1: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd2; end 8'd2: begin spics <= 1'b0; spiclk <= 1'b0; dstate <= 8'd3; end 8'd3: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd4; end 8'd4: begin spics <= 1'b0; spiclk <= 1'b0; dreceive[7] <= spidi; dstate <= 8'd5; end 8'd5: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd6; end …… 8'd18: begin spics <= 1'b0; spiclk <= 1'b0; dreceive[0] <= spidi; dstate <= 8'd19; end 8'd19: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd20; dataout <= dreceive; end 8'd20: begin spics <= 1'b0; spiclk <= 1'b1; dstate <= 8'd0; spistate <= 2'b00; end endcase end
由上圖分析看出,收到的數(shù)據(jù)與SPI傳輸?shù)臄?shù)據(jù)相對(duì)應(yīng),SPI接收數(shù)據(jù)部分得到正確驗(yàn)證。
實(shí)驗(yàn)項(xiàng)目框圖:
實(shí)驗(yàn)心得:
1、在給復(fù)位信號(hào)低電平時(shí)時(shí)間過短,分頻后時(shí)鐘上升沿還未到復(fù)位信號(hào)就拉高了,導(dǎo)致未進(jìn)行有效復(fù)位。
2、進(jìn)行發(fā)送/接收狀態(tài)檢測(cè)時(shí)設(shè)置的計(jì)數(shù)子過大,如下圖,每過40個(gè)時(shí)鐘周期進(jìn)行一次檢測(cè),當(dāng)仿真時(shí)間過短時(shí),容易看不到結(jié)果。
if(cnt == 8'd40) begin cnt <= 8'd0; if((wr == 1'b0) && (rd == 1'b1)) begin spistate <= send_data; dstate <= 8'd0; dsend <= datain; end else if((wr == 1'b1) && (rd == 1'b0)) begin spistate <= receive_data; dstate <= 8'd0; end end else begin cnt <= cnt + 8'd1; end
3、若結(jié)果出現(xiàn)問題,將相關(guān)控制信號(hào)添加至窗口,觀察其狀態(tài),分析程序存在的問題。
-
Verilog
+關(guān)注
關(guān)注
29文章
1366瀏覽量
111909 -
SPI
+關(guān)注
關(guān)注
17文章
1785瀏覽量
94879 -
通信總線
+關(guān)注
關(guān)注
0文章
46瀏覽量
9989
原文標(biāo)題:SPI詳解及Verilog源碼分析
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
SPI總線的原理與Verilog設(shè)計(jì)實(shí)現(xiàn)

SPI總線概述
怎么使用FPGA實(shí)現(xiàn)SPI總線的通信接口?
STM32通信接口之硬件SPI概述
介紹一下SPI通信總線構(gòu)成與通信特點(diǎn)
用SPI總線實(shí)現(xiàn)DSP和MCU之間的高速通信
FPGA實(shí)現(xiàn)CAN總線通信節(jié)點(diǎn)設(shè)計(jì)

使用Verilog實(shí)現(xiàn)SPI串行總線接口的資料和源代碼免費(fèi)下載

SPI總線驅(qū)動(dòng)的C語(yǔ)言源代碼詳細(xì)概述
基于SPI串行總線接口的Verilog實(shí)現(xiàn)

通信協(xié)議:SPI

評(píng)論