Zynq開發實踐(FPGA之spi實現)

【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 聯系信箱:feixiaoxing @163.com】

? ? ? ? 雖然串口用的地方比較多,實現起來也比較簡單。但是串口本身速度比較慢,不利于高速數據通信。而且單個串口沒有辦法和很多芯片設備通信。所以,人們在串口的基礎之上添加clk、cs信號,這樣就形成了基本的spi總線協議。它也是mcu/soc和fpga通信的重要方式之一。

1、spi和串口的區別

? ? ? ? 相比較串口,spi多了cs和clk。正因為有了cs,這樣fpga就可以通過它來區分不同的spi接口芯片。此時clk、rx、tx就可以完全復用。此外有了clk之后,數據的收發都可以借助于clk的邊沿來進行處理,處理的效率高了很多,甚至可以達到20~50M,快一點的話100M也是可以的,這不是串口可以比擬的。

2、spi和iic的區別

? ? ? ? 現在spi和iic比較,iic的收發是同一根pin,iic也有clk信號,但是沒有cs信號。這導致iic上的芯片都會接收總線上的數據,但是如果發現設備數據不是自己的,會直接扔掉。

3、spi和iic應用范圍非常廣

? ? ? ? 不僅spi norflash、spi nandflash,還是spi網絡芯片、spi adc、spi dac,spi和iic的應用范圍都是非常廣的。spi一般用于中高速芯片,iic和uart則用于低速芯片。所以說,如果掌握好了spi、iic、uart之后,基本上mcu能做的事情,都可以用fpga來完成。像rgb、mcu、vga這樣mcu做不來的視頻接口,也可以用fpga來完成。甚至于很多sdio接口的外設,都是可以轉換成spi訪問,tf卡就是一個典型的案例。

? ? ? ? spi本身只是一個總線,所以我們實際對芯片操作的時候,還需要了解操作的方式,比如怎么發命令,怎么發命令和地址,怎么讀數據。就拿spi nanflash來說,要做好這個工作需要分成這三步,

實現基本的spi協議;
實現訪問spi nandflash需要的各個命令;
根據需求訪問spi nandflash,做好讀、寫和狀態的校驗。

4、spi master和spi slave

? ? ? ? 一般把主動發起命令的設備稱之為master,被動接收命令的設備稱之為slave。當然fpga和spi nandflash通信時,此時fpga就是master,nandflash就是slave。如果此時mcu/soc和fpga通信,這種情況下mcu/soc就是master,fpga就是slave。

? ? ? ? 如果有同學不知道如何用spi寫slave,那么可以找一個spi nandflash的芯片手冊,把自己當成一個spi nand,去適配master就可以了。

5、spi的四種模式

? ? ? ? 根據時鐘極性cpol和時鐘相位cpha,就可以把spi分成四種工作模式。其中cpol,就是空閑狀態的時候,spi處于高電平還是低電平。而cpha,則告訴我們采樣的時候,應該是第一個邊沿采樣,還是第二個邊沿采樣。實際應用的時候,我們記住0-0就可以,即空閑狀態是0,第一個邊沿觸發的時候采樣。

6、發送和采樣數據

? ? ? ? spi的發送和采樣都是基于clock進行的。如果spi時鐘不是很快,那么可以通過計數分頻的辦法去解決。首先我們談一下發送。假設spi的工作模式是0-0,即空閑為0,上升沿采樣。這種情況下,只需要一個周期發送一個bit數據即可,每半個周期時鐘反轉一下,也就是上升沿的時候提示對方接收數據,因此數據肯定是提前準備好的。

? ? ? ? 采樣的時候一般是反過來的。以spi nandflash為例。fpga發送完命令之后,一般就可以開始準備采樣數據了。采樣的時候,其實和發送也是一樣的,在上升沿的時候開始采樣,因為對方數據發送一般是下降沿開始發送。所以在一個周期內spi clock做兩次翻轉就可以了。

7、spi協議的實現

? ? ? ? 所以這里spi的實現主要集中在底層領域,涉及到spi clock、cs、mosi、miso,可以好好看一下,


module spi_top(input clk,input rst,input rw,input rw_valid,input[7:0] w_data,output[7:0] r_data,output status,// about signaloutput cs,output reg tx,output reg spi_clk,input rx);reg[3:0] state;
reg[3:0] next_state;
reg[15:0] counter;
reg[3:0] num;reg rw_reg;
reg[7:0] w_data_reg;
reg[7:0] r_data_reg;localparam TIMER_INTERVAL = 16'd20;localparam IDLE     = 4'h0;
localparam SPI_CLK  = 4'h1;
localparam SPI_CHK  = 4'h2;
localparam LAST_CLK = 4'h3;
localparam SPI_END  = 4'h4;// about state machinealways@(posedge clk or negedge rst)if(!rst)state <= IDLE;else state <= next_state;always@(*)case(state)IDLE: beginif(rw_valid)next_state = SPI_CLK;elsenext_state = IDLE;endSPI_CLK: beginif(counter == TIMER_INTERVAL)next_state = SPI_CHK;elsenext_state = SPI_CLK;endSPI_CHK: beginif(num == 4'hf)next_state = LAST_CLK;elsenext_state = SPI_CLK;endLAST_CLK: beginif(counter == TIMER_INTERVAL)next_state = SPI_END;elsenext_state = LAST_CLK;endSPI_END:next_state = IDLE;default:next_state = IDLE;endcase// about cs, sometime can be used for multiple devicesassign cs = (state != IDLE) ? 0 : 1;// save rw dataalways@(posedge clk or negedge rst)if(!rst) beginrw_reg <= 0;w_data_reg <= 8'h0;endelse if(state == IDLE && rw_valid) beginrw_reg <= rw;w_data_reg <= w_data;end// about frequency divisonalways@(posedge clk or negedge rst)if(!rst)counter <= 16'h0;else if(state == SPI_CLK || state == LAST_CLK)counter <= counter + 1;elsecounter <= 16'h0;// about clk numberalways@(posedge clk or negedge rst)if(!rst)num <= 4'h0;else if(state == SPI_CHK)num <= num + 1;else if(state == IDLE)num <= 4'h0;//
// about spi clk
// this is very import, useful for low speed communication
//always@(posedge clk or negedge rst)if(!rst)spi_clk <= 0;else if(state == SPI_CLK && counter == TIMER_INTERVAL)spi_clk <= ~spi_clk;else if(state == IDLE)spi_clk <= 0;// about tx signalalways@(posedge clk or negedge rst)if(!rst)tx <= 0;else if(state == SPI_CLK && rw_reg)tx <= w_data_reg[0];else if(state == SPI_CHK && num <= 13 && rw_reg) // fix bug about num 2025.9.9tx <= w_data_reg[(num >> 1) +1];else if(state == IDLE)tx <= 0;// about rx signalalways@(posedge clk or negedge rst)if(!rst)r_data_reg <= 8'h0;else if(state == SPI_CHK && !num[0] && !rw_reg)r_data_reg[num >> 1] <= rx;else if(state == IDLE)r_data_reg <= 8'h0;assign r_data = r_data_reg;
assign status = (state == SPI_END);endmodule

? ? ? ? 實際跑起來,添加上testbench之后,仿真截圖是這樣的,

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96279.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96279.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96279.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

指甲打磨機/磨甲器MCU控制方案開發,輕松解決磨甲問題

美甲打磨機/指甲打磨機核心功能需求 1. 基礎功能 無級調速(5,000-30,000 RPM&#xff0c;PWM控制) 正反轉切換&#xff08;可選&#xff0c;用于拋光/去角質&#xff09; 按鍵鎖/防誤觸&#xff08;長按3秒解鎖&#xff09; 鋰電池管理&#xff08;3.7V單節&#xff0c;帶充電指…

臨床數據挖掘與分析:利用GPU加速Pandas和Scikit-learn處理大規模數據集

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 摘要 隨著電子健康記錄&#xff08;EHR&#xff09;的普…

二進制安裝MySQL 8.0指南:跨平臺、自定義數據路徑、安全遠程訪問配置

二進制安裝 MySQL 8.0 在生產或測試環境中&#xff0c;我們常常希望避免包管理器帶來的依賴和交互問題&#xff0c;尤其是當系統自帶版本過舊或安裝過程頻繁彈窗時。此時&#xff0c;使用 MySQL 官方提供的二進制壓縮包&#xff08;Generic Linux Binary&#xff09; 進行安裝…

Z檢驗與T檢驗的區別與聯系:原理、公式和案例全解

Z檢驗與T檢驗全解析&#xff1a;原理、區別與實際案例 統計學的核心任務之一&#xff0c;就是通過有限的樣本數據去推斷總體特征。在這一過程中&#xff0c;假設檢驗成為了最常見的工具。而在眾多檢驗方法中&#xff0c;Z檢驗與T檢驗幾乎是入門必學&#xff0c;也是應用最廣泛的…

SpringBoot之緩存(最詳細)

文章目錄項目準備新建項目并選擇模塊安裝添加依賴添加application.yml刪除demos.web包編寫pojo層userdto/ResultJson編寫mapper層UserMapper編寫service層UserService編寫controller層編寫配置類MybatisPlusConfig編寫測試類1 緩存分類1.1 MyBatis一級緩存1.2 MyBatis二級緩存1…

B站 韓順平 筆記 (Day 29)

目錄 1&#xff08;集合的框架體系&#xff09; 2&#xff08;Collection接口和常用方法&#xff09; 2.1&#xff08;Collection接口實現類特點&#xff09; 2.2&#xff08;常用方法&#xff09; 2.3&#xff08;遍歷元素方式1&#xff1a;迭代器&#xff09; 1&#x…

axios報錯解決:unsupported BodyInit type

目錄 問題 原因 解決方法 問題 Got ‘unsupported BodyInit type’ bug on iPhone 14(IOS 17.5) Issue #6444 axios/axios 我這里是iPhone 6plus打開會報錯白屏 好多人遇到了相同的問題 當我在 iPhone 14 上瀏覽頁面時,我收到一條錯誤消息:錯誤:不支持的 BodyInit 類型,…

iperf3網絡性能測試工具

iperf3 是一個功能非常強大的網絡性能測試工具,用于測量兩個網絡節點之間的最大TCP、UDP帶寬和性能。它通過創建數據流并測量其吞吐量來工作。 下面我將為您詳細介紹其核心用法、常用命令和參數。 核心概念:客戶端/服務器模式 iperf3 測試需要兩臺機器:一臺作為服務器端(…

【C#】 資源共享和實例管理:靜態類,Lazy<T>單例模式,IOC容器Singleton我們該如何選

文章目錄前言一、靜態類1.1 靜態類的特點1.2 靜態類的使用1.3 靜態類的缺點二、單例模式2.1 Lazy延遲初始化2.2 Lazy< T>單例模式的使用2.3 單例模式的特點三、IOC的Singleton總結前言 編寫程序的時候&#xff0c;常常能碰到當某些數據或方法需要被整個程序共享&#xf…

MySQL——存儲引擎、索引

一、存儲引擎1.MySQL體系結構2.存儲引擎簡介存儲引擎就是儲存數據、建立索引、更新/查詢數據等技術的實現方式。儲存引擎是基于表的&#xff0c;而不是基于庫的&#xff0c;所以存儲引擎也可被稱為表類型建表語句&#xff1a;查詢數據庫支持的儲存引擎&#xff1a;show engines…

機器學習01——機器學習概述

上一章&#xff1a;機器學習核心知識點目錄 下一章&#xff1a;機器學習02——模型評估與選擇 機器學習實戰項目&#xff1a;【從 0 到 1 落地】機器學習實操項目目錄&#xff1a;覆蓋入門到進階&#xff0c;大學生就業 / 競賽必備 文章目錄一、參考書推薦二、機器學習的基本概…

Shell編程:檢測主機ip所在網段內其他在線ip

一、邏輯設計獲取本機 ip 及 網段循環檢測網段內所有 ip判斷 ping 結果&#xff0c;符合條件的輸出相關信息二、代碼展示#!/bin/bash#獲取本機ip local_iphostname -I #local_ipip addr| grep "inet "|grep -v 127.0.0.1| awk {print $2}#獲取本機網段 networkecho $…

Windows安裝Chroma DB

安裝步驟 安裝python 3.8或以上的版本創建虛擬環境&#xff1a;python -m venv chroma_env激活虛擬環境&#xff1a;.\chroma_env\Scripts\activate安裝Chroma DB&#xff1a;pip install chromadb(可選)安裝擴展功能&#xff1a;pip install sentence-transformers pypdf tikt…

李彥宏親自說

昨天&#xff0c;李彥宏親自說&#xff1a;百度的數字人直播以假亂真&#xff0c;很多人是看不出這是數字人&#xff0c;而且轉化率很高”這幾個月百度一直在推“數字人”不再強調“大模型”了。數字人是AI落地最適合企業的一款產品&#xff0c;一般用于客服、面試、直播帶貨等…

JS 中bind、call、apply的區別以及手寫bind

1.作用call、apply、bind作用是改變函數執行的上下文&#xff0c;簡而言之就是改變函數運行時的this指向那么什么情況下需要改變this的指向呢&#xff1f;下面舉個例子var name "lucy"; var obj {name: "martin",say: function () {console.log(this.nam…

vue2(7)-單頁應用程序路由

1.單頁應用程序如 單頁&#xff1a;網易云&#xff0c;多頁&#xff1a;京東單頁應用程序&#xff0c;之所以開發效率高&#xff0c;性能高&#xff0c;用戶體驗好最大的原因是&#xff1a;頁面按需更新 要按需更新&#xff0c;就要明確訪問路徑和組件的關系這時候就要用…

vue中通過heatmap.js實現熱力圖(多個熱力點)熱區展示(帶鼠標移入彈窗)

直接上完整代碼&#xff01;記錄實現方式 注意heatmap.min.js需要通過heatmap.js提供的下載地址進行下載&#xff0c;地址放在下邊 url&#xff1a;heatmap GIT地址 <template><div class"heatmap-view" ref"heatmapContainer"></div&g…

配置Kronos:k線金融大模型

github地址 網頁btc預測demo使用的Kronos-mini模型 huggingface的倉庫 文章目錄配置環境安裝python環境獲取市場數據的庫通過webui使用example中的例子prediction_example.py補充說明根據原例優化的代碼CryptoDataFetcher單幣對多周期預測配置環境 使用conda的環境. 首先進行換…

【Deep Learning】Ubuntu配置深度學習環境

【start: 250715】 文章目錄ubuntu與深度學習安裝cuda查看顯卡信息&#xff08;nvidia-smi&#xff09;升級驅動下載cuda安裝conda安裝anaconda默認指向自己的conda初始化conda確認 conda.sh 被加載安裝cuda-toolkit直接安裝cuda-toolkit&#xff08;高級的&#xff09;安裝高于…

車載數據采集(DAQ)解析

<摘要> 車載數據采集&#xff08;DAQ&#xff09;軟件模塊是現代汽車電子系統的核心組件&#xff0c;負責實時采集、處理、記錄和傳輸車輛運行數據。本文系統解析了DAQ模塊的開發&#xff0c;涵蓋其隨著汽車智能化演進的歷史背景&#xff0c;深入闡釋了信號、協議、緩存等…