D2--FPGA SPI接口通信2022-08-03

article/2025/8/23 7:55:22

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有四种数据传输的时序模式,这是有设备的属性的决定的,用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;
endvio_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
);


http://chatgpt.dhexx.cn/article/ZKPLhh8I.shtml

相关文章

[SPI]SPI接口简介

SPI接口简介 前言&#xff1a;串行外设接口(SPI)是微控制器和外围IC&#xff08;如传感器、ADC、DAC、移位寄存器、SRAM等&#xff09;之间使用较广泛的接口之一。本文先简要说明SPI接口&#xff0c;然后介绍ADI公司支持SPI的模拟开关与多路转换器&#xff0c;以及它们如何帮助…

计算机串口接spi,SPI串口模块-SPI接口详细介绍

SPI串口模块-SPI接口详细介绍 1. SPI串口模块-概述 SPI = Serial Peripheral Interface,是串行外围设备接口,是一种高速,全双工,同步的通信总线。常规只占用四根线,节约了芯片管脚,PCB的布局省空间。现在越来越多的芯片集成了这种通信协议,常见的有EEPROM、FLASH、AD转换…

SPI接口介绍

SPI接口的全称是”Serial Peripheral Interface”&#xff0c;即串行外围接口。SPI接口主要应用在EEPROM、FLASH、实时时钟、AD转换器&#xff0c;还有数字信号处理器和数字信号解码器之间。SPI接口是在CPU和外围低速器件之间进行同步串行数据传输&#xff0c;在主器件的移位脉…

SPI接口协议的学习1

SPI接口是一种同步串行总线&#xff08;Serial Peripheral Interface&#xff09;。 四线SPI接口连线图&#xff1a; CS为片选脚&#xff0c;用于选中从机。 SCLK为时钟脚&#xff0c;用于数据传输时提供时钟信号。 MOSI为主output&#xff0c;从input&#xff0c;即主机发送…

SPI接口详细介绍

概述 SPI Serial Peripheral Interface&#xff0c;是串行外围设备接口&#xff0c;是一种高速&#xff0c;全双工&#xff0c;同步的通信总线。常规只占用四根线&#xff0c;节约了芯片管脚&#xff0c;PCB的布局省空间。现在越来越多的芯片集成了这种通信协议&#xff0c;常…

软件模拟SPI接口程序代码

目录 SPI协议简介 SPI接口介绍 SPI接口连接图 SPI数据传输方向 SPI传输模式 模拟SPI程序 SPI协议简介 SPI的通信原理很简单&#xff0c;一般主从方式工作&#xff0c;这种模式通常有一个主设备和一个或者多个从设备&#xff0c;通常采用的是4根线&#xff0c;它们是MISO&…

SPI接口及驱动

1. 简介 SPI接口是Motorola 首先提出的全双工三线同步串行外围接口&#xff0c;采用主从模式&#xff08;Master Slave&#xff09;架构。支持多slave模式应用&#xff0c;一般仅支持单Master。时钟由Master控制&#xff0c;在时钟移位脉冲下&#xff0c;数据按位传输&#xf…

SPI 接口

SPI 接口的全称是“Serial Peripheral Interface”意为串行外围接口&#xff0c;是 Motorola 首先在其 MC68HCxx 系列处理器上定义的。SPI 接口主要应用于 EEPROM、FLASH、实时时钟、AD转换器&#xff0c;还有数字信号处理器和数字信号解码器之间。 SPI 接口是在 CPU 和外围低…

ESP32 SPI 接口的应用

总体介绍 1. ESP32 共有 4 个 SPI 控制器 SPI0、SPI1、SPI2、SPI3&#xff0c;用于连接支持 SPI 协议的设备。 SPI0 控制器作为 cache 访问外部存储单元接口使用;SPI1 作为主机使用;SPI2 和 SPI3 控制器既可作为主机使用又可作为从机使用。作主机使用时&#xff0c;每个 SPI 控…

SPI接口简介-Piyu Dhaker

SPI接口简介 作者&#xff1a; Piyu Dhaker 串行外设接口(SPI)是微控制器和外围IC&#xff08;如传感器、ADC、DAC、移位寄存器、SRAM等&#xff09;之间使用最广泛的接口之一。本文先简要说明SPI接口&#xff0c;然后介绍ADI公司支持SPI的模拟开关与多路转换器&#xff0c;以…

弄懂SPI接口

SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是Motorola公司提出的一种同步串行数据传输标准&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;在很多器件中被广泛应用。 SPI相关缩写 SS: Slave Select&…

SPI接口

SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是Motorola公司提出的一种同步串行数据传输标准&#xff0c;在很多器件中被广泛应用。 1. 接口 SPI接口经常被称为4线串行总线&#xff0c;SPI协议是主从模式&#xff1a;从机不主动发起访问&…

SPI接口简介

串行外设接口(SPI)是微控制器和外围IC&#xff08;如传感器、ADC、DAC、移位寄存器、SRAM等&#xff09;之间使用最广泛的接口之一。本文先简要说明SPI接口&#xff0c;然后介绍ADI公司支持SPI的模拟开关与多路转换器&#xff0c;以及它们如何帮助减少系统电路板设计中的数字GP…

SPI接口详解

一、SPI接口简介 SPI 是英语Serial Peripheral interface的缩写&#xff0c;顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX系列处理器上定义的。 SPI&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用…

【科普贴】SPI接口详解

一、SPI接口简介 SPI接口是一种同步串行总线&#xff08;Serial Peripheral Interface&#xff09;多用于Flash存储器&#xff08;如NOR Flash&Nand Flash&#xff09;&#xff0c;ADC、LCD控制器等外围器件的通讯接口。大大增强了处理器的外设扩展能力。 SPI接口缩写 SSE…

第四章 - 程序计数器

文章目录 1.PC 寄存器介绍2.PC 寄存器的作用3.代码示例4.两个常见面试题5.CPU时间片 官网文档 1.PC 寄存器介绍 JVM中的程序计数寄存器&#xff08;Program Counter Register&#xff09;&#xff0c;Register的命名源于CPU的寄存器&#xff0c;寄存器存储指令相关的现场信息。…

运行时数据区 - 程序计数器

① 介绍 JVM中的程序计数寄存器(Program Counter Register)中&#xff0c;Register的命名源于CPU的寄存器&#xff0c;寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。 PC寄存器用来存储指向下一条指令的地址(即将要执行的指令代码)&#xff0c;由执行…

操作系统-程序计数器

查考资料&#xff1a;https://blog.csdn.net/xxb2008/article/details/42145649 程序计数器是用于存放下一条指令所在单元的地址的地方。 冯 诺伊曼计算机体系结构的主要内容之一就是“程序预存储&#xff0c;计算机自动执行”&#xff01; 处理器要执行的程序&#xff08;指…

04-程序计数器(PC计数器)

程序计数器 介绍 JVM中的程序计数寄存器&#xff08;Program Counter Register&#xff09;中&#xff0c;Register的命名源于CPU的寄存器&#xff0c;寄存器存储指令相关的现场信息。CPU只有把数据装载到寄存器才能够运行。 这里&#xff0c;并非是广义上所指的物理寄存器&…

三、程序计数器(PC寄存器)

文章目录 1.PC Register 介绍介绍作用 2.举例说明3.两个常见问题使用PC寄存器存储字节码指令的地址有什么用&#xff1f;PC寄存器为什么会被设定为线程私有的&#xff1f; 1.PC Register 介绍 介绍 JVM中的程序计时器&#xff08;Program Counter Register&#xff09;中&…