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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;深入阐释了信号、协议、缓存等…