SPI 通信-stm32入门

本节我们将继续学习下一个通信协议 SPI,SPI 通信和我们刚学完的 I2C 通信差不多。两个协议的设计目的都一样,都是实现主控芯片和各种外挂芯片之间的数据交流,有了数据交流的能力,我们主控芯片就可以挂载并操纵各式各样的外部芯片,来实现一个功能更加强大的控制系统。那本节 SPI 通信的安排和上一节 I2C 的也是一样,我们先学习 SPI 协议的软硬件规定,先用软件模拟的 SPI,实现读写 W25Q64 Flash 存储器;之后,我们再学习 STM32 中的 SPI 外设,再用硬件 SPI 实现同样的功能。

W25Q64 是一个 Flash 存储器芯片,它内部可以存储 8 M 字节的数据,并且是掉电不丢失的。如果你之后的项目中,需要存储大量的数据,就可以考虑一下外挂这个芯片来实现。

那在这里,我们用 4 根 SPI 通信线把 W25Q64 和 STM32 连接在一起,STM32 操作引脚电平,实现 SPI 通信的时序,进而实现读写存储器芯片的目的。

那在 OLED 上,我们可以看到程序测试的现象:第一行,显示的是 ID 号,MID 是厂商 ID,读出来是 0xEF,DID 是设备 ID,读出来是 0x4017,这些 ID 号都是固定的数值,在手册里有写,我们用 SPI 读写 ID 号,就可以进行最简单的测试了,如果读取 ID 号和手册里 一样,说明 SPI 通信基本没问题。之后,既然是存储器芯片,我们肯定就是写几个数据,再读出来,看看对不对了,这里第二行,W,写的内容是 4 个字节:0x01,02,03,04。然后第三行,R,就是读到的内容了,显示出来,可以看到也是 0x01,02,03,04,读出来和写入的一样,这说明读写存储器芯片没问题。当然更进一步的测试,比如读写更多的数据、写入的数据是不是掉电不丢失,这些我们之后写程序的时候再来验证。程序现象就看到这里。

1. SPI 通信简介

1.1 SPI 的基本功能

SPI(Serial Peripheral Interface,串行外设接口)是由Motorola公司开发的一种通用数据总线

和 I2C 一样,它们都是通用的数据总线。同时,它们也都是用于主控和外挂芯片之间的通信,应用领域非常相似。当然,I2C 和 SPI,两者是各有优势和劣势的。在某些芯片呢,我们用 I2C 更好,在另一些芯片呢,我们用 SPI 更好。
上一节我们学习 I2C 的时候,可以发现 I2C,无论是硬件电路,还是软件时序,设计的都是相对比较复杂的。硬件上,我们要配置为开漏外加上拉的模式,软件上,我们有很多功能和要求,比如,一根通信线兼顾数据收发,应答位的收发、寻址机制的设计等等,最终,通过这么多的设计,就使得 I2C 通信的性价比非常高,I2C 可以在消耗最低硬件资源的情况下,实现最多的功能。在硬件上,无论挂载多少个设备,都只需要两根通信线,在软件上,数据双向通信、应答位,都可以实现。如果把通信协议比作是一个人的话,那 I2C 就属于精打细算、思维灵活这类型的人,既要实现硬件上最少的通信线,又要实现软件上最多的功能。最终,I2C 通过精心的设计,也确实实现了这么多功能,可以说是非常的优雅。当然,在这些优雅之中,也隐藏了一个缺点,就是我们上节说的,由于 I2C 开漏外加上拉电阻的电路结构,使得通信线高电平的驱动能力比较弱,这就会导致,通信线由低电平变到高电平的时候,这个上升沿耗时比较长,这会限制 I2C 的最大通信速度,所以,I2C 的标准模式,只有 100 KHz 的时钟频率,I2C 的快速模式,也只有 400 KHz,虽然 I2C 协议之后又通过改进电路的方式,设计出了高速模式,可以达到 3.4 MHz,但是高速模式目前普及程度不是很高。所以一般情况下,我们认为 I2C 的时钟速度最多就是 400 KHz,这个速度,相比较 SPI 而言,还是慢了很多,那了解完 I2C 的优势和缺点,我们就来看一下 SPI。
在学习之前,简单概括几点 SPI 相对于 I2C 的优缺点:
首先,SPI 传输更快,SPI 协议并没有严格规定最大传输速度,这个最大传输速度取决于芯片厂商的设计需求,比如说,我们这个 W25Q64 存储器芯片,手册里写的 SPI 时钟频率,最大可达 80 MHz,这比 STM32F1 的主频还要高。
其次,SPI 的设计比较简单粗暴,实现的功能没有 I2C 那么多,所以学习起来,SPI 还是比 I2C 简单很多的。
最后,SPI 的硬件开销比较大,通信线的个数比较多,并且通信过程中,经常会有资源浪费的现象,如果继续把通信协议比作一个人的话,那 SPI 就属于富家子弟、有钱任性这类型的人,SPI 说,我不在乎我花了多少钱,我只在乎我的任务有没有最简单、最快速的完成,这就是 SPI 的风格。
好,经过这么多的对比和铺垫,大家对 SPI 应该就有了一个第一印象了吧。

四根通信线:SCK(Serial Clock,串行时钟线)、MOSI(Master Output Slave Input,主机输出从机输入)、MISO(Master Input Slave Output,主机输入从机输出)、SS(Slave Select,从机选择)

这是 SPI 通信典型的引脚名称。当然在实际情况下,这些名称可能会有别的表述方式。比如,SCK,有的地方可能叫作 SCLK、CLK、CK;MOSI 和 MISO,有的地方可能直接叫作 DO(Data Output)和 DI(Data Input);SS,有的地方也可能叫作 NSS(Not Slave Select)、CS(Chip Select),这些不同的名称都是一个意思,大家了解一下。那这里,就以 SPI 官方文档的名称为准,统一都用这几个名词来表示。
那这四个引脚的意义和作用是什么呢?我们继续往后看

SPI 基本特性是:同步,全双工

首先既然是同步时序,肯定就得有时钟线了,所以 SCK 引脚,就是用来提供时钟信号的,数据位的输出和输入,都是在 SCK 的上升沿或下降沿进行的,这样,数据位的收发时刻就可以明确的确定。并且,同步时序,时钟快点慢点,或者中途暂停一会儿,都是没问题的,这就是同步时序的好处。那对照 I2C 总线,这个 SCK,就相当于 I2C 的 SCL,两者作用相同。
之后,SPI 是全双工的协议。全双工:就是数据发送和数据接收单独各占一条线,发送用发送的线路,接收用接收的线路,两者互不影响。所以这里,MOSI 和 MISO,就是分别用于发送和接收的两条线路,MOSI 线,是主机输出从机输入,如果是主机接在这条线上,那就是 MO,主机输出;如果是从机接在这条线上,那就是 SI,从机输入,意思就是一条通信线,如果主机接在上面配置为输出,那从机肯定得配置为输入,才能接收主机的数据对吧。主机和从机不能同时配置为输出或输入,要不然就没法通信了。所以这条 MOSI,就是主机向从机发送数据的线路,那同理,下面这条 MISO,就是主机从从机接收数据的线路,这就是全双工通信的两根通信线,那这两根通信线,加在一起,就相当于 I2C 总线的 SDA,当然 I2C 是一根线兼具发送和接收,是半双工。这里 SPI 是一根发送、一根接收,是全双工。全双工的好处就是简单高效,输出线就一直输出,输入线就一直输入,数据流的方向不会改变,也不用担心发送和接收没协调好冲突了,但是坏处就是多了一根线,会有通信资源的浪费,这就是全双工。

支持总线挂载多设备(使用的是 一主多从 的模型)

SPI 仅支持一主多从,不支持多主机,这一点,SPI 从功能上,没有 I2C 强大。那 I2C,实现一主多从的方式是在起始条件之后,主机必须先发送一个字节进行寻址,用来指定我要跟哪个从机进行通信,所以 I2C 这里,要涉及分配地址和寻址的问题。但是 SPI 表示,你这太麻烦了,我直接大手一挥,再开辟一条通信线,专门用来指定我要跟哪个从机进行通信,所以,这条专门用来指定从机的通信线,就是这里的 SS,从机选择线。并且,这个 SS 可能不止一条,SPI 的主机表示,我有几个从机,我就开几条 SS,所有从机,一人一根,都别抢,我需要找你的时候,我就控制接到你那一根的 SS 线,给你低电平,就说明我要找你了;给你高电平,就说明我不跟你玩了,那这样一来,指定从机不就是动动手指就能完成的事了么,哪还需要什么分配地址,先发一个字节寻址的操作啊。那这就是 SPI 实现一主多从,指定从机的方式,好处就是方便,坏处就是得加钱(线)。

那最后这里,SPI,没有写应答机制的介绍,SPI 没有应答机制的设计。发送数据就发送,接收数据就接收,至于对面是不是存在,SPI 是不管的。

然后看一下下面的图片,这些都是采用了 SPI 通信的芯片和模块。
在这里插入图片描述
第一个图,就是我们本节使用的芯片,型号是 W25Q64,是一个 Flash 存储器,这个模块的引脚,可以看到和刚才说的并不一样。这里 CLK 就是 SCK,DI 和 DO 就是 MOSI 和 MISO。那 DI 到底是 MOSI 还是 MISO 呢,我们要看一下这个芯片的身份,显然,这个芯片接在 STM32 上,应该是从机的身份,所以这里的 DI,数据输入,就是从机的数据输入 SI,对应需要接在主机的 MO 上,所以这里的 DI 就是 MOSI,那另一个 DO,就是 MISO 了,一般在这种始终作为从机的设备上,可能会用 DI 和 DO 的简写。像 STM32 这种可以进行身份转换的设备,一般都会把 MOSI、MISO 的全程写完整,当然,即使它简写了,只要明确了它的身份,是主机还是从机,之后再辨别这两个引脚,应该就好判断了。那最后一个 CS 片选,其实就是 SS 从机选择了。

然后继续下一个模块,这个是利用 SPI 通信的 OLED 屏幕,上面的引脚也不是标准的名称,所以这个模块要查一下手册,在手册里有写的。

之后下一个,这个是一个 2.4 G 无线通信模块,芯片型号是 NRF24L01,这个芯片使用的就是 SPI 通信协议,要想使用这个芯片来进行无线通信,那就需要利用 SPI,来读写这个芯片。

然后最后一个图片,就是常见的 Micro SD 卡了,这个 SD 卡,官方的通信协议是 SDIO,但是它也是支持 SPI 协议的,我们可以利用 SPI,,对这个 SD 卡进行读写操作。

那到这里,我们这个 SPI 通信的大体介绍,就完成了。

接下来我们来看一下 SPI 的硬件和软件规定。

1.2 SPI 硬件规定

  • 所有SPI设备的SCK、MOSI、MISO分别连在一起
  • 主机另外引出多条SS控制线,分别接到各从机的SS引脚
  • 输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入

首先是硬件电路
在这里插入图片描述
这个图,就是 SPI 一个典型的应用电路。我们看一下

  1. 左边这里,是 SPI 主机,主导整个 SPI 总线。主机,一般都是控制器来作,比如 STM32,下面这里,SPI 从机 1、2、3,就是挂载在主机上的从设备了,比如存储器、显示屏、通信模块、传感器等等等等。
  2. 左边 SPI 主机实际上引出了 6 根通信线,因为有 3 个从机,所以 SS 线需要 3 根,再加 SCK、MOSI、MISO,就是 6 根通信线,当然 SPI 所有通信线都是单端信号,它们的高低电平都是相对 GND 的电压差。所以,单端信号,所有的设备还需要供电,这里 GND 的线没画出来,但是是必须要接的。然后如果从机没有独立供电的话,主机还需要再额外引出电源正极 VCC,给从机供电,这两根电源线 VCC 和 GND,也要注意接好。
  3. 然后我们看一下这几根通信线,首先,SCK,时钟线,时钟线完全由主机掌控,所以对于主机来说,时钟线为输出,对于所有从机来说,时钟线都为输入,这样主机的同步时钟,就能送到各个从机了。然后下一个,MOSI,主机输出从机输入,这里左边是主机,所以就对应 MO,主机输出,下面三个都是从机,所以就对应 SI,从机输入,数据传输方向是,主机通过 MOSI 输出,所有从机通过 MOSI 输入。接着下一个,MISO,主机输入从机输出,左边是主机,对应 MI,下面三个都是从机,对应 SO,数据传输方向是,三个从机通过 MISO 输出,主机通过 MISO 输出。

那到这里,SCK、MOSI、MISO 的连接方式我们就清楚了。这就是上面写的第一条,所有SPI设备的SCK、MOSI、MISO分别连在一起,就是上面图示的这样,每条线的数据传输方向,图中都用箭头标出来了,可以看一下,应该都挺明确的。

之后我们继续看,时钟和数据传输没问题了。最后要解决的就是从机的选择问题了,为了确定通信的目标,主机就要另外引出多条 SS 通信线,分别接到各从机的 SS 引脚,上面图中有 3 个从机,我们需要在主机另外引出 3 根 SS 选择线,分别接到每个从机的 SS 输入端。主机的 SS 线都是输出,从机的 SS 线都是输入,SS 线是低电平有效的,主机想指定谁,就把对应的 SS 输出线置低电平就行了。比如,主机初始化之后,所有的 SS 都输出高电平,这样就是谁也不指定。当主机需要和,比如从机 1,进行通信了,主机就把 SS1 线输出低电平,这样从机 1 就知道,主机在找我,然后主机在数据引脚进行的传输,就只有从机 1 会响应,其他从机的 SS 线是高电平,所以它们都会保持沉默。当主机和从机 1 通信完成之后,就会把 SS1 置回高电平,这样从机 1 就知道,主机结束了和我的通信。之后主机需要和从机 2 和从机 3 通信时,也是同理,需要找谁通信,就置谁的 SS 为低电平。当然同一时间,主机只能置一个 SS 为低电平,只能选中一个从机,否则,如果主机同时选中多个从机,就会导致数据冲突,这就是 SPI 实现选择从机的方式。不需要像 I2C 一样进行寻址,是不是挺简单的。

然后我们继续看下一条,输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入,这就是 SPI 引脚的配置。在上图里,输出引脚和输入引脚都用箭头标出来了,哪个是输出哪个是输入,应该很好判断。对于输出,我们配置推挽输出,推挽输出,高低电平具有很强的驱动能力,这将使得 SPI 引脚信号的下降沿,非常迅速,上升沿,也非常迅速,不像 I2C 那样,下降沿非常迅速,但是上升沿,就比较缓慢了。那得益于推挽输出的驱动能力,SPI 信号变化的快,那自然它就能达到更高的传输速度,一般 SPI 信号都能轻松达到 MHz 的速度级别。然后这里 I2C 并不是不想使用更快的推挽输出,而是 I2C 要实现半双工,经常要切换输入输出,另外 I2C 又要实现多主机的时钟同步和总线仲裁,这些功能,都不允许 I2C 使用推挽输出,要不然一不小心,就电源短路了,所以 I2C 选择了更多的功能,自然就要放弃更强的性能了。对于 SPI 来说,首先 SPI 不支持多主机,然后 SPI 又是全双工,SPI 的输出引脚始终是输出,输入引脚始终是输入,基本不会出现冲突,所以 SPI 可以大胆地使用推挽输出。不过当然,SPI 其实还是有一个冲突点的,就是图上的 MISO 引脚,在这个引脚上,可以看到主机一个是输入,但是三个从机全都是输出,如果三个从机都始终是推挽输出,势必会导致冲突。所以在 SPI 协议里,有一条规定,就是当从机的 SS 引脚为高电平,也就是从机未被选中时,它的 MISO 引脚,必须切换为高阻态,高阻态就相当于引脚断开,不输出任何电平,这样就可以防止,一条线有多个输出,而导致的电平冲突的问题了。在 SS 为低电平时,MISO 才允许变为推挽输出,这就是 SPI 对这个可能的冲突做出的规定,当然这个切换过程都是在从机里,我们一般都是写主机的程序,所以我们主机的程序中,并不需要关注这个问题。

好,那有关 SPI 的硬件电路,就介绍到这里。

接下来,我们来看一下移位示意图
在这里插入图片描述
这个移位示意图是 SPI 硬件电路设计的核心。只要你把这个移位示意图搞懂了,那无论是上面的硬件电路,还是我们等会学习的软件时序,理解起来都会更加轻松。我们看一下:

  1. SPI 的基本收发电路,就是使用了这样一个移位的模型

1.3 SPI 软件规定

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

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

相关文章

gpu版本的GNN的demo

1、当涉及到在GPU上运行图神经网络(GNN)时,通常使用深度学习框架,如PyTorch或TensorFlow。在这里,我将为您提供一个使用PyTorch Geometric库实现GNN的简单示例。 首先,确保您已经安装了PyTorch和PyTorch G…

第 375 场 LeetCode 周赛题解

A 统计已测试设备 模拟&#xff1a;记录当前已测试设备数量 class Solution { public:int countTestedDevices(vector<int> &batteryPercentages) {int res 0;int s 0;for (auto x: batteryPercentages) {if (x - s > 0) {res;s;}}return res;} };B 双模幂运算 …

【无线网络技术】——无线城域网(学习笔记)

&#x1f4d6; 前言&#xff1a;无线城域网&#xff08;WMAN&#xff09;是指在地域上覆盖城市及其郊区范围的分布节点之间传输信息的本地分配无线网络。能实现语音、数据、图像、多媒体、IP等多业务的接入服务。其覆盖范围的典型值为3~5km&#xff0c;点到点链路的覆盖可以高达…

少儿编程考级:激发孩子逻辑思维能力的关键

在当今信息化时代&#xff0c;少儿编程已经成为孩子们不可或缺的一项技能。而少儿编程考级&#xff0c;则是检验孩子们在这一技能上所取得的成就的重要途径。少儿编程考级不仅能够激发孩子们的逻辑思维能力&#xff0c;还能够提高他们的动手能力和创造力。6547网将详细介绍少儿…

电源模块测试系统测试LED电源项目的优势

LED电源测试是电源在设计、生产过程中的关键环节&#xff0c;也是确保LED照明产品可靠性和稳定性的重要步骤。LED电源测试一般包括电压、电流、效率、稳定性等。电源模块测试系统测试LED电源&#xff0c;实现自动化测试&#xff0c;保证测试结果的可靠性。 LED电源测试项目及方…

实现加盐加密方法以及MappedByteBuffer,RandomAccess

目录 自己实现 Spring Security MappedByteBuffer RandomAccess 加盐加密的实现 自己实现 传统MD5可通过彩虹表暴力破解&#xff0c; 加盐加密算法是一种常用的密码保护方法&#xff0c;它将一个随机字符串&#xff08;盐&#xff09;添加到原始密码中&#xff0c;然后再进…

力扣17. 电话号码的字母组合(java 回溯法)

Problem: 17. 电话号码的字母组合 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 题目给定一串数字&#xff0c;要求我们找出所有可能的字母组合&#xff0c;即我们可以穷举出所有可能的结果&#xff0c;而涉及到穷举我们自然可以想到利用回溯来解决问题&#xff0c…

无线且列窄图片如何转excel?

写此文原因&#xff1a;图片要转excel&#xff0c;这放以前&#xff0c;是不能实现的功能&#xff0c;但随着人工智能的蓬勃发展&#xff0c;人们已克服了这一难题&#xff0c;但是&#xff0c;我们知道&#xff0c;要将图片识别成excel&#xff0c;识别程序首先要先识别图片中…

如何在小米路由器4A千兆版刷入OpenWRT并通过内网穿透工具实现公网远程访问

文章目录 前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 前言 OpenWRT是一个高度模块化、高度自…

交易历史记录20231206 记录

昨日回顾&#xff1a; select top 10000 * from dbo.CODEINFO A left join dbo.全部&#xff21;股20231206010101 B ON A.CODE B.代码 left join dbo.全部&#xff21;股20231206CONF D on A.CODED.代码left join dbo.全部&#xff21;股20231206 G on A.CODEG.代码 left…

Kafka-快速实战

Kafka介绍 ChatGPT对于Apache Kafka的介绍&#xff1a; Apache Kafka是一个分布式流处理平台&#xff0c;最初由LinkedIn开发并于2011年开源。它主要用于解决大规模数据的实时流式处理和数据管道问题。 Kafka是一个分布式的发布-订阅消息系统&#xff0c;可以快速地处理高吞吐…

阿里云国际基于CentOS系统镜像快速部署Apache服务

阿里云轻量应用服务器提供了Windows Server系统镜像和主流的Linux系统镜像&#xff0c;您可以通过该类镜像创建纯净、安全、稳定的运行环境。本文以CentOS 7.6系统镜像为例&#xff0c;介绍如何快速配置Apache服务。 背景信息 注意&#xff0c;阿里云国际通过corebyt注册并充…

使用rawpy.imread读取.RAW格式数据和.dng格式数据(附代码)

.dng格式是一个更兼容、更高效的RAW格式。如果需要在不同软件之间交换RAW文件&#xff0c;或者需要在软件中进行大量编辑&#xff0c;那么.dng格式是一个不错的选择。 目录 一、 .dng格式数据和.RAW格式数据二、 .dng格式数据和.RAW格式数据区别三、安装rawpy包四、读取.dng格式…

Flask应用基础入门总结

【1】使用migrate方式进行数据库连接 使用migrate方式进行数据库连接需要在终端分别运行三行代码&#xff1a; #init&#xff08;运行一次即可&#xff09;&#xff08;此db为自己设置的连接数据库的对象,可以修改&#xff09; flask db init #&#xff08;将orm模型生成迁移…

从零开始搭建企业管理系统(四):集成 Knife4j

集成 Knife4j 前言Knife4j是什么集成 Knife4j引入 pom 依赖添加基础配置启动程序测试完善文档信息编写配置类修改 UserController修改 UserEntity修改 BaseEntity 文档效果图swagger 界面knife4j 界面 前言 前面一小节我们使用postman来进行接口的调试&#xff0c;如果接口一多…

游戏王的题解

目录 原题&#xff1a; 时间&#xff1a;1s 空间&#xff1a;256M 题目描述 输入格式 输出格式 样例输入 样例输出 题目大意&#xff1a; 主要思路&#xff1a; dp转移&#xff1a; dp初始化&#xff1a; 代码&#xff1a; 原题&#xff1a; 时间&#xff1a;1s …

springboot集成knife4j详细教程

使用原生的swagger作为接口文档&#xff0c;功能不够强大&#xff0c;并且默认的ui比较简陋&#xff0c;不符合大众审美。所以实际开发中推荐使用knife4j对swagger进行增强。knife4j的地址&#xff1a;https://gitee.com/xiaoym/knife4j 基本使用 想要使用knife4j非常简单&…

深入学习Redis:从入门到实战

Redis快速入门 1.初识Redis1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结 1.2.认识Redis1.3.安装Redis1.3.1.依赖库1.3.2.上传安装包并解压1.3.3.启动1.3.4.默认启动1.3.5.指定配置启动1.3.6.开机自启 1.4.Redis桌面客户端1.4.1.R…

【VS Code开发】使用Live Server搭建MENJA小游戏并发布至公网远程访问

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…