0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于FPGA的SPI協(xié)議實(shí)現(xiàn)

FPGA設(shè)計(jì)論壇 ? 來源:FPGA設(shè)計(jì)論壇 ? 作者:FPGA設(shè)計(jì)論壇 ? 2022-03-14 14:07 ? 次閱讀

一、SPI協(xié)議

1、SPI協(xié)議概括

SPI(Serial Peripheral Interface)——串行外圍設(shè)備接口。是Motorola首先在其MC68HCXX系列處理器上定義的。SPI接口主要應(yīng)用在EEPROM、FLASH、實(shí)時(shí)時(shí)鐘,AD轉(zhuǎn)換器以及數(shù)字信號(hào)處理器和數(shù)字信號(hào)解碼器之間。SPI是一種高速,全雙工,同步的通信總線,在芯片上只占用四根線(CS、MOSI、MISO、SCK),極大的節(jié)約了芯片的引腳。

2、SPI物理層

SPI的通信原理很簡(jiǎn)單,它以主從方式工作,這種模式通常有一個(gè)主設(shè)備和一個(gè)或者多個(gè)從設(shè)備。圖1是一個(gè)主設(shè)備一個(gè)從設(shè)備的物理連接示意圖。圖中SCK是由主設(shè)備發(fā)送給從的時(shí)鐘,該時(shí)鐘決定了主設(shè)備發(fā)送數(shù)據(jù)的速率;MOSI是主設(shè)備發(fā)送給從設(shè)備的數(shù)據(jù);MISO是從設(shè)備發(fā)送給主設(shè)備的數(shù)據(jù);CS是片選信號(hào),即只有片選信號(hào)為預(yù)先規(guī)定的使能信號(hào)時(shí)(高電平或者低電平)對(duì)此芯片的操作才有效。

927212b0-a22a-11ec-952b-dac502259ad0.png

圖1 點(diǎn)對(duì)點(diǎn)通信

927dfddc-a22a-11ec-952b-dac502259ad0.png

圖2 一主多從通信

3、SPI協(xié)議層

SPI通信是四線串行通信,也就是說數(shù)據(jù)是一位一位傳輸?shù)摹_@也即是SCK存在的意義,SCK提供通信所需的時(shí)鐘脈沖,MOSI和MISO則基于此時(shí)鐘進(jìn)行數(shù)據(jù)傳輸。數(shù)據(jù)輸出通過MOSI線,數(shù)據(jù)在時(shí)鐘的上升沿或下降沿時(shí)改變,在緊接著的下降沿或者上升沿被讀取。完成一位數(shù)據(jù)傳輸,輸入也使用同樣原理。這樣,至少在8次時(shí)鐘信號(hào)的改變(上升沿和下降沿為一次),就可以實(shí)現(xiàn)8位數(shù)據(jù)的傳輸。

需要注意的是,SCK信號(hào)線只由主設(shè)備控制,從設(shè)備不能控制信號(hào)線。同樣,在一個(gè)基于SPI的設(shè)備中,至少要有一個(gè)主控設(shè)備。這樣傳輸?shù)奶攸c(diǎn):此傳輸方式有一個(gè)優(yōu)點(diǎn),與普通串行通信不同,普通的串行通信一次連續(xù)傳送至少8位數(shù)據(jù),而SPI允許數(shù)據(jù)一位一位的傳送,甚至允許暫停,因?yàn)镾CK時(shí)鐘線由主控設(shè)備控制,當(dāng)沒有時(shí)鐘跳變時(shí),從設(shè)備不采集或傳送數(shù)據(jù)。也就是說,主設(shè)備通過對(duì)SCK時(shí)鐘線的控制可以完成對(duì)通信的控制。SPI協(xié)議還可以實(shí)現(xiàn)數(shù)據(jù)的交換:因?yàn)镾PI的數(shù)據(jù)輸入和輸出線獨(dú)立所以允許同時(shí)完成數(shù)據(jù)的輸入和輸出。不同的SPI設(shè)備的實(shí)現(xiàn)方式不盡相同,主要時(shí)改變和采集數(shù)據(jù)的時(shí)間不同,在時(shí)鐘信號(hào)上升沿或下降沿采集有不同的定義。

SPI總線有四種工作方式(SPI0、SPI1、SPI2、SPI3),其中使用的最為廣泛的是SPI0和SPI3方式。

SPI模塊為了和外設(shè)進(jìn)行數(shù)據(jù)交換,根據(jù)外設(shè)工作要求,其輸出串行同步時(shí)鐘極性和相位可以進(jìn)行配置,時(shí)鐘極性(CPOL)對(duì)傳輸協(xié)議沒有重大的影響。如果CPOL=0,串行同步時(shí)鐘的空閑狀態(tài)為低電平;如果CPOL=1,串行同步時(shí)鐘的空閑狀態(tài)為高電平。時(shí)鐘相位(CPHA)能夠配置用于選擇兩種不同的傳輸協(xié)議之一進(jìn)行數(shù)據(jù)傳輸。如果CPHA=0,在串行同步時(shí)鐘的第一個(gè)跳變沿(上升沿或下降沿)數(shù)據(jù)被采集;如果CPHA=1,在串行同步時(shí)鐘的第二個(gè)跳變沿(上升沿或下降沿)數(shù)據(jù)被采集。SPI主模塊和與之通信的外設(shè)時(shí)鐘相位和極性應(yīng)該一致。

SPI時(shí)序圖詳解:SPI接口有四種不同的數(shù)據(jù)傳輸時(shí)序,取決于CPOL和CPHA的組合。圖3中給出了這四種時(shí)序,時(shí)序與CPOL和CPHA的關(guān)系也可以從圖中看出。

92974ba2-a22a-11ec-952b-dac502259ad0.png

圖3 SPI四種時(shí)序

圖3中可以看出,CPOL是用來決定SCK時(shí)鐘信號(hào)空閑時(shí)的電平。CPOL=0,SCK空閑時(shí)為低電平;CPOL=1,SCK空閑時(shí)為高電平。CPHA是用來決定采樣輸入數(shù)據(jù)MISO時(shí)刻,CPHA = 0,在第一個(gè)SCK時(shí)鐘沿進(jìn)行數(shù)據(jù)采樣;CPHA=1,在第二個(gè)SCK時(shí)鐘沿進(jìn)行數(shù)據(jù)采集。(工作模式的確定:由SLAVE的工作模式確定MASTER的工作模式)。

二、SPI協(xié)議使用舉例

這里通過使用SPI3來實(shí)現(xiàn)主機(jī)發(fā)送數(shù)據(jù)。

92b499aa-a22a-11ec-952b-dac502259ad0.png

圖4 SPI3 工作模式的主機(jī)發(fā)送數(shù)據(jù)

在SPI3模式下,CPOL = 1,CPHA = 1。SCK在空閑時(shí)為高電平,在SCK的第二個(gè)時(shí)鐘沿從機(jī)進(jìn)行數(shù)據(jù)的采集(只考慮主機(jī)發(fā)送情況),在SCK的第一個(gè)時(shí)鐘沿發(fā)送數(shù)據(jù)MOSI。

三、使用verilog實(shí)現(xiàn)SPI3工作模式的時(shí)序

1、SPI3模式下工作過程如下圖所示,

92cc8d8a-a22a-11ec-952b-dac502259ad0.png

圖5 SPI發(fā)送數(shù)據(jù)過程

接下來分析圖5所示SPI發(fā)送數(shù)據(jù)的過程,首先在復(fù)位信號(hào)到來時(shí),進(jìn)入s0狀態(tài),在s0狀態(tài)計(jì)數(shù)器和分頻器模塊加載初始值,如果發(fā)送數(shù)據(jù)開始信號(hào)spi_start有效進(jìn)入s1狀態(tài),s1狀態(tài)加載待發(fā)送的數(shù)據(jù),同時(shí)計(jì)數(shù)器計(jì)數(shù)計(jì)數(shù),分頻器開始工作,如果i=1,進(jìn)入s2狀態(tài),s2狀態(tài)主要用來發(fā)送數(shù)據(jù),如果i為偶數(shù),進(jìn)入s3狀態(tài),該狀態(tài)是用來采集數(shù)據(jù),由于只考慮發(fā)送,因此此模塊不進(jìn)行數(shù)據(jù)采集工作,如果i=15,進(jìn)入s4狀態(tài),否則如果i為奇數(shù),則進(jìn)入s2狀態(tài)。;在s4狀態(tài),發(fā)送最后一位數(shù)據(jù),如果i=16,進(jìn)入s5狀態(tài),此時(shí)整個(gè)SPI時(shí)序模擬完成。

2、數(shù)據(jù)路徑

由圖5可知,構(gòu)成SPI發(fā)送時(shí)序的基本電路塊包括計(jì)數(shù)器,移位寄存器和觸發(fā)器模塊。

92df65f4-a22a-11ec-952b-dac502259ad0.png

圖6 數(shù)據(jù)路徑

圖6中,左移寄存器將8位的待發(fā)送的數(shù)據(jù)spi_data轉(zhuǎn)換為串行的數(shù)據(jù)mosi一位一位的發(fā)送出去,計(jì)數(shù)器用來計(jì)數(shù)發(fā)送數(shù)據(jù)的個(gè)數(shù),觸發(fā)器用來產(chǎn)生分頻后的sck時(shí)鐘信號(hào)。

3、控制信號(hào)

92f25ec0-a22a-11ec-952b-dac502259ad0.png

圖7 控制信號(hào)

圖7中給出了各個(gè)狀態(tài)哪些控制信號(hào)應(yīng)該有效,參照?qǐng)D5圖6圖7可以理清spi整個(gè)發(fā)送數(shù)據(jù)的過程。

四、 verilog描述

接下來使用verilog來描述圖6所示的電路,控制信號(hào)可根據(jù)圖7進(jìn)行描述。

spi發(fā)送模塊(該模塊主要描述控制信號(hào)):

module SPI_SEND(input clk_50m,

input rst_n,

input spi_start,

input[7:0] spi_data,

output reg spi_done,

output sck,

output reg cs,

output mosi

);

reg load_c;

reg en_c;

reg load_a;

reg en_a;

reg load_b;

reg en_b;

wire [4:0]i;

parameter [4:0] s0 = 'b000001;

parameter [4:0] s1 = 'b000010;

parameter [4:0] s2 = 'b000100;

parameter [4:0] s3 = 'b001000;

parameter [4:0] s4 = 'b010000;

parameter [4:0] s5 = 'b100000;

reg [5:0]current_state = 'd0;

reg [5:0]next_state = 'd0;

always @(posedge clk_50m or negedge rst_n)

if(!rst_n)

current_state <= s0;

else

current_state <= next_state;

always @(*)

case(current_state)

s0:begin

if(spi_start)

next_state = s1;

else

next_state = s0;

end

s1:begin/該狀態(tài)加載待發(fā)送的數(shù)據(jù)

if(i == 'd1)

next_state = s2;

else

next_state = s1;

end

s2:begin1,3,5,7,9,11,13,15

if(i[0] == 1'b0)//

next_state = s3;

else

next_state = s2;

end

s3:begin2,4,6,8,10,12,14,16

if(i == 'd15)

next_state = s4;

else if(i[0] == 'd1)

next_state = s2;

else

next_state = s3;

end

s4:begin

if(i == 'd16)

next_state = s5;

else

next_state = s4;

end

s5:begin

if(i == 'd0)

next_state = s0;

else

next_state = s5;

end

default:next_state = s0;

endcase

always @(*)

case(current_state)

s0:begin///空閑狀態(tài)

load_c = 'd1;

en_c = 'd0;

load_a = 'd0;

en_a = 'd0;

load_b = 'd1;

en_b = 'd0;

spi_done = 'd0;

cs = 'd1;

end

s1:begin加載待發(fā)送數(shù)據(jù)狀態(tài)

load_c = 'd0;

en_c = 'd1;

load_a = 'd1;

en_a = 'd0;

load_b = 'd0;

en_b = 'd1;

spi_done = 'd0;

cs = 'd0;

end

s2:begin第一個(gè)時(shí)鐘沿發(fā)送數(shù)據(jù)

load_c = 'd0;

en_c = 'd1;

load_a = 'd0;

en_a = 'd1;

load_b = 'd0;

en_b = 'd1;

spi_done = 'd0;

cs = 'd0;

end

s3:begin第二個(gè)時(shí)鐘沿采樣數(shù)據(jù)

load_c = 'd0;

en_c = 'd1;

load_a = 'd0;

en_a = 'd0;

load_b = 'd0;

en_b = 'd1;

spi_done = 'd0;

cs = 'd0;

end

s4:begin數(shù)據(jù)發(fā)送完畢

load_c = 'd0;

en_c = 'd1;

load_a = 'd0;

en_a = 'd0;

load_b = 'd0;

en_b = 'd0;

spi_done = 'd0;

cs = 'd0;

end

s5:begin

load_c = 'd0;

en_c = 'd0;

load_a = 'd0;

en_a = 'd0;

load_b = 'd0;

en_b = 'd0;

spi_done = 'd1;

cs = 'd1;

end

default:begin

load_c = 'd1;

en_c = 'd0;

load_a = 'd0;

en_a = 'd0;

load_b = 'd1;

en_b = 'd0;

spi_done = 'd0;

cs = 'd1;

end

endcase

// Instantiate the module

count_num count_num (

.clk_50m(clk_50m),

.load_c(load_c),

.en_c(en_c),

.count(i)

);

// Instantiate the module

left_shifter left_shifter (

.clk_50m(clk_50m),

.load_a(load_a),

.en_a(en_a),

.spi_data_in(spi_data),

.mosi(mosi)

);

// Instantiate the module

sck_generate sck_generate (

.clk_50m(clk_50m),

.load_b(load_b),

.en_b(en_b),

.sck(sck)

);

endmodule

計(jì)數(shù)器電路描述:

module count_num(input clk_50m,

input load_c,

input en_c,

output reg[4:0]count

);

always @(posedge clk_50m)

if(load_c)

count <= 'd0;?

else if(en_c)begin

if(count == 'd16)

count <= 'd0;

else

count <= count + 'd1;

end

else

count <= count;

endmodule

移位寄存器電路描述:

module left_shifter(input clk_50m,

input load_a,

input en_a,

input [7:0]spi_data_in,

output mosi

);

reg [7:0]data_reg;

always @(posedge clk_50m)

if(load_a)

data_reg <= spi_data_in;

else if(en_a)

data_reg <= {data_reg[6:0],1'b0};

else

data_reg <= data_reg;

assign mosi = data_reg[7];

endmodule

觸發(fā)器電路描述:

//SPI3模式下工作,SCK空閑時(shí)為高電平

//

module sck_generate(input clk_50m,

input load_b,

input en_b,

output reg sck

);

always @(posedge clk_50m)

if(load_b)

sck <= 'd1;

else if(en_b)

sck <= ~sck;

else

sck <= 'd1;

endmodule

仿真激勵(lì)文件:

module test;

// Inputs

reg clk_50m;

reg rst_n;

reg spi_start;

reg [7:0]spi_data;

// Outputs

wire spi_done;

wire sck;

wire cs;

wire mosi;

// Instantiate the Unit Under Test (UUT)

SPI_SEND uut (

.clk_50m(clk_50m),

.rst_n(rst_n),

.spi_start(spi_start),

.spi_done(spi_done),

.sck(sck),

.cs(cs),

.spi_data(spi_data),

.mosi(mosi)

);

initial begin

// Initialize Inputs

clk_50m = 0;

rst_n = 0;

spi_start = 0;

spi_data = 'd0;

// Wait 100 ns for global reset to finish

#100;

// Add stimulus here

end

always #5 clk_50m = ~clk_50m;

reg [4:0] count = 'd0;

always @(posedge clk_50m)

if(count == 'd20)

count <= 'd20;

else

count <= count + 'd1;

always @(posedge clk_50m)

if(count <= 'd10)

rst_n <= 'd0;

else

rst_n <= 'd1;

reg [9:0]cnt = 'd0;

always @(posedge clk_50m)

if(spi_done)

cnt <= 'd0;

else if(cnt == 'd500)

cnt <= 'd500;

else

cnt <= cnt + 'd1;

always @(posedge clk_50m)

if(cnt=='d499)begin

spi_start <= 'd1;

spi_data <= 'b10101010;

end

elsebegin

spi_start <= 'd0;

spi_data <= spi_data;

end

endmodule

使用ISIM仿真結(jié)果:

9305d31a-a22a-11ec-952b-dac502259ad0.png

圖8 仿真結(jié)果

圖8中待發(fā)送的數(shù)據(jù)spi_data[7:0]=10101010,由于使用的是SPI3模式(CPOL=1,CPHA=1),此模式下SCK空閑時(shí)為1,在SCK第一個(gè)時(shí)鐘沿進(jìn)行數(shù)據(jù)發(fā)送(即圖中SCK下降沿進(jìn)行數(shù)據(jù)發(fā)送),從圖中波形可以看出 ,在cs為低時(shí),mosi被一位一位的送出(高位先輸出)。

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1625

    文章

    21624

    瀏覽量

    601245
  • SPI
    SPI
    +關(guān)注

    關(guān)注

    17

    文章

    1688

    瀏覽量

    91215

原文標(biāo)題:FPGA學(xué)習(xí)-基于FPGA的SPI協(xié)議實(shí)現(xiàn)

文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    fpgaspi通信協(xié)議

    fpga通過spi通信協(xié)議在與外圍設(shè)備實(shí)現(xiàn)通信的過程中程序代碼該怎么寫?新手勿噴
    發(fā)表于 04-09 12:44

    DSP和FPGASPI通信不能實(shí)現(xiàn)怎么辦

    用的貴公司的TL138F-EVM A2開發(fā)板。想利用SPI協(xié)議實(shí)現(xiàn)FPGA和DSP通信??戳撕诵陌逡_說明 沒有看到FPGA這邊
    發(fā)表于 04-24 06:46

    基于FPGA來介紹并設(shè)計(jì)標(biāo)準(zhǔn)的SPI總線協(xié)議

    不懂的有疑惑的也可以加微信咨詢,歡迎大家前來投稿,謝謝!引言介紹在電子通信領(lǐng)域里采用的通信協(xié)議有IIC,SPI,UART,F(xiàn)SMC等協(xié)議。本文將基于FPGA來介紹并設(shè)計(jì)標(biāo)準(zhǔn)的
    發(fā)表于 11-10 09:37

    SPI協(xié)議的相關(guān)資料分享

    FPGA作為從機(jī)與STM32進(jìn)行SPI協(xié)議通信---Verilog實(shí)現(xiàn) [轉(zhuǎn)]一.SPI協(xié)議簡(jiǎn)要
    發(fā)表于 01-18 10:01

    SPI協(xié)議是怎么實(shí)現(xiàn)

    、硬件的 SPI四、模擬的 SPI五、對(duì) W25Q64的實(shí)際應(yīng)用一、SPI協(xié)議實(shí)現(xiàn) SPI功能
    發(fā)表于 02-17 07:29

    FPGA實(shí)現(xiàn)SPI協(xié)議

    寫在前面SPI協(xié)議系列文章:FPGA實(shí)現(xiàn)SPI協(xié)議(一)----
    發(fā)表于 02-17 06:03

    SPI-4.2接口的FPGA實(shí)現(xiàn)

    去偏移和包重組是在FPGA實(shí)現(xiàn)SPI-4.2接口的核心難點(diǎn),在分析偏移和包重組原理的基礎(chǔ)上,給出基于FPGASPI-4.2接口的設(shè)計(jì)與
    發(fā)表于 04-10 09:43 ?32次下載

    如何在FPGA實(shí)現(xiàn)SPI4.2接口

    偏移和包重組是在FPGA實(shí)現(xiàn)SPI一4.2接口的核心難點(diǎn),在分析偏移和包重組原理的基礎(chǔ)E,給出基于FPGASPI一4.2接口的設(shè)計(jì)與
    發(fā)表于 01-25 14:51 ?13次下載
    如何在<b class='flag-5'>FPGA</b>中<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>SPI</b>4.2接口

    基于FPGA的TCP/IP協(xié)議實(shí)現(xiàn)

    基于FPGA的TCP/IP協(xié)議實(shí)現(xiàn)說明。
    發(fā)表于 04-28 11:19 ?50次下載

    基于FPGA與MCU通信的SPI協(xié)議設(shè)計(jì)

    typora-copy-images-to: typora_picture基于FPGA與MCU通信的SPI協(xié)議設(shè)計(jì)1. SPI總線協(xié)議介紹及
    發(fā)表于 11-05 15:35 ?14次下載
    基于<b class='flag-5'>FPGA</b>與MCU通信的<b class='flag-5'>SPI</b><b class='flag-5'>協(xié)議</b>設(shè)計(jì)

    基于FPGASPI協(xié)議及設(shè)計(jì)實(shí)現(xiàn)

    基于FPGASPI協(xié)議及設(shè)計(jì)實(shí)現(xiàn)博主微信:flm13724054952,不懂的有疑惑的也可以加微信咨詢,歡迎大家前來投稿,謝謝!引言介紹在電子通信領(lǐng)域里采用的通信
    發(fā)表于 11-05 19:05 ?24次下載
    基于<b class='flag-5'>FPGA</b>的<b class='flag-5'>SPI</b><b class='flag-5'>協(xié)議</b>及設(shè)計(jì)<b class='flag-5'>實(shí)現(xiàn)</b>

    FPGA實(shí)現(xiàn)SPI協(xié)議(二)----基于SPI接口的FLASH芯片M25P16的使用

    寫在前面SPI協(xié)議系列文章:FPGA實(shí)現(xiàn)SPI協(xié)議(一)----
    發(fā)表于 12-22 19:25 ?19次下載
    <b class='flag-5'>FPGA</b><b class='flag-5'>實(shí)現(xiàn)</b>的<b class='flag-5'>SPI</b><b class='flag-5'>協(xié)議</b>(二)----基于<b class='flag-5'>SPI</b>接口的FLASH芯片M25P16的使用

    FPGA實(shí)現(xiàn)SPI協(xié)議(一)----SPI驅(qū)動(dòng)

    1、什么是SPI協(xié)議SPI(Serial Peripheral Interface,串行外圍設(shè)備接口)通訊協(xié)議,是 Motorola 公司提出的一種同步串行接口技術(shù),是一種高速、全雙工
    發(fā)表于 12-22 19:29 ?19次下載
    <b class='flag-5'>FPGA</b><b class='flag-5'>實(shí)現(xiàn)</b>的<b class='flag-5'>SPI</b><b class='flag-5'>協(xié)議</b>(一)----<b class='flag-5'>SPI</b>驅(qū)動(dòng)

    一文看懂SPI協(xié)議

    作者:王超首發(fā):電子電路開發(fā)學(xué)習(xí)都有哪些內(nèi)容?SPI協(xié)議簡(jiǎn)介4線還是3線?4種工作模式多種傳輸速率SPI協(xié)議的時(shí)序SPI
    發(fā)表于 01-25 18:35 ?38次下載
    一文看懂<b class='flag-5'>SPI</b><b class='flag-5'>協(xié)議</b>

    FPGA實(shí)現(xiàn)SPI

    FPGA實(shí)現(xiàn)SPI協(xié)議
    發(fā)表于 03-20 10:35 ?0次下載