『FPGA通信接口』串行通信接口-SPI

在这里插入图片描述

文章目录

  • 1.SPI简介
  • 2.控制时序
  • 3.Dual、Qual模式
  • 4.例程设计与代码解读
  • 5.SPI接口实战应用
    • 5.1时序要求
    • 5.2仿真时序图
    • 5.3代码设计
  • 6.传送门

1.SPI简介

SPI是串行外设接口(Serial Peripheral Interface)的缩写,通常说SPI接口或SPI协议都是指SPI这一种串行外设接口规范。相对于串口,SPI是一种高速的(可达10Mb\s以上),全双工,同步的通信总线。串口是点对点的全双工的异步通信,因此要通信双方按照相同的约定(指起始、暂停位、波特率)才能在数据上同步,准确通信。而SPI是一种同步通信的总线结构,同步是指有专门时钟线用来同步源端和目的端,总线结构是指主从之分,通常是一个设备做主,可以多个设备做从,也正因为如此才有了CS片选线,指定所选从设备。
在这里插入图片描述
在实际的应用中,通常也只是一主一从。SPI接口多应用于Flash、ADC、LCD控制器,CMOS寄存器配置接口等场景。SPI在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,越来越多的芯片集成了这种通信协议。

2.控制时序

SPI有四根线,如下,
在这里插入图片描述
(1)MISO– Master Input Slave Output,主设备数据输入,从设备数据输出;
(2)MOSI– Master Output Slave Input,主设备数据输出,从设备数据输入;
(3)SCLK – Serial Clock,时钟信号,由主设备产生;
(4)CS – Chip Select,从设备使能信号,由主设备控制。
SPI通信一般包括主设备(Master)和从设备(Slave),主设备负责发起通信并控制通信的时序,从设备则响应主设备的指令。SPI通信有四种模式,分别是模式0、模式1、模式2和模式3,不同的模式在时钟极性和相位上有所不同。这四种数据传输的时序模式,是由设备的属性的决定的,用CPOL和CPHA标识这四种时序。CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0(1),空闲电平为低电平(高电平)CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,CPHA=1,则在每个周期的第二个时钟沿采样。 通常使用的是MODE0模式,即CPOL=CPHA=0,空闲时为低电平,在第一个时钟沿采样。其他几种模式如果需要可以上网搜索,资料很多。
使用SPI接口时需要注意,很多SPI接口的芯片并不是标准的SPI协议,可能是稍有变化,例如对哪个沿采样会有明确的说明。此外,还有一种可能是在SPI协议的基础上进一步做限制,例如要求一次读写过程结束后CS必须拉高等。SPI要求是高位在前,MSB的方式。还有就是SPI一个时钟周期必然要执行接收一位数据和发送一位数据。

3.Dual、Qual模式

上面描述的就是标准SPI,有4根引脚信号:clk , cs, mosi, miso。针对SPI Flash而言,有Dual SPI和Qual SPI两种模式,这是因为,Flash器件的全双工并不常用,因此扩展mosi和miso的用法,让它们工作在半双工,用以加倍数据传输。也就是对于Dual SPI Flash,可以发送一个命令字节进入dual mode,这样mosi变成SIO0(serial io 0),mosi变成SIO1(serial io 1),这样一个时钟周期内就能传输2个bit数据,加倍了数据传输。与Dual SPI类似,Qual SPI Flash增加了两根I/O线(SIO2,SIO3),目的是一个时钟内传输4个bit。

4.例程设计与代码解读

如图所示,把Spi_driver模块的输入输出分成两个部分,一个部分为图示左侧的与其他模块交互的接口,另一部分为图示右侧与物理管脚相连。Spi_en信号为外部的脉冲信号,收到该脉冲执行一次8Bit的发送动作,和8Bit的接收动作。通过VIO产生spi_en信号和要发送的数据信号data[7:0],将板卡上的mosi和miso管脚相连,判断发送数据和接收数据是否一致,若一致则点亮led。由于缺乏带SPI设备的板卡,故设计此例程。一次发送动作结束后会产生spi_done的脉冲信号,在发送动作执行过程中,spi_busy持续为拉高状态。另外,spi_sck作为同步时钟直接决定传输数据的速度,通常在10Mb/s以下,或者依据对端设备来指定。
在这里插入图片描述

在使用SPI设备时可以修改此驱动模块以满足需求,左侧信号与外部设备交互,当busy拉高的时候不允许发送spi_en信号;可以对data信号采用多路选择器,以完成某些固定的指令或者读写操作;同样,数据的位宽也可以扩展。另外,实际使用的时候应该使用cs管脚,按照相关设备的要求灵活运用该管脚。
下面代码在硬件板卡上完成测试。该代码使用MODE0,即CPOL=CPHA=0的模式。程序分为以下四步,第一步产生sck同步时钟,第二步依据en指示信号写数据,第三步依据en指示信号并发读数据,第四步产生ui交互信号。

module spi_wr(input        clk_i       ,//user interface// input        spi_en     ,//其他模块的spi使能信号// input    [7:0]data      ,output       spi_busy      ,//指示spi的状态,表示SPI过程output       spi_done      ,//指示spi结束一次动作output       led           ,// output       spi_cs        ,//SPI从机的片选信号,低电平有效。output       spi_clk       ,//主从机之间的数据同步时钟。output       spi_mosi      ,//数据引脚,主机输出,从机输入。input        spi_miso      //数据引脚,主机输入,从机输出。 );
// assign spi_cs = 0;
//1.同步时钟产生模块 用50MHz分频为50KHz
assign spi_clk = m_clk;
parameter [9:0] SPI_DIV    = 10'd499;//分频定为50KHz,50Mhz/50K/2- 1'b1=499
reg [9:0] clk_cnt = 10'd0;//分频计数器
always@(posedge clk_i)beginif(clk_cnt < SPI_DIV&&spi_busy)clk_cnt <= clk_cnt + 1'b1;else clk_cnt <= 10'd0;
end
reg m_clk = 1'b0;
always@(posedge clk_i)beginif(spi_en)m_clk <= 1'b0;else if(clk_cnt==SPI_DIV) m_clk <= ~m_clk;
end
//2.接收en信号和数据,执行spi mosi操作(写数据)
//计数发送个数
reg [3:0]tx_cnt = 0;
always@(posedge clk_i)beginif(spi_en)begintx_cnt <= 0; end else if((clk_cnt == SPI_DIV)&&(tx_cnt==4'd8))begintx_cnt <= 0;end else if((clk_cnt == SPI_DIV)&&spi_clk==0)tx_cnt<=tx_cnt+1;
end
//移位寄存器发送
wire [7:0]data;
reg  [7:0]data_reg=8'b0;//数据源
always@(posedge clk_i)beginif(spi_en)data_reg <= data;else if(spi_done)data_reg <=8'b0;else if(clk_cnt == SPI_DIV&&spi_clk==1)data_reg[7:0] <= {data_reg[6:0],data_reg[7]};
end
assign spi_mosi = data_reg[7];
//3.接收en信号和数据,执行spi miso操作(读数据)
reg  [7:0]data_fifo=8'b0;
always@(posedge clk_i)beginif((clk_cnt == SPI_DIV)&&spi_clk==0)begincase (tx_cnt)0 : data_fifo[7] <= spi_miso;1 : data_fifo[6] <= spi_miso;2 : data_fifo[5] <= spi_miso;3 : data_fifo[4] <= spi_miso;4 : data_fifo[3] <= spi_miso;5 : data_fifo[2] <= spi_miso;6 : data_fifo[1] <= spi_miso;7 : data_fifo[0] <= spi_miso;default: ;endcaseend else data_fifo <= data_fifo;
end
//4.发出user interface相关指示信号
wire spi_en;
reg spi_busy =0;
assign spi_done = ((clk_cnt == SPI_DIV)&&(tx_cnt==4'd8)) ? 1'b1 : 1'b0;
assign led = (data_fifo==8'b11010111) ? 1'b1 : 1'b0;
//产生busy信号,指示spi进程
always@(posedge clk_i)beginif(spi_en)spi_busy<=1'b1;else if(spi_done)spi_busy<=1'b0;elsespi_busy<=spi_busy;
end
vio_0 use_vio (.clk(clk_i),                // input wire clk.probe_out0(spi_en),  // output wire [0 : 0] probe_out0.probe_out1(data)  // output wire [7 : 0] probe_out1
);
ila_0 your_instance_name (.clk(clk_i), // input wire clk.probe0({data_reg,data_fifo}), // input wire [15:0]  probe0  .probe1(tx_cnt), // input wire [3:0]  probe1 .probe2({spi_en,spi_mosi,spi_miso,spi_busy}) // input wire [3:0]  probe2
);

5.SPI接口实战应用

给一款以SPI寄存器接口作为接口的芯片写一个SPI控制器大概需要三步,首先搞清楚芯片datasheet对于SPI接口的时序要求,每个芯片都可能有特殊的一面。然后,根据芯片要求设计程序完成仿真验证。最后,RTL设计,布局布线上板测试。

5.1时序要求

  1. 系统对于SPI读写发生的时隙做了规定,即上电之后经过一系列步骤等reset拉高之后的10us之后。

  2. 在使用PLL时钟的情况下,最大的SPI的时钟为10MHz,如下。为了精准的控制每一个上升沿和下降沿的数据,使用手动的方式生成这个时钟,用户时钟为50MHz,因此分频的时钟周期为20ns。
    在这里插入图片描述

  3. 根据datasheet提及的SPI时序,首先应该在按照上电时序要求的情况下把ss_n拉低。

  4. 手册要求,ss_n拉低之后需要保持一个spi的时钟周期才能给spi时钟。
    在这里插入图片描述

  5. 该芯片的SPI的时序是,第一个时钟边沿是上升沿,直接在第一个边沿就加载数据了。此处加载的是写入的9bit宽的地址值,注意此处是,MSB.
    在这里插入图片描述

  6. 注意读写之间的切换,与标准的SPI的时序不同,是在spiclk的下降沿抓取数据。

5.2仿真时序图

在这里插入图片描述

5.3代码设计

在这里插入图片描述
源码工程见文末
init模块完成系统对于上电时序的要求,上电后10us给时钟,时钟给到后的10us才开始复位拉高,控制SPI Upload在reset 10us之后开始;
②形成四个模块,各司其职。spi_ctrl模块控制读写寄存器的顺序以满足配置顺序要求;LUT模块将每个寄存器的将要写入的内容提前编辑好,配合ctrl完成读写配置;spi_driver模块根据ctrl模块的读写命令指示和lut的寄存器地址和写入数据驱动spi接口写入数据;top模块将三个子模块例化保持与design_top的通信。
③当开始spi upload后,spi_ctrl模块将按照预先编辑好的查找表,按顺序写入寄存器,其中需要注意有一个环节要读时钟管理寄存器的状态,状态正常后才能继续写,这点尤为重要。

6.传送门

  • 我的主页
  • SPI实战代码
  • FPGA通信接口专栏汇总导航
END

🔈文章原创,首发于CSDN论坛,我的主页。
🔈欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🔈欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/311729.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多模态之ALBEF—先对齐后融合,利用动量蒸馏学习视觉语言模型表征,学习细节理解与论文详细阅读:Align before Fuse

Align before Fuse: Vision and Language Representation Learning with Momentum Distillation &#xff08;ALBEF&#xff09;在融合之前对齐&#xff1a;利用动量蒸馏进行视觉与语言表示学习 Paper: arxiv.org/pdf/2107.07651.pdf Github: https://github.com/salesforce/…

NineData正式将SQL开发正式升级为数据库DevOps

NineData SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;时至今日已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能。 为了让企业…

Vue3 + Element-Plus 使用 Table 预览图片发生元素遮挡

Vue3 Element-Plus 使用 Table 预览图片发生元素遮挡 问题代码问题重现解决方法最终效果 问题代码 <el-table-column label"视频" align"center"><template #default"scope" style"display: flex;"><div style"…

Prime (2021): 2

前言 这个靶机有亿点难,收获很多。打靶的时候&#xff0c;前面很顺&#xff0c;到创建ssh公钥之后就一点不会了。 1 01 arp扫描&#xff0c;发现有一个130&#xff0c;再查看端口 有22&#xff0c;80&#xff0c;129&#xff0c;445&#xff0c;10123 dirb扫描目录 这…

【Git】安装 Git

文章目录 1. CentOS 下安装2. Ubuntu 下安装 Git 是开放源代码的代码托管工具&#xff0c;最早是在 Linux 下开发的。开始也只能应用于 Linux 平台&#xff0c;后面慢慢的被移植到 Windows 下。现在&#xff0c;Git 可以在 Linux、Unix、Mac 和 Windows 这几大平台上正常运行了…

在Qt中如何简单设计一个文件和图像浏览器

文本浏览器 设计一个文本浏览器程序&#xff0c;可以打开、显示 txt、html等文件。 1.在Qt Designer中设计一个菜单其中包含打开和退出选项&#xff1a; 2. 在 QMainWindow 构造函数中把 textBrower 设为主窗口的中心部件&#xff0c;这样整个窗口就成了包含 textBrower 的单文…

Samtec应用分享 | 汽车应用中的视觉系统

【前言】 视觉系统在未来的汽车设计中扮演着关键的角色。 在过去&#xff0c;一直是由驾驶员掌握和应对道路上的危险&#xff0c;但现代车辆在保障驾驶安全方面发挥着前所未有的作用。 视觉系统&#xff0c;无论是可见光摄像头还是先进的探测系统&#xff0c;如激光雷达&…

解读科技智慧公厕改变生活的革命性创新之路

公共厕所&#xff0c;作为城市基础设施的一部分&#xff0c;一直以来都备受人们诟病。脏乱差、设施老旧、管理混乱&#xff0c;成为公共厕所长期存在的问题。然而&#xff0c;随着科技的不断进步&#xff0c;智慧公厕应运而生&#xff0c;为解决公厕难题&#xff0c;智慧公厕源…

CentOS 7开机启动过程,引导和服务,密码的修改

开机启动过程&#xff1a; 引导过程&#xff1a;1.开机自检(BIOS)->2.MBR引导->GRUB菜单->加载内核kernel->systemd进程初始化 程序&#xff1a;执行特定任务的一串代码&#xff0c;静态&#xff0c;存在硬盘中。 进程&#xff1a;运行中的程序叫进程&#xff0…

分类损失函数与评估指标

目录 1 评估指标 1.1 准确率 1.2 精确率 1.3 召回率 1.4 F1 score 1.5 ROC曲线 1.6 AUC 1.7 PRC曲线的优势 2 损失函数 1. 负对数似然损失 2. 交叉熵损失 3. 指数损失 3 分类问题为什么用交叉熵损失不用 MSE 损失 1 评估指标 混淆矩阵 TP(True Positive) ---- 正…

AUTOCAD输出或打印PDF文件时,如何将图形居中且布满图纸?

AUTOCAD输出或打印PDF文件时,如何将图形居中且布满图纸? 如下图所示,我们打开一份DWG格式的图纸文件,然后点击上方的“打印“图标, 如下图所示, 打印机/绘图仪这里选择“DWG To PDF“; 图纸尺寸:这里以普通的A4纸为例进行说明; 打印比例选择“布满图纸“; 打印偏移…

【微信小程序之分包】

微信小程序之分包 什么是分包分包的好处分包前的结构图分包后的结构图分包的加载规则分包的体积限制使用分包打包原则引用原则独立分包独立分包的配置方法独立分包的引用原则分包预下载配置分包的预下载分包预下载限制 什么是分包 分包指的是把一个完整小程序项目&#xff0c;…

公园高速公路景区校园IP网络广播音柱SIP音柱

公园高速公路景区校园IP网络广播音柱SIP音柱 适用于学校、车站、教堂、工厂、仓库、公园停车场及露天市场高速公路等场所播放录制语音文件或背景音乐节目&#xff0c;专业一体化音箱设计&#xff0c;高强度防水设计&#xff0c;符合IP54防护等认证&#xff0c;数字化产品&…

酷开系统丨酷开科技打造P9系列智能投影,让智能化更进一步

近些年&#xff0c;随着科技的进步&#xff0c;家用投影仪已经成为家庭娱乐中不可或缺的一部分。尤其对年轻人来说&#xff0c;他们更喜欢在巨幕上看电影、玩游戏或听歌唱歌&#xff0c;投影仪在巨幕上的光影效果确实能带来更好的沉浸感体验&#xff0c;但这也是需要强大的系统…

论文略读:SWE-bench: Can Language Models Resolve Real-world Github Issues?

iclr 2024 oral reviewer评分 5668 现有的语言模型&#xff08;LMs&#xff09;的基准测试已经饱和&#xff0c;无法捕捉到最先进的语言模型能做什么和不能做什么的前沿。 ——>要具有挑战性的基准测试论文引入了SWE-bench 在现实软件工程环境中评估语言模型的基准测试 ​​…

word文件的创建时间和修改时间可以更改吗?答案是肯定的 文件属性修改的方法

一&#xff0c;引言 在日常生活和工作中&#xff0c;我们经常需要处理各种Word文件。有时&#xff0c;由于某些原因&#xff0c;我们可能需要更改Word文件的创建时间和修改时间。虽然这听起来可能有些复杂&#xff0c;但实际上&#xff0c;通过一些简单的方法和工具&#xff0…

数据库语言实战(三)

删除操作 本篇文章重点在于SQL中的各种删除操作 题目一 删除表中的学号不全是数字的那些错误数据&#xff0c;学号应该是数字组成&#xff0c;不能够包含字母空格等非数字字符。方法之一&#xff1a;用substr函数&#xff0c;例如Substr(sid,1,1)返回学号的第一位&#xff0…

java版数字藏品深色UI仿鲸探数藏盲盒合成短视频卡牌模式支持高并发

Java版数字藏品深色UI仿鲸探数藏盲盒合成短视频卡牌模式支持高并发&#xff0c;是一种结合了Java技术、深色用户界面&#xff08;UI&#xff09;设计、数字藏品概念、盲盒合成玩法以及短视频卡牌模式的综合性应用。该模式旨在为用户提供一种新颖、有趣的数字藏品体验&#xff0…

电脑怎么设置静态ip地址

在互联网连接中&#xff0c;IP地址扮演着至关重要的角色。它不仅是设备在网络世界中的唯一标识&#xff0c;还决定了设备如何与其他计算机通信。静态IP地址是一种固定不变的IP配置方式&#xff0c;与动态IP地址相比&#xff0c;它更加稳定&#xff0c;适用于需要长期、稳定网络…

Mysql的事务隔离级别以及事务的四大特性。

MySQL 的事务隔离级别是数据库管理系统中的一个重要概念&#xff0c;它决定了事务如何隔离和影响其他并发事务。MySQL 支持四种事务隔离级别&#xff0c;分别是&#xff1a;读未提交&#xff08;READ UNCOMMITTED&#xff09;、读已提交&#xff08;READ COMMITTED&#xff09;…