1. 程式人生 > >FPGA作為從機與STM32進行SPI協議通訊---Verilog實現

FPGA作為從機與STM32進行SPI協議通訊---Verilog實現

FPGA作為從機與STM32進行SPI協議通訊—Verilog實現
0

一.SPI協議簡要介紹

SPI,是英語Serial Peripheral Interface的縮寫,顧名思義就是序列外圍裝置介面。SPI,是一種高速的,全雙工,同步的通訊匯流排,並且在晶片的管腳上只佔用四根線,節約了晶片的管腳,同時為PCB的佈局上節省空間,提供方便,正是出於這種簡單易用的特性,現在越來越多的晶片集成了這種通訊協議。
SPI匯流排是Motorola公司推出的三線同步介面,同步序列3線方式進行通訊:一條時鐘線SCK,一條資料輸入線MOSI,一條資料輸出線MISO;用於 CPU與各種外圍器件進行全雙工、同步序列通訊。SPI主要特點有:可以同時發出和接收序列資料;可以當作主機或從機工作;提供頻率可程式設計時鐘;傳送結束中斷標誌;寫衝突保護;匯流排競爭保護等。

SPI匯流排有四種工作方式(SP0, SP1, SP2, SP3),其中使用的最為廣泛的是SPI0和SPI3方式。SPI模組為了和外設進行資料交換,根據外設工作要求,其輸出串行同步時鐘極性和相位可以進行配置,時鐘極性(CPOL)對傳輸協議沒有重大的影響。如果CPOL=0,串行同步時鐘的空閒狀態為低電平;如果CPOL=1,串行同步時鐘的空閒狀態為高電平。時鐘相位(CPHA)能夠配置用於選擇兩種不同的傳輸協議之一進行資料傳輸。如果 CPHA=0,在串行同步時鐘的第一個跳變沿(上升或下降)資料被取樣;如果CPHA=1,在串行同步時鐘的第二個跳變沿(上升或下降)資料被取樣。

SPI主模組和與之通訊的外設時鐘相位和極性應該一致。

以下是SPI時序圖:

主要講解一下廣泛使用的兩種方式設定:

SPI0方式:CPOL=0,CPHA=0;SCK空閒狀態為低電平,第一個跳變沿(上升沿)取樣資料,無論對Master還是Slaver都是如此。

SPI3方式:CPOL=1,CPHA=1;SCK空閒狀態為高電平,第二個跳變沿(上升沿取樣資料,無論對Master還是Slaver都是如此。

其實對於SPI0和SPI1傳送與接收資料,可以總結為一句話:上升沿取樣資料,下降沿傳送資料。全雙工同時進行,當然,必須在CS拉低使能情況下。

二.FPGA作為Slaver實現SPI3方式與STM32通訊

1.STM32方面:用庫函式配置SPI1,設定CPOL=1,CPHA=1.

2.FPGA方面:

(1)通過邊沿檢測技術得出SCK上升沿與下降沿標誌,用於下面狀態機中的資料取樣及傳送。

(2)根據時序圖,採用2個狀態機分別在SCK上升沿實現資料取樣,下降沿實現資料傳送。無論是取樣還是傳送,都是高位在前,從Bit[7]到Bit[0],共8位資料。

(3)最後通過邊沿檢測技術得出資料取樣完成標誌,用於使用者操作。

以下是SPI3的時序圖:

三.Verilog程式碼部分

測試工程程式碼:實現了STM32每隔200ms傳送流水燈資料給FPGA,使FPGA系統板上的4個LED燈實現流水操作;同時,FPGA每隔1s傳送計數資料給STM32,並在STM32系統板上的LCD屏出來,即:顯示0-9迴圈計數。

但下面的程式碼只是SPI作為從機的驅動部分,包括SPI傳送資料與接收資料。

/*************************************************************
   ******** name:SPI_Slaver_Driver ****
   ** author:made by zzuxzt **
   ******** time:2014.4.29 ************
*************************************************************/
//use SPI 3 mode,CHOL = 1,CHAL = 1
module spi(input clk,
input rst_n,
input CS_N,
input SCK,
input MOSI,
input [7:0] txd_data,
output reg MISO,
output reg [7:0] rxd_data,
output rxd_flag);

//————————-capture the sck—————————–
reg sck_r0,sck_r1;
wire sck_n,sck_p;
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
sck_r0 <= 1’b1; //sck of the idle state is high
sck_r1 <= 1’b1;
end
else
begin
sck_r0 <= SCK;
sck_r1 <= sck_r0;
end
end

assign sck_n = (~sck_r0 & sck_r1)? 1’b1:1’b0; //capture the sck negedge
assign sck_p = (~sck_r1 & sck_r0)? 1’b1:1’b0; //capture the sck posedge

//———————–spi_slaver read data——————————-
reg rxd_flag_r;
reg [2:0] rxd_state;
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rxd_data <= 1’b0;
rxd_flag_r <= 1’b0;
rxd_state <= 1’b0;
end
else if(sck_p && !CS_N)
begin
case(rxd_state)
3’d0:begin
rxd_data[7] <= MOSI;
rxd_flag_r <= 1’b0; //reset rxd_flag
rxd_state <= 3’d1;
end
3’d1:begin
rxd_data[6] <= MOSI;
rxd_state <= 3’d2;
end
3’d2:begin
rxd_data[5] <= MOSI;
rxd_state <= 3’d3;
end
3’d3:begin
rxd_data[4] <= MOSI;
rxd_state <= 3’d4;
end
3’d4:begin
rxd_data[3] <= MOSI;
rxd_state <= 3’d5;
end
3’d5:begin
rxd_data[2] <= MOSI;
rxd_state <= 3’d6;
end
3’d6:begin
rxd_data[1] <= MOSI;
rxd_state <= 3’d7;
end
3’d7:begin
rxd_data[0] <= MOSI;
rxd_flag_r <= 1’b1; //set rxd_flag
rxd_state <= 3’d0;
end
default: ;
endcase
end
end

//——————–capture spi_flag posedge——————————–
reg rxd_flag_r0,rxd_flag_r1;
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rxd_flag_r0 <= 1’b0;
rxd_flag_r1 <= 1’b0;
end
else
begin
rxd_flag_r0 <= rxd_flag_r;
rxd_flag_r1 <= rxd_flag_r0;
end
end

assign rxd_flag = (~rxd_flag_r1 & rxd_flag_r0)? 1’b1:1’b0;

//———————spi_slaver send data—————————
reg [2:0] txd_state;
[email protected](posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
txd_state <= 1’b0;
end
else if(sck_n && !CS_N)
begin
case(txd_state)
3’d0:begin
MISO <= txd_data[7];
txd_state <= 3’d1;
end
3’d1:begin
MISO <= txd_data[6];
txd_state <= 3’d2;
end
3’d2:begin
MISO <= txd_data[5];
txd_state <= 3’d3;
end
3’d3:begin
MISO <= txd_data[4];
txd_state <= 3’d4;
end
3’d4:begin
MISO <= txd_data[3];
txd_state <= 3’d5;
end
3’d5:begin
MISO <= txd_data[2];
txd_state <= 3’d6;
end
3’d6:begin
MISO <= txd_data[1];
txd_state <= 3’d7;
end
3’d7:begin
MISO <= txd_data[0];
txd_state <= 3’d0;
end
default: ;
endcase
end
end

endmodule

相關推薦

FPGA作為STM32進行SPI協議通訊---Verilog實現 [轉]

一.SPI協議簡要介紹 SPI,是英語Serial Peripheral Interface的縮寫,顧名思義就是序列外圍裝置介面。SPI,是一種高速的,全雙工,同步的通訊匯流排,並且在晶片的管腳上只佔用四根線,節約了晶片的管腳,同時為PCB的佈局上節省空間,提供方便,正

FPGA作為STM32進行SPI協議通訊---Verilog實現

FPGA作為從機與STM32進行SPI協議通訊—Verilog實現 0 一.SPI協議簡要介紹 SPI,是英語Serial Peripheral Interface的縮寫,顧名思義就是序列外圍裝置介面。SPI,是一種高速的,全雙工,同步的通訊匯流排,並且在

FPGA作為STM32進行SPI協議通信---Verilog實現

src 空間 thumb author 必須 介紹 brush ref 2.0 一.SPI協議簡要介紹 SPI,是英語Serial Peripheral Interface的縮寫,顧名思義就是串行外圍設備接口。SPI,是一種高速的,全雙工,同步的通信總線,並且在芯片的管腳

FPGA 學習之路(九)SPI協議通訊

SPI通訊協議 SPI是同步序列通訊介面。 SPI是英語Serial Peripheral Interface的縮寫,顧名思義就是序列外圍裝置介面。SPI是一種高速的、全雙工、同步通訊匯流排,標準的SPI也僅僅使用4個引腳,常用於微控制器和EEPROM、FL

ESP8266 是一個完整且自成體系的 WiFi 網絡解決方案,能夠獨立運行,也可以作為搭載於其他主機 MCU 運行

處理 天線 -1 系統資源 pwm adc 高度 能夠 能力 ESP8266EX 在搭載應用並作為設備中唯一的應用處理器時,能夠直接從外接閃存中啟動。內置的高速緩沖存儲器有利於提高系統性能,並減少內存需求。另外一種情況是,ESP8266EX 負責無線上網接入承擔 WiF

MikroTik RouterOS使用VirtualBox掛載物理硬盤作為虛擬硬盤進行安裝

bsp png ng- 自動 rtu sin out virtual get 說明:這一切似乎在Windows下更好操作。虛擬機操作不是難點,難點在於虛擬磁盤的轉換掛載 一、先掛載硬盤 # 創建虛擬鏡像並映射到物理硬盤 cd "c:\Program Files\O

LIN匯流排多主機通訊(控制+反饋)

LIN通訊方式為主從機通訊,屬於非同步通訊。其中幀頭+資料幀才算一完整報文,多從機與主機通訊資料流(控制+反饋)如下:      一號從機:    第一次進入中斷,一號從機判斷接收到主機幀頭,分析LIN匯流排幀頭ID 是否為該從機控制指令,若是,從機則置位標誌位One_Fla

STM32F103使用硬體i2c作為模式

一、簡單說明 本例子參考了ST官方歷程,官方歷程的連結如下 關於i2c的協議這裡就不做描述了 關於STM32 i2c的模式可以在中文資料手冊中檢視 手冊中已經描述,該模組預設工作在從模式,要想變為主模式,主要生產一個起始條件。(主模式的程式碼可以參考野火開發板的硬體i2

STM32F207上I2C作為的硬體中斷實現的程式碼及註釋

人家都說,寫驅動簡單,一般網上都有參考程式,或者官網有demo,可是要是看不懂例程程式碼,怎麼辦?確實也沒什麼好辦法,只能硬著頭皮,自己花時間研究研究嘍。一般看懂程式碼最起碼知道其中的原理,才能推測出

【Arduino】使用C#實現Arduino電腦進行串行通訊

可視化 action 指示 追加 停止 format reads 接受 按鈕 在給Arduino編程的時候,因為沒有調試工具,經常要通過使用串口通訊的方式調用Serial.print和Serial.println輸出Arduino運行過程中的相關信息,然後在電腦上用Ardu

wince模擬器PC進行串列埠通訊設定步驟(附詳細步驟圖解)

在網上一搜,關於wince模擬器與PC進行串列埠通訊的介紹很多,也有人說模擬器不能虛擬串列埠的,也有說必須用串列埠連線線把USB口和串列埠連線起來的,說法可謂種類繁多。結合搜尋到的資訊,我進行多次試驗,最終實現了WINCE模擬器串列埠與PC串列埠工具之間的通訊。現介紹一下步驟

解決smb宿主虛擬機器之間的通訊問題

smb通訊之間的設定過程我們就不說了,就說下中間遇到的問題。我這是第二次搭建smb,還是出現了第一次遇到的很多問題。所以我認為還是很有必要記錄下。宿主機:win10教育版64,虛擬機器Redhat9.0 VMware1、虛擬機器ip地址問題--我用的筆記本無線網絡卡上網,正常

使用ZigBee模組實現PC樹莓派的無線通訊

背景:最近在做專案的過程中看到了一份以前的學長留給我的ZigBee模組的資料,之前在和其它學院的同學一起準備某個比賽的時候聽說過ZigBee是一種無線通訊模組,於是就淘寶了一下,找到了這個 然後在淘

PCFL2440的串列埠通訊程式設計

#include <stdio.h> /*標準輸入輸出定義*/ #include <stdlib.h> /*標準函式庫定義*/ #include <unistd.h> /*Unix標準函式

AT指令進行MQTT協議通訊

        M0M1系列模組,經過1年多的演化後,已存在多套標準的韌體程式。如果使用者需要使用MQTT方式進行通訊,則需要選擇標準AT指令+MQTT的版本。此版本不僅可以支援標準AT指令的SOCKET通訊,還可以支援阿里雲物聯網套件。本文將著重介紹標準MQTT伺服器的連線

關於 STM32 SPI 模式的問題

你再尋找 關於SPI 作為從機時  而且還沒有NSS 訊號    而出現數據接收錯誤的煩惱吧 最近給客戶做一個專案 使用到了SPI 從機     在網上找答案  但是沒有找到自己滿意的  現在來說  都沒有 將SPI 通訊接收錯誤的根本原因說明白 網上有很多關於STM32

STM32SPIDMA例程

#include "stm32f10x.h" /* RCC時鐘配置 */ void RCC_config(void) { ErrorStatus HSEStartUpStatus;/* RCC暫存器設定為預設配置 */RCC_DeInit();/* 開啟外部高速時鐘 */R

51單片SPI協議應用實例

fly 級聯 微軟雅黑 應用 目前 clas log tom .com ———————————————————————————————————————————— SPI總線 - - - - - - - - - - - - - - - - - - - - - - - -

如何讓虛擬進行通信

.cn 虛擬 主機 ifconfig 復制 配置 通信 列操作 nbsp 如果ifconfig還不能看到IP,那麽就需要做下列操作,或者說如果虛擬機是復制來的,就需要做以下操作 進行主機配置 橋接:虛擬機利用的是真實網卡和互聯網局域網進行通信 僅主機:缺點就是不可以上

STM32SPIQSPI學習筆記

QSPI介面簡介 QSPI是Queued SPI的簡寫,是Motorola公司推出的SPI介面的擴充套件,比SPI應用更加廣泛。 在SPI協議的基礎上,Motorola公司對其功能進行了增強,增加了佇列傳輸機制,推出了佇列序列外圍介面協議(即QSPI協議)。 QSPI是一種專用的通訊