在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

常用串行總線(二)——SPI協議(Verilog實現)

HJ18656750788 ? 來源:Cascatrix ? 2023-01-06 14:35 ? 次閱讀

01SPI基礎知識

SPI(Serial Perripheral Interface, 串行外圍設備接口)是 Motorola 公司推出的一種同步串行接口技術。SPI 總線在物理上是通過接在外圍設備微控制器(PICmicro) 上面的微處理控制單元 (MCU) 上叫作同步串行端口(Synchronous Serial Port) 的模塊(Module)來實現的, 它允許 MCU 以全雙工的同步串行方式, 與各種外圍設備進行高速數據通信

SPI 主要應用在 EEPROM, Flash, 實時時鐘(RTC), 數模轉換器(ADC), 數字信號處理器(DSP) 以及數字信號解碼器之間。它在芯片中只占用四根管腳 (Pin) 用來控制以及數據傳輸, 節約了芯片的 pin 數目, 同時為 PCB 在布局上節省了空間。正是出于這種簡單易用的特性, 現在越來越多的芯片上都集成了 SPI技術。

00bb8b24-8d8b-11ed-bfe3-dac502259ad0.png

SPI主要具有以下特點:

1.1 采用主-從模式(Master-Slave) 的控制方式SPI

規定了兩個 SPI 設備之間通信必須由主設備 (Master) 來控制次設備 (Slave). 一個 Master 設備可以通過提供 Clock 以及對 Slave 設備進行片選 (Slave Select) 來控制多個 Slave 設備, SPI 協議還規定 Slave 設備的 Clock 由 Master 設備通過 SCK 管腳提供給 Slave 設備, Slave 設備本身不能產生或控制 Clock, 沒有 Clock 則 Slave 設備不能正常工作.

1.2 采用同步方式(Synchronous)傳輸數據

采用同步方式(Synchronous)傳輸數據Master 設備會根據將要交換的數據來產生相應的時鐘脈沖(Clock Pulse), 時鐘脈沖組成了時鐘信號(Clock Signal) , 時鐘信號通過時鐘極性 (CPOL) 和 時鐘相位 (CPHA) 控制著兩個 SPI 設備間何時數據交換以及何時對接收到的數據進行采樣, 來保證數據在兩個設備之間是同步傳輸的.

1.3 數據交換(Data Exchanges)

SPI 設備間的數據傳輸之所以又被稱為數據交換, 是因為 SPI 協議規定一個 SPI 設備不能在數據通信過程中僅僅只充當一個 "發送者(Transmitter)" 或者 "接收者(Receiver)". 在每個 Clock 周期內, SPI 設備都會發送并接收一個 bit 大小的數據, 相當于該設備有一個 bit 大小的數據被交換了.一個 Slave 設備要想能夠接收到 Master 發過來的控制信號, 必須在此之前能夠被 Master 設備進行訪問 (Access). 所以, Master 設備必須首先通過 SS/CS pin 對 Slave 設備進行片選, 把想要訪問的 Slave 設備選上.

在數據傳輸的過程中, 每次接收到的數據必須在下一次數據傳輸之前被采樣. 如果之前接收到的數據沒有被讀取, 那么這些已經接收完成的數據將有可能會被丟棄, 導致 SPI 物理模塊最終失效. 因此, 在程序中一般都會在 SPI 傳輸完數據后, 去讀取 SPI 設備里的數據, 即使這些數據(Dummy Data)在我們的程序里是無用的.

00d044ba-8d8b-11ed-bfe3-dac502259ad0.png

02SPI傳輸協議

2.1 SPI協議層相關組件和接口

00ebe1f2-8d8b-11ed-bfe3-dac502259ad0.png

時鐘相關概念:

CPOL(clock polarity): 時鐘極性, 表示 SPI 在空閑時, 時鐘信號是高電平還是低電平. 若 CPOL 被設為 1, 那么該設備在空閑時 SCK 管腳下的時鐘信號為高電平. 當 CPOL 被設為 0 時則正好相反;

CPHA(clock phase): 時鐘相位, 表示 SPI 設備是在 SCK 管腳上的時鐘信號變為上升沿時觸發數據采樣, 還是在時鐘信號變為下降沿時觸發數據采樣. 若 CPHA 被設置為 1, 則 SPI 設備在時鐘信號變為下降沿時觸發數據采樣, 在上升沿時發送數據. 當 CPHA 被設為 0 時也正好相反.

0105c6bc-8d8b-11ed-bfe3-dac502259ad0.png

SSPBUF(Synchronous Serial Port Buffer): 泛指 SPI 設備里面的內部緩沖區, 一般在物理上是以 FIFO 的形式, 保存傳輸過程中的臨時數據;

SSPSR(Synchronous Serial Port Register):泛指 SPI 設備里面的移位寄存器(Shift Regitser), 它的作用是根據設置好的數據位寬(bit-width) 把數據移入或者移出 SSPBUF;

Controller:泛指 SPI 設備里面的控制寄存器, 可以通過配置它們來設置 SPI 總線的傳輸模式.

通常情況下, 我們只需要對上圖所描述的四個管腳(pin) 進行控制即可實現整個 SPI 設備之間的數據通信:

SCK(Serial Clock):主要的作用是 Master 設備往 Slave 設備傳輸時鐘信號, 控制數據交換的時機以及速率;

SS/CS(Slave Select/Chip Select):用于 Master 設備片選 Slave 設備, 使被選中的 Slave 設備能夠被 Master 設備所訪問;

SDO/MOSI(Serial Data Output/Master Out Slave In):在 Master 上面也被稱為 Tx-Channel, 作為數據的出口, 主要用于 SPI 設備發送數據;

SDI/MISO(Serial Data Input/Master In Slave Out):在 Master 上面也被稱為 Rx-Channel, 作為數據的入口, 主要用于SPI 設備接收數據。

2.2 SPI協議層傳輸規則

01216ef8-8d8b-11ed-bfe3-dac502259ad0.png

當SPI進行數據傳輸時,片選信號cs_n置低,數據位按照SPI同步時鐘發送。主設備發給從設備的數據沿mosi數據線發送,從設備同步發給主設備的數據沿miso數據線發送,主從設備接收的數據依次分別存入主從設備內的FIFO中。

2.3 說明

1. Timing

首先, 在這里解釋一下兩個概念:

CPOL: 時鐘極性, 表示 SPI 在空閑時, 時鐘信號是高電平還是低電平. 若 CPOL 被設為 1, 那么該設備在空閑時 SCK 管腳下的時鐘信號為高電平. 當 CPOL 被設為 0 時則正好相反.

CPHA: 時鐘相位, 表示 SPI 設備是在 SCK 管腳上的時鐘信號變為上升沿時觸發數據采樣, 還是在時鐘信號變為下降沿時觸發數據采樣. 若 CPHA 被設置為 1, 則 SPI 設備在時鐘信號變為下降沿時觸發數據采樣, 在上升沿時發送數據. 當 CPHA 被設為 0 時也正好相反.

例如,SPI 數據傳輸模式被設置成 CPOL = 1, CPHA = 1. 這樣, 在一個 Clock 周期內, 每個單獨的 SPI 設備都能以全雙工(Full-Duplex) 的方式, 同時發送和接收 1 bit 數據, 即相當于交換了 1 bit 大小的數據. 如果 SPI 總線的 Channel-Width 被設置成 Byte, 表示 SPI 總線上每次數據傳輸的最小單位為 Byte, 那么掛載在該 SPI 總線的設備每次數據傳輸的過程至少需要 8 個 Clock 周期(忽略設備的物理延遲). 因此, SPI 總線的頻率越快, Clock 周期越短, 則 SPI 設備間數據交換的速率就越快.

2. SSPSR

SSPSR 是 SPI 設備內部的移位寄存器(Shift Register). 它的主要作用是根據 SPI 時鐘信號狀態, 往 SSPBUF 里移入或者移出數據, 每次移動的數據大小由 Bus-Width 以及 Channel-Width 所決定.

Bus-Width 的作用是指定地址總線到 Master 設備之間數據傳輸的單位.

例如, 我們想要往 Master 設備里面的 SSPBUF 寫入 16 Byte 大小的數據: 首先, 給 Master 設備的配置寄存器設置 Bus-Width 為 Byte; 然后往 Master 設備的 Tx-Data 移位寄存器在地址總線的入口寫入數據, 每次寫入 1 Byte 大小的數據(使用 writeb 函數); 寫完 1 Byte 數據之后, Master 設備里面的 Tx-Data 移位寄存器會自動把從地址總線傳來的1 Byte 數據移入 SSPBUF 里; 上述動作一共需要重復執行 16 次.

Channel-Width 的作用是指定 Master 設備與 Slave 設備之間數據傳輸的單位. 與 Bus-Width 相似, Master 設備內部的移位寄存器會依據 Channel-Width 自動地把數據從 Master-SSPBUF 里通過 Master-SDO 管腳搬運到 Slave 設備里的 Slave-SDI 引腳, Slave-SSPSR 再把每次接收的數據移入 Slave-SSPBUF里.

通常情況下, Bus-Width 總是會大于或等于 Channel-Width, 這樣能保證不會出現因 Master 與 Slave 之間數據交換的頻率比地址總線與 Master 之間的數據交換頻率要快, 導致 SSPBUF 里面存放的數據為無效數據這樣的情況.

3. SSPBUF

我們知道, 在每個時鐘周期內, Master 與 Slave 之間交換的數據其實都是 SPI 內部移位寄存器從 SSPBUF 里面拷貝的. 我們可以通過往 SSPBUF 對應的寄存器 (Tx-Data / Rx-Data register) 里讀寫數據, 間接地操控 SPI 設備內部的 SSPBUF.

例如, 在發送數據之前, 我們應該先往 Master 的 Tx-Data 寄存器寫入將要發送出去的數據, 這些數據會被 Master-SSPSR 移位寄存器根據 Bus-Width 自動移入 Master-SSPBUF 里, 然后這些數據又會被 Master-SSPSR 根據 Channel-Width 從 Master-SSPBUF 中移出, 通過 Master-SDO 管腳傳給 Slave-SDI 管腳, Slave-SSPSR 則把從 Slave-SDI 接收到的數據移入 Slave-SSPBUF 里. 與此同時, Slave-SSPBUF 里面的數據根據每次接收數據的大小(Channel-Width), 通過 Slave-SDO 發往 Master-SDI, Master-SSPSR 再把從 Master-SDI 接收的數據移入 Master-SSPBUF.在單次數據傳輸完成之后, 用戶程序可以通過從 Master 設備的 Rx-Data 寄存器讀取 Master 設備數據交換得到的數據.

4. Controller

Master 設備里面的 Controller 主要通過時鐘信號(Clock Signal)以及片選信號(Slave Select Signal)來控制 Slave 設備. Slave 設備會一直等待, 直到接收到 Master 設備發過來的片選信號, 然后根據時鐘信號來工作.

Master 設備的片選操作必須由程序所實現. 例如: 由程序把 SS/CS 管腳的時鐘信號拉低電平, 完成 SPI 設備數據通信的前期工作; 當程序想讓 SPI 設備結束數據通信時, 再把 SS/CS 管腳上的時鐘信號拉高電平.

03SPI從機配置方式

3.1 常規多片選模式

01330cd0-8d8b-11ed-bfe3-dac502259ad0.png

上圖所示系統中,主機需要為每一個從機提供單獨的片選信號,一旦主機使能(拉低)片選信號,MOSI/MISO線上的時鐘和數據便可用于所選的從機。如果使能多個片選信號,則MISO線上的數據會被破壞,因為主機無法識別哪個從機正在傳輸數據。

但是,隨著從機數量的增加,來自主機的片選線的數量也增加。這會快速增加主機需要提供的輸入和輸出數量,并限制可以使用的從機數量。可以使用其他技術來增加常規模式下的從機數量,例如使用多路復用器產生片選信號。

3.2 菊花鏈模式

0146e37c-8d8b-11ed-bfe3-dac502259ad0.png

在菊花鏈模式下,所有從機的片選信號連接在一起,數據從一個從機傳播到下一個從機。在此配置中,所有從機同時接收同一SPI時鐘。來自主機的數據直接送到第一個從機,該從機將數據提供給下一個從機,依此類推。

使用該方法時,由于數據是從一個從機傳播到下一個從機,所以傳輸數據所需的時鐘周期數與菊花鏈中的從機位置成比例。例如,在上圖所示的8位系統中,為使第3個從機能夠獲得數據,需要24個時鐘脈沖,而常規SPI模式下只需8個時鐘脈沖。

時鐘周期和通過菊花鏈的數據傳播如下圖所示:

016279a2-8d8b-11ed-bfe3-dac502259ad0.png

04SPI的Verilog實現代碼

4.1 SPI目標實現功能

設計4線SPI master 模塊和slave 模塊,要求如下:

1. 主機模塊(master)接口定義:

module spi_master(

input clk_40k, //時鐘信號,40kHz

input rst_n, //復位信號,低有效

input [7:0] data_in, //主機準備要輸出給從機的數據,8位寬

input send_start,//通信使能信號,高有效,寬度為1個時鐘周期(40kHz),收到該信號后開始一次主從設備通信

output [7:0] data_out, //主機從從機接收到的數據,8位寬

output data_out_vld, //輸出數據有效標志,高電平有效,寬度為1個時鐘周期(40kHz)

output cs_n, //從設備片選使能信號,低有效,低電平時選中從設備與主設備進行通信,處于通信狀態時維持低電平

output sclk, //同步時鐘,1kHz,空閑時置低電平

input miso, //主機當前從從機收到的串行數據

output mosi //主機當前發送給從機的串行數據

);

2. 從機模塊(slave)接口定義:

module spi_slave(

input rst_n, //復位信號,低有效

input cs_n, //從設備片選使能信號

input sclk, //SPI時鐘,1kHz空閑時置低電平

input mosi, //從機從主機接收到的串行數據

output miso, //從機要發送給主機的串行數據

output [7:0] reg0_out, //內部寄存器0的值

output [7:0] reg1_out, //內部寄存器1的值

output [7:0] reg2_out, //內部寄存器2的值

output [7:0] reg3_out //內部寄存器3的值

);

3.電路功能描述:

Slave模塊中有四個八位內部寄存器(reg0、reg1、reg2、reg3),地址分別為 0~3,master模塊通過SPI總線配置slave模塊中四個寄存器的值,slave寄存器的值直接通過其端口輸出。Master模塊收到send_start信號之后,將數據data_in通過spi總線發送到slave模塊的reg0,然后將data_in循環右移兩位后發送到slave模塊的reg1,然后再將data_in循環右移兩位發送到reg2,最后將data_in再循環右移兩位發送到reg3。至此,master完成對slave中所有寄存器的配置。然后master再通過spi總線將slave中reg2的數據讀出來,通過data_out輸出,并同時給出一個周期寬度的data_out_vld。

4. SPI傳輸格式:

SPI每幀數據包含16位,最先發送的第0位為讀寫控制位,該位為0代表master向slave寫數據,為1則代表master從slave讀數據;隨后發送的第1-7位為地址位,先發高位地址再發低位地址,9-16位為數據位,高位數據先發。所有數據均在sclk的上升沿產生,下降沿采樣。

SPI寫數據格式如圖所示:

0177bb28-8d8b-11ed-bfe3-dac502259ad0.png

SPI讀數據格式如圖所示:

018df21c-8d8b-11ed-bfe3-dac502259ad0.png

4.2 Verilog代碼

1. 主模塊(SPI_master):

module spi_master(

input clk_40k,

input rst_n,

input [7:0] data_in,

input send_start,

output [7:0] data_out,

output data_out_vld,

output cs_n,

output sclk,

input miso,

output mosi

);

reg cs_n_r;

reg sclk_r;

reg mosi_r;

reg data_out_vld_r;

reg [7:0] data_out_r;

reg wr_rd;

reg [1:0] reg_num;

reg [6:0] clk_cnt;

reg [3:0] bit_cnt;

reg [7:0] rx_data;

reg [15:0] tx_data;

parameter reg0 = 2'd0;

parameter reg1 = 2'd1;

parameter reg2 = 2'd2;

parameter reg3 = 2'd3;

parameter reg0_address = 7'b0000000; //address of reg0

parameter reg1_address = 7'b0000001; //address of reg1

parameter reg2_address = 7'b0000010; //address of reg2

parameter reg3_address = 7'b0000011; //address of reg3

//cs_n

assign cs_n = cs_n_r;

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

cs_n_r <= 1'b1;

else if(send_start)

cs_n_r <= 1'b0;

else if(data_out_vld_r)

cs_n_r <= 1'b1;

end

//clk_cnt

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

clk_cnt <= 7'b0;

else if(cs_n_r)

clk_cnt <= 7'b0;

else if(clk_cnt == 7'd39)

clk_cnt <= 7'b0;

else

clk_cnt <= clk_cnt + 1'b1;

end

//bit_cnt

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

bit_cnt <= 4'b0;

else if(clk_cnt == 7'd39)

bit_cnt <= bit_cnt + 1'b1;

end

//sclk

assign sclk = sclk_r;

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

sclk_r <= 1'b0;

else if(clk_cnt == 7'd19 || clk_cnt == 7'd39)

sclk_r <= ~sclk_r;

end

//wr_rd

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

wr_rd <= 1'b0;

else if(cs_n_r)

wr_rd <= 1'b0;

else if(reg_num == reg3 && bit_cnt == 4'd15 && clk_cnt == 7'd39)

wr_rd <= 1'b1;

end

//send

//reg_num

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

reg_num <= reg0;

else if(cs_n_r)

reg_num <= reg0;

else if(bit_cnt == 4'd15 && clk_cnt == 7'd39)

case(reg_num)

reg0:reg_num <= reg1;

reg1:reg_num <= reg2;

reg2:reg_num <= reg3;

reg3:reg_num <= reg0;

endcase

end

//tx_data

always @ (posedge sclk_r or negedge rst_n)

begin

if(~rst_n)

tx_data <= 16'b0;

else if(wr_rd && bit_cnt == 4'd0)

tx_data <= {1'b1,reg2_address,8'b0};

else if(~wr_rd && bit_cnt == 4'd0)

case(reg_num)

reg0:tx_data <= {1'b0,reg0_address,data_in};

reg1:tx_data <= {1'b0,reg1_address,data_in[1:0],data_in[7:2]};

reg2:tx_data <= {1'b0,reg2_address,data_in[3:0],data_in[7:4]};

reg3:tx_data <= {1'b0,reg3_address,data_in[5:0],data_in[7:6]};

endcase

else

tx_data <= {tx_data[14:0],tx_data[15]};

end

//mosi

assign mosi = tx_data[15];

//recieve

//rx_data

always @ (posedge sclk_r or negedge rst_n)

begin

if(~rst_n)

rx_data <= 8'b0;

else if(wr_rd)

rx_data <= {rx_data[6:0],miso};

end

//data_out_vld

assign data_out_vld = data_out_vld_r;

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

data_out_vld_r <= 1'b0;

else if(wr_rd && bit_cnt == 4'd15 && clk_cnt == 7'd39)

data_out_vld_r <= 1'b1;

else

data_out_vld_r <= 1'b0;

end

//data_out

assign data_out = data_out_r;

always @ (posedge clk_40k or negedge rst_n)

begin

if(~rst_n)

data_out_r <= 8'b0;

else if(wr_rd && bit_cnt == 4'd15 && clk_cnt == 7'd39)

data_out_r <= rx_data;

end

endmodule

2. 從模塊(SPI_slave):

module spi_slave(

input rst_n,

input cs_n,

input sclk,

input mosi,

output miso,

output [7:0] reg0_out,

output [7:0] reg1_out,

output [7:0] reg2_out,

output [7:0] reg3_out

);

reg miso_r;

reg [7:0] reg1_out_r;

reg [7:0] reg2_out_r;

reg [7:0] reg3_out_r;

reg [7:0] reg0_out_r;

reg start;

reg wr_rd;

reg [3:0] bit_cnt;

reg [6:0] reg_addr;

reg [7:0] reg_data;

parameter reg0_address = 7'b0000000; //address of reg0

parameter reg1_address = 7'b0000001; //address of reg1

parameter reg2_address = 7'b0000010; //address of reg2

parameter reg3_address = 7'b0000011; //address of reg3

//start

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

start <= 1'b0;

else

start <= 1'b1;

end

//bit_cnt

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

bit_cnt <= 4'b0;

else if(start)

bit_cnt <= bit_cnt + 1'b1;

end

//wr_rd

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

wr_rd <= 1'b0;

else if(bit_cnt == 4'b0 && mosi == 1'b0)

wr_rd <= 1'b0;

else if(bit_cnt == 4'b0 && mosi == 1'b1)

wr_rd <= 1'b1;

end

//reg_addr

always @ (negedge sclk or negedge rst_n)

begin

if(~rst_n)

reg_addr <= 7'b0;

else if(bit_cnt >= 4'd1 && bit_cnt <= 4'd7)

reg_addr <= {reg_addr[5:0],mosi};

end

//reg_data

always @ (posedge sclk or negedge rst_n)

begin

if(~rst_n)

reg_data <= 8'b0;

else if(!wr_rd && bit_cnt >= 4'd7)

reg_data <= {reg_data[6:0],mosi};

else if(wr_rd && bit_cnt == 4'd6)

reg_data <= reg2_out_r;

else if(wr_rd && bit_cnt >= 4'd7)

reg_data <= {reg_data[6:0],reg_data[7]};

end

//reg_out

assign reg0_out = reg0_out_r;

assign reg1_out = reg1_out_r;

assign reg2_out = reg2_out_r;

assign reg3_out = reg3_out_r;

always @ (negedge sclk or negedge rst_n)

begin

if(~rst_n)

begin

reg0_out_r <= 8'b0;

reg1_out_r <= 8'b0;

reg2_out_r <= 8'b0;

reg3_out_r <= 8'b0;

end

else if(!wr_rd && bit_cnt == 4'd0)

case(reg_addr)

reg0_address: reg0_out_r <= reg_data;

reg1_address: reg1_out_r <= reg_data;

reg2_address: reg2_out_r <= reg_data;

reg3_address: reg3_out_r <= reg_data;

endcase

end

//miso

assign miso = miso_r;

always @ (negedge sclk or posedge rst_n)

begin

if(~rst_n)

miso_r <= 1'b0;

else if(wr_rd && bit_cnt >= 4'd7)

miso_r <= reg_data[7];

end

endmodule

3. Testbench(tb):

`timescale 1us/1us

module tb();

regclk_40k;

regrst_n;

reg [7:0] data_in;

regsend_start;

wiresclk;

wirecs_n;

wiremosi;

wiremiso;

wire [7:0] data_out;

wire data_out_vld;

wire [7:0] reg0_out;

wire [7:0] reg1_out;

wire [7:0] reg2_out;

wire [7:0] reg3_out;

spi_master i_spi_master(

.clk_40k (clk_40k),

.rst_n (rst_n),

.data_in (data_in),

.send_start (send_start),

.sclk (sclk),

.cs_n (cs_n),

.mosi (mosi),

.miso (miso),

.data_out (data_out),

.data_out_vld (data_out_vld)

);

spi_slave i_spi_slave(

.rst_n(rst_n),

.cs_n (cs_n),

.sclk (sclk),

.mosi(mosi),

.miso(miso),

.reg0_out(reg0_out),

.reg1_out (reg1_out),

.reg2_out (reg2_out),

.reg3_out (reg3_out)

);

initial

begin

rst_n = 1'b0;

#10rst_n = 1'b1;

end

initial

begin

clk_40k = 1'b0;

forever

#1clk_40k = ~clk_40k;

end

initial

begin

send_start = 1'b0;

data_in = 8'd0;

forever

begin

#200;

data_in = $random()%256;

send_start = 1'b1;

#2

send_start = 1'b0;

#8000;

end

end

endmodule

4. 仿真結果:

按照testbench對SPI主從設備進行仿真,仿真結果如圖:

01aa75ea-8d8b-11ed-bfe3-dac502259ad0.png

1. 系統時鐘和SPI時鐘不一致,clk_40k為高頻系統時鐘,利用計數器分頻實現1k波特率SPI時鐘;

2. 復位信號rst_n低電平有效,正常傳輸時始終處于高電平;

3. 開始傳輸時send_start信號拉高,傳輸結束時data_out_vld信號拉高;

4. SPI主設備將輸入數據data_in并行轉mosi串行輸出,SPI從設備將接收到的串行存入數據,將移位后的數據data_out并行轉miso串行輸出。

05SPI的優缺點

5.1 SPI協議優點

1. 全雙工同步串行通信;

2. 允許數據逐位傳遞;

3. 允許數據傳輸暫停;

4. 硬件結構簡單,不需要精密時鐘;

5. 從機不需要唯一地址,也不需要收發器

5.1 SPI協議缺點

1. 需要4個引腳接口;

2. 支持傳輸距離較短;

3. 硬件層面沒有定義校錯協議和從機應答信號。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 接口
    +關注

    關注

    33

    文章

    8885

    瀏覽量

    152985
  • Verilog
    +關注

    關注

    28

    文章

    1365

    瀏覽量

    111496
  • SPI
    SPI
    +關注

    關注

    17

    文章

    1749

    瀏覽量

    94155
  • 串行總線
    +關注

    關注

    1

    文章

    185

    瀏覽量

    30942

原文標題:常用串行總線(二)——SPI協議(Verilog實現)

文章出處:【微信號:Carlinx FPGA,微信公眾號:Carlinx FPGA】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    SPI總線的原理與Verilog設計實現

     SPI(Serial Peripheral Interface,串行外圍設備接口),是Motorola公司提出的一種同步串行接口技術
    發表于 08-14 09:00 ?1369次閱讀
    <b class='flag-5'>SPI</b><b class='flag-5'>總線</b>的原理與<b class='flag-5'>Verilog</b>設計<b class='flag-5'>實現</b>

    SPI通信總線概述和Verilog實現

    SPI = Serial Peripheral Interface,是串行外圍設備接口,是一種高速,全雙工,同步的通信總線。
    的頭像 發表于 02-07 14:28 ?1166次閱讀
    <b class='flag-5'>SPI</b>通信<b class='flag-5'>總線</b>概述和<b class='flag-5'>Verilog</b><b class='flag-5'>實現</b>

    SPI、I2C、UART三種串行總線協議的區別

    Receiver Transmitter:通用異步收發器)第,區別在電氣信號線上:SPI總線由三條信號線組成:串行時鐘(SCLK)、串行
    發表于 11-02 09:48

    常用串行總線協議有哪些

    一、常用串行總線協議目前常用的微機與外設之間進行數據傳輸的串行
    發表于 11-03 07:14

    常用串行總線協議有哪些

    常用串行總線協議I2C總線、SPI總線、SCI
    發表于 11-19 06:46

    SPI協議的相關資料分享

    FPGA作為從機與STM32進行SPI協議通信---Verilog實現 [轉]一.SPI協議簡要
    發表于 01-18 10:01

    SPI、I2C、UART三種串行總線協議的區別

    SPI、I2C、UART三種串行總線協議的區別
    發表于 07-17 17:23 ?0次下載

    一文介紹SPI串行總線

    SPI協議是由摩托羅拉公司提出的通訊協議(SerialPeripheralInterface),即串行外圍設備接口,是一種高速全雙工的通信總線
    發表于 07-16 17:58 ?3121次閱讀
    一文介紹<b class='flag-5'>SPI</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b>

    使用Verilog實現SPI串行總線接口的資料和源代碼免費下載

    器件以串行方式進行通信、交換信息。本文簡述了SPI總線的特點,介紹了其4條信號線,SPI串行總線
    發表于 08-19 08:00 ?9次下載
    使用<b class='flag-5'>Verilog</b><b class='flag-5'>實現</b><b class='flag-5'>SPI</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b>接口的資料和源代碼免費下載

    基于SPI串行總線接口的Verilog實現

    與各種外圍接口器件以串行方式進行通信、交換信息。本文簡述了SPI總線的特點,介紹了其4條信號線,SPI串行
    的頭像 發表于 05-29 10:16 ?5334次閱讀
    基于<b class='flag-5'>SPI</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b>接口的<b class='flag-5'>Verilog</b><b class='flag-5'>實現</b>

    基于FPGA的SPI協議及設計實現

    ,FSMC等協議。本文將基于FPGA來介紹并設計標準的SPI總線協議實現FPGA與MCU的數據通信。S
    發表于 11-05 19:05 ?24次下載
    基于FPGA的<b class='flag-5'>SPI</b><b class='flag-5'>協議</b>及設計<b class='flag-5'>實現</b>

    SPI協議

    目錄SPI協議簡介SPI物理層SPI協議SPI協議
    發表于 12-22 19:17 ?34次下載
    <b class='flag-5'>SPI</b><b class='flag-5'>協議</b>

    FPGA實現SPI協議(一)----SPI驅動

    1、什么是SPI協議SPI(Serial Peripheral Interface,串行外圍設備接口)通訊協議,是 Motorola 公司提
    發表于 12-22 19:29 ?19次下載
    FPGA<b class='flag-5'>實現</b>的<b class='flag-5'>SPI</b><b class='flag-5'>協議</b>(一)----<b class='flag-5'>SPI</b>驅動

    常用串行總線——SPI協議(上)

    SPI(Serial Perripheral Interface, 串行外圍設備接口)** 是 Motorola 公司推出的一種同步串行接口技術。SPI
    的頭像 發表于 01-21 17:00 ?1653次閱讀
    <b class='flag-5'>常用</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b>——<b class='flag-5'>SPI</b><b class='flag-5'>協議</b>(上)

    常用串行總線——SPI協議(下)

    SPI(Serial Perripheral Interface, 串行外圍設備接口)** 是 Motorola 公司推出的一種同步串行接口技術。SPI
    的頭像 發表于 01-21 17:03 ?1140次閱讀
    <b class='flag-5'>常用</b><b class='flag-5'>串行</b><b class='flag-5'>總線</b>——<b class='flag-5'>SPI</b><b class='flag-5'>協議</b>(下)
    主站蜘蛛池模板: 色综合天天射 | 天堂bt资源www在线 | 午夜在线视频 | 国模视频一区 | 欧美成人免费午夜全 | 夜夜爽www| 欧美人成网 | 欧美日韩亚洲色图 | 亚洲四虎在线 | 天天操天天玩 | 手机免费在线视频 | 色天天天天综合男人的天堂 | 在线电影天堂 | 九九免费久久这里有精品23 | 亚洲最新黄色网址 | 一级毛片真人免费播放视频 | 天天操天天摸天天干 | 性生交酡| 欧美成网 | 久久久99精品免费观看精品 | 国产精品综合色区在线观看 | 四虎色影院 | 色视频www在线播放国产人成 | 国产精品欧美一区二区三区 | 久色99| 成人影院在线观看视频 | 欧美日韩亚洲色图 | 一区二区高清在线观看 | 久久精品国产6699国产精 | 34看网片午夜理 | 久久的色偷偷 | 如果我们是季节韩剧在线观看 | 天天摸天天摸天天躁 | 最近最新视频中文字幕4 | 黄色a级免费 | 日本免费黄色小视频 | 中文字幕一区在线观看 | 亚洲人与牲动交xxxxbbbb | 色老板在线视频一区二区 | 色拍拍视频 | 免费 在线播放 |