SPI 总线协议

1、协议介绍

  SPI,是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。

  SPI,是一种高速的,全双工,同步的通信总线。主节点或子节点的数据在时钟上升沿或下降沿同步。主节点和子节点可以同时传输数据。SPI 接口可以是 3 线或 4 线。本文重点介绍流行的 4 线 SPI 接口

  串行外设接口 (SPI) 是微控制器与外设 IC(如传感器、ADC、DAC、移位寄存器、SRAM 等)之间使用最广泛的接口之一。


在这里插入图片描述

4 线 SPI 设备有四种信号:

  • 时钟(SPI CLK、SCLK)
  • 片选(CS)
  • 主节点输出,子节点输入 (MOSI)
  • 主节点输入,子节点输出 (MISO)

  产生时钟信号的设备称为主设备。主节点和子节点之间传输的数据与主节点产生的时钟同步。与 I2C 接口相比,SPI 设备支持的时钟频率要高得多(时钟频率和传输速度有着直接的关系)。用户应查阅产品数据手册以了解 SPI 接口的时钟频率规格。

  SPI 接口只能有一个主节点,可以有一个或多个子节点

  主节点的片选信号用于选择子节点。这通常是低电平有效信号,拉高可断开子节点与 SPI 总线的连接。当使用多个子节点时,主节点需要为每个子节点提供单独的片选信号。在本文中,片选信号始终是低电平有效信号。

  MOSI 和 MISO 是数据线,MOSI 将数据从主节点传输到子节点,MISO 将数据从子节点传输到主节点。

下表总结了 SPI 的关键特性:

特性规格
导线4
最大速度SPI 传输速度没有协议的限制,但会受硬件设计的影响。可能是 10MHz、50MHz、100MHz 等
同步或异步?同步
串行或并行?串行
最大主器件数1
最大节点数无限制

2、数据传输

  要开始 SPI 通信,主设备必须发送时钟信号并通过启用 CS 信号选择子节点。

主机没有数据传输(数据发送)的情况下,通常是没有 CLK 信号的

  通常,芯片选择是低电平有效信号;因此,主设备必须在此信号上发送逻辑 0 来选择子节点。SPI 是一个全双工接口;主节点和子节点可以分别通过 MOSI 和 MISO 线路同时发送数据。在 SPI 通信期间,数据同时传输和接收。串行时钟沿同步数据的移位和采样。

  SPI 接口为用户提供了灵活性,可以选择时钟的上升沿或下降沿来采样和/或发送数据。请参阅设备数据表以确定使用 SPI 接口传输的数据位数。

2.1 时钟极性

  极性,会直接影响 SPI CLK 总线空闲时的时钟信号是高电平还是低电平。

  • CPOL = 1:表示空闲时是高电平
  • CPOL = 0:表示空闲时是低电平

  当 CPOL 时钟极性控制位被拉低时,它会使 SCK 管脚产生一个稳定的低电平。如果 CPOL 时钟极性控制为被拉高,当没有数据传输时,它会使 CLK 管脚产生一个稳定的高电平。即确定 SCK 在不传输数据时,是默认高电平或者默认低电平

2.2 时钟相位

  一个时钟周期会有 2 个跳变沿。而相位,直接决定 SPI CLK 总线从那个跳变沿开始采样数据。

  • CPHA = 0:表示从第一个跳变沿开始采样
  • CPHA = 1:表示从第二个跳变沿开始采样

    在这里插入图片描述
SPI modeCPOLCPHA
000
101
210
311

可以参考 W25Q64FW 中使用 0x9f 命令读 ID 的传输过程示意图:
在这里插入图片描述

2.3 数据交换

  SPI 设备间的数据传输之所以又被称为数据交换,是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 “发送者(Transmitter)” 或者 “接收者(Receiver)”。

  一个 Slave 设备要想能够接收到 Master 发过来的控制信号,必须在此之前能够被 Master 设备进行访问 (Access)。所以,Master 设备必须首先通过 SS/CS pin 对 Slave 设备进行片选, 把想要访问的 Slave 设备选上。 在数据传输的过程中,每次接收到的数据必须在下一次数据传输之前被采样。如果之前接收到的数据没有被读取,那么这些已经接收完成的数据将有可能会被丢弃,导致 SPI 物理模块最终失效。因此,在程序中一般都会在 SPI 传输完数据后,去读取 SPI 设备里的数据, 即使这些数据(Dummy Data)在我们的程序里是无用的(虽然发送后紧接着的读取是无意义的,但仍然需要从寄存器中读出来)。

  • 如果不对接收进行读取操作可能会导致溢出,将使以后发送出的数据全部无效
  • 在每个 SPI 时钟周期内,都会发生全双工数据传输
  • SPI 只有主模式和从模式之分(提供时钟的为主设备 Master,接收时钟的设备为从设备 Slave),没有读和写的说法,因为实质上每次 SPI 是主从设备在交换数据。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据
  • 发一个字节任意值数据是为了在 CLK 总线上产生时钟,给从机的 SPI 信号提供时钟用的,从机 SPI 不会自己产生 CLK 信号的

在 CS 片选有效的情况下才会有数据传输,有一种特殊情况,如果 CS 片选无效,设备硬件 FIFO 中的数据都会丢失。如果两次写操作中间 CS 一直有效,设备硬件 FIFO 中的数据不会丢失。这里要注意


  特别要注意的是,关于 Transfer Mode,是一个很奇怪的东西。这个玩意违背了“发送就一定需要接收”的逻辑,即上面所说“数据交换”的逻辑在一定程度上是问题的。这也给 SPI 总线驱动、包括 SPI 设备驱动带来了很多变数。所以,写设备驱动前,最好对总线驱动的发送与接收过程有个了解。

例如 rk3568 SPI 控制器中的 SPI_CTRLR0 寄存器:

在这里插入图片描述

  • Transmit & Receive(就是我们上面提到,只要有发送,就一定会有接收,即使是脏数据,也需要读出来):

In transmit-and-receive mode,both transmit and receive data are valid. The transfer continues until the transmit FIFO is empty. Data received from the external device are stored into the receive FIFO memory, where it can be accessed by the host processor

  • Transmit Only:

In transmit-only mode,data received from the external device is not valid and is not stored in the receive FIFO memory; it is overwritten on the next transfer

  • Receive Only:

In receive-only mode,transmitted data are not valid. After the first write to the transmit FIFO,the same word is retransmitted for the duration of the transfer

  • EEPROM Read:

In eeprom-read mode, receive data is not valid while control data is being transmitted. When all control data is sent to the EEPROM, receive data becomes valid and transmit data becomes invalid. All data in the transmit FIFO is considered control data in this mode. This transfer mode is only valid when the DW_apb_ssi is configured as a master device


还有一个 SPI_CTRLR1 寄存器:
在这里插入图片描述
  这个只针对于 Receive Only 模式和 EEPROM Read 模式有效。该寄存器含义是指定 SPI 控制器一次连续接收的数据帧数量。通常情况下,是需要接收的帧数 -1 。

例如 EEPROM Read 模式:发送数据用于传输命令码和地址到 EEPROM 设备,一般需要 3 个数据帧(8-bit 操作码,8-bit 高位地址,8-bit 低位地址)。在操作码和地址传输的过程中,控制器不会从串行总线上接收数据。当发送 FIFO 中的条目发送完毕,接收数据才开始被采样,采样的数据帧数是 NDF+1(也就是上面的 ndm 寄存器值 + 1)。

2.4 关于帧长度

  在发起一个 SPI 传输前,通常还需要设置本次传输的帧长度( Data Frame Size ) ,通常是 8 或 16 位。

struct spi_message {......unsigned		frame_length;......
};

  SPI 协议本身并没有帧长度(Frame Length)的固定概念,因为 SPI 是一种流式(streaming)传输协议,它是一个基于主从模式的时钟同步串行通信协议,只关心 时钟脉冲(SCK)和数据位(MOSI、MISO) 的同步,并不会主动分割数据。然而,在具体的 SPI 控制器、驱动程序或某些应用场景下,帧长度的概念被引入。这里要注意。

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

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

相关文章

Qt msvc程序运行

第一个Qt msvc程序 我们一般用qt msvc来编译程序&#xff0c;就是用webview。 第一个Qt msvc webview程序实现如下&#xff1a; 运行结果&#xff1a; 标注&#xff1a; QT版本大于6.0的时候才能用<Webview>模块。 QT版本在大于5.2版本&#xff0c;引入了Webengine模…

Java设计模式建模语言面向对象设计原则

设计模式 设计模式的概念 设计模式最初用于建筑领域的设计中。 软件的设计模式&#xff0c;又称设计模式&#xff0c;是一套被反复使用&#xff0c;多数人知道的&#xff0c;经过分类编目的&#xff0c;代码设计经验的总结。 它描述了在软件设计过程中的一些不断重复发生的…

搜广推校招面经五十四

美团推荐算法 一、手撕Transformer的位置编码 1.1. 位置编码的作用 Transformer 模型没有显式的序列信息&#xff08;如 RNN 的循环结构&#xff09;&#xff0c;因此需要通过位置编码&#xff08;Positional Encoding&#xff09;为输入序列中的每个位置添加位置信息。位置…

深入解析 SQL 事务:确保数据一致性的关键

SQL 事务 什么是 SQL 事务&#xff1f;事务的 ACID 特性原子性&#xff08;Atomicity&#xff09;:示例&#xff1a; 一致性&#xff08;Consistency&#xff09;:示例&#xff1a; 隔离性&#xff08;Isolation&#xff09;:持久性&#xff08;Durability&#xff09;:示例&am…

【软考-架构】11.3、设计模式-新

✨资料&文章更新✨ GitHub地址&#xff1a;https://github.com/tyronczt/system_architect 文章目录 项目中的应用设计模式创建型设计模式结构型设计模式行为型设计模式 &#x1f4af;考试真题题外话 项目中的应用 在实际项目中&#xff0c;我应用过多种设计模式来解决不同…

观察者模式详解:用 Qt 信号与槽机制深入理解

引言 你是否曾遇到这样的需求&#xff1a;一个对象的状态发生变化后&#xff0c;希望通知其他对象进行相应的更新&#xff1f;比如&#xff1a; 新闻订阅系统&#xff1a;当新闻发布后&#xff0c;所有订阅者都会收到通知。股票行情推送&#xff1a;股价变化时&#xff0c;所…

流量分析实践

下载附件使用wireshark打开&#xff0c;发现数据包非常多&#xff0c;一共有1万多条数据&#xff0c;我们点击分析来看一下协议分级 然后我们再来看一下会话&#xff0c;看有哪些ip地址&#xff0c; 我们通过会话结合大部分的流量发现&#xff0c;172.17.0.1一直在请求172.17.0…

新手村:混淆矩阵

新手村&#xff1a;混淆矩阵 一、前置条件 知识点要求学习资源分类模型基础理解分类任务&#xff08;如二分类、多分类&#xff09;和常见分类算法&#xff08;如逻辑回归、决策树&#xff09;。《Hands-On Machine Learning with Scikit-Learn》Python基础熟悉变量、循环、函…

MYSQL库的操作

目录 一、创建数据库 二、字符集和校验规则 1、查看系统默认字符集以及校验规则 2、查看系统支持的所有字符集以及字符集校验规则 3、指定字符集以及校验规则来创建数据库 4、校验规则对数据库的影响 三、操纵数据库 1、查看数据库 2、修改数据库 3、删除数据库 4、数…

Next App Router(下)

五、loading 新增 app/loading.tsx 页面 const Loading () > {return <div>Loading...</div>; }; export default Loading;修改 app/page.tsx页面 /** 假设为一个获取数字的api */ const fetch_getNumber async (): Promise<number> > {return ne…

【JAVA】】深入浅出了解cookie、session、jwt

文章目录 前言一、首先了解http的cookie是什么&#xff1f;Cookie 属性及其含义1. NameValue2. Expires3. Max-Age4. Domain5. Path6. Secure7. HttpOnly8. SameSite示例 Cookie 分类1. Session Cookies2. Persistent Cookies3. First-Party Cookies4. Third-Party Cookies 二、…

【css酷炫效果】纯CSS实现粒子旋转动画

【css酷炫效果】纯CSS实现粒子旋转动画 缘创作背景html结构css样式完整代码效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492008 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚看到csdn出活动了&…

C++Lambda表达式

Lambda表达式 什么是Lambda表达式 ​ C11的颁布让C丰富了起来&#xff0c;任何一本介绍C11的书籍&#xff0c;都不可能跳过这一个点——Lambda表达式。人们经常称Lambda表达式是一个语法糖&#xff0c;说明这是一个”没有没事&#xff0c;有了更好“的一种语法表达&#xff0…

每天五分钟深度学习框架pytorch:基于pytorch搭建循环神经网络RNN

本文重点 我们前面介绍了循环神经网络RNN,主要分析了它的维度信息,其实它的维度信息是最重要的,一旦我们把维度弄清楚了,一起就很简单了,本文我们正式的来学习一下,如何使用pytorch搭建循环神经网络RNN。 RNN的搭建 在pytorch中我们使用nn.RNN()就可以创建出RNN神经网络…

el-table树形表格合并相同的值

el-table树形表格合并相同的值 el-table树形表格合并相同的值让Ai进行优化后的代码 el-table树形表格合并相同的值 <style lang"scss" scoped> .tableBox {/deep/ &.el-table th:first-child,/deep/ &.el-table td:first-child {padding-left: 0;} } …

2025年3月19日 十二生肖 今日运势

小运播报&#xff1a;2025年3月19日&#xff0c;星期三&#xff0c;农历二月二十 &#xff08;乙巳年己卯月丁亥日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;兔、虎、羊 需要注意&#xff1a;猪、猴、蛇 喜神方位&#xff1a;正南方 财神方位&#xff1a;…

Git——分布式版本控制工具使用教程

本文主要介绍两种版本控制工具——SVN和Git的概念&#xff0c;接着会讲到Git的安装&#xff0c;Git常用的命令&#xff0c;以及怎么在Vscode中使用Git。帮助新手小白快速上手Git。 1. SVN和Git介绍 1.1 SVN 集中式版本控制工具&#xff0c;版本库是集中存放在中央服务器的&am…

QT5.15.2加载pdf为QGraphicsScene的背景

5.15.2使用pdf 必须要安装QT源码&#xff0c;可以看到编译器lib目录已经有pdf相关的lib文件&#xff0c;d是debug 1.找到源码目录&#xff1a;D:\soft\QT\5.15.2\Src\qtwebengine\include 复制这两个文件夹到编译器的包含目录中:D:\soft\QT\5.15.2\msvc2019_64\include 2.找…

【H2O2 | 软件开发】前端深拷贝的实现

目录 前言 开篇语 准备工作 正文 概述 JSON方法 递归 其他 结束语 前言 开篇语 本系列为短篇&#xff0c;每次讲述少量知识点&#xff0c;无需一次性灌输太多的新知识点。该主题文章主要是围绕前端、全栈开发相关面试常见问题撰写的&#xff0c;希望对诸位有所帮助。…

Docker - 切换源 (Linux / macOS)

文章目录 Linux 系统macOS 系统 Linux 系统 修改配置文件&#xff1a;/etc/docker/daemon.json "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn","https://hub-mirror.c.163.com"]验证是否修改成功&#xff1a; docker info重启 …