SPI通信协议

SPI通信结介绍

在这里插入图片描述

W25Q64是一个Flash存储器芯片,内部可以存储8M字节的数据,并且是掉电不丢失的。

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

SPI通讯使用3条总线及片选线,3条总线分别为SCK、MOSI、MISO,片选线为SS,它们的作用介绍如下:

  • (1) SCK (Serial Clock):时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如STM32的SPI时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。
  • (2) MOSI (Master Output, Slave Input):主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。
  • (3) MISO (Master Input,,Slave Output):主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。
  • (4) SS ( Slave Select):从设备选择信号线,常称为片选信号线,也称为NSS、CS,以下用NSS表示。当有多个SPI从设备与SPI主机相连时,设备的其它信号线SCK、MOSI及MISO同时并联到相同的SPI总线上,即无论有多少个从设备,都共同只使用这3条总线; 而每个从设备都有独立的这一条NSS信号线,本信号线独占主机的一个引脚,即有多少个从设备,就有多少条片选信号线。
    I2C协议中通过设备地址来寻址、选中总线上的某个设备并与其进行通讯;而SPI协议中没有设备地址,它使用NSS信号线来寻址,当主机要选择从设备时,把该从设备的NSS信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI通讯。所以SPI通讯以NSS线置低电平为开始信号,以NSS线被拉高作为结束信号。

硬件电路

在这里插入图片描述

所有SPI设备的SCK、MOSI、MISO分别连在一起:
SCK时钟线,对于主机来说,时钟线为输出,对于所有从机来说,时钟线为输入。

MOSI主机输出从机输入,主机对应MO,输出,从机对应SI,输入。数据传送方向:主机通过MOSI输出,所有从机通过MOSI输入。

MIOS主机输入从机输出,主机对应MI,输入,从机对应SO。数据传送方向:三个从机对通过MIOS输入,主机通过MIOSI输出。

主机另外引出多条SS控制线,分别接到各从机的SS引脚
主机的SS线是输出,从机的SS线是输入,SS线是低电平有效,主机想指定谁,就把对应的SS线置低电平就行。如主机初始化化后,SS全部置高电平,这就是谁也不指定。
当主机需要和从机进行通信,主机就把SS1线置低电平,进行数据传输时,只有从机1响应,其余SS线高电平,保持沉默。

当主机和从机1通信完成后,就会把SS置回高电平,这样主机就结束和从机1的通信。
在同一时间,主机只能置一个SS为低电平,只能选择一个从机,否则,如果主机同时选中多个从机,就会导致数据冲突,这就是SPI选择从机的方式。

输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入:

SPI有一个冲突点的:主机MISO引脚是一个输入,而从机MISO引脚三个从机都是输出,如三个从机都是推挽输出,会导致冲突。所以SPI协议规定,当从机的SS引脚为高电平时,也就是从机未被选中,它的MISO引脚,必须是高阻态,高阻态相当于引脚断卡,不输出任何电平。在SS低电平时,MISO才允许变为推挽输出。

移位示意图

在这里插入图片描述
总结;SPI通信是交换一个字节,有了交换一个字节,就可以发送一个字节,接收一个字节和发送同时接收一个字节。

在这里插入图片描述

这里移位寄存器有一个时钟输入端,因SPI一般是高位先行,所以每来一个时钟,移位寄存器都会向左移位,从机同理。
移位寄存器的时钟源由主机提供的,叫做波特率发生器,它产生的时钟,驱动主机的移位寄存器进行移位,同时这个引脚也通过SCK引脚进行输出,接到从机的移位寄存器里。

在这里插入图片描述

工作:
首先,规定波特率发生器的时钟上升沿,所以移位寄存器向左移动一位,移出去的一位放到引脚上,MOSI是1,MISO是0 ,之后时钟继续运行,时钟下降沿时,MOSI的1,会采样输入到从机的最低位,MISO的0,会采样输入到主机的最低位,这是第一个时钟结束后现象。

在这里插入图片描述
8个时钟后,主机的10101010跑到从机里面了,从机的01010101跑到主句里面了,实现了主机和从机的一个字节的数据交接。
如只想发送,不想接收呢:扔然调用交换字节的时序,发送,同时接收,只是接收到的数据,我们不看它就行了。

SPI时序基本单元

在这里插入图片描述

模式1
在这里插入图片描述

CPO时钟极性,CPHA时钟相位。
在SS未被选中时,SCK默认电平为低电平。

第一个SS从机选择,在通信开始前,SS位为高电平,在通信过程中,SS始终保持低电平,通信结束,SS恢复高电平。

在这里插入图片描述

最下面MISO主机输入从机输出,SS高电平时,MISO用一条中间的线,表示高组态,SS下降沿之后,从机MISO被允许开启输出,SS上升沿之后,从机的MISO必须置回高组态。

在这里插入图片描述

移位传输:因为CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据。
SCK上上升沿,主机和从机同时移出数据,主机通过MOSI移出最高位,此时MOSI的电平就表示了主机要发送的数据B7,从机通过MISO移出最高位,此时MISO表示从机要发送的数据B7,然后时钟运行,产生下降沿,此时从机和主机同时移入数据,也就是进行数据采样,这里主机移出的B7,进入从机移位寄存器的最低位,从机移出的B7,进入从主移位寄存器的最低位,这样一个脉冲产生完毕,一个字节传输完毕。

在这里插入图片描述

如主机只想交换一个字节,可以置SS为高电平,通信结束,在SS上升沿,MOSI还可以再变化一次,将MOSI置到一个默认的高电平或低电平,也可不管,因为SPI没有硬性规定MOSI的默认电平。
然后,MISO从机必须置回高阻态,此时如果主机MISO,为上拉输入,那MISO引脚电平默认是高电平;如果主机MISO,为浮空输入,那MISO引脚电不确定。这是交换一个字节结束的流程。

在这里插入图片描述

如果主机还想继续交换字节,此时,主机就不必把SS置回高电平,直接重复一下,从这里到这里,这样可以交换多个字节。

模式0
在这里插入图片描述
模式0和模式1时序上区别:就是模式0数据移入移出,相位提前了。模式0应用更多。

在这里插入图片描述

SCK第一个边沿移入数据,第二个边沿移出数据:

在模式0下,SCK第一个边沿之前,就要提前开始移出数据,或称作第0个边沿移出,第一个边沿移入。
首先,SS下降沿开始通信,SCK还没有变化时,SS下降沿,就要立刻触发移位输出。这里MOSI和MISO的输出是对齐到SS的下降沿,那SS下降沿触位输出,SCK上升沿,就可以采样输入数据了,这样B7传输完毕。最终在第8个上升沿时,B0移入完成。整个字节交换完成。

在这里插入图片描述

之后,SCK还有一个下降沿,如主机只想交换一个字节结束,那在这个下降沿时,MOSII置到一个默认的高电平或低电平,也可不管;MISO也会变化一次,这一位实际上是下一字节的B7。因为相位提前了,如不需要,SS上升沿后,从机MISO置回高阻态。

模式3
在这里插入图片描述
模式0和模式2上区别:就是模式0的CPOL=0,模式2的CPOL=1。两者的波形,就是SCK的极性取反。
模式1和模式3上区别:就是模式1的CPOL=0,模式3的CPOL=1。两者的波形,也是SCK的极性取反。
模式0和模式3,都是SCK上升沿采样。
模式1和模式2,都是SCK下降沿采样。

SPI时序波形

发送指令
在这里插入图片描述
每个芯片对于SPI时序,字节流功能的定义不一样,这里采用的是W25Q64。

SPI对字节流功能的规定不像I2C那样,I2C的规定一般是,有效数据流第一个字节是寄存器地址,之后依次是读写的数据,使用的是读写寄存器器的模型。

而在SPI中,通常采用的是指令码加读写数据的模型。这个过程就是SPI起始后,第一个交换发送给从机的数据一般叫做指令码,在从机中,对应的会定义一个指令集,当我们需要发送什么指令时,就可以在起始后第一个字节发送指令集里面的数据,这样就能指导从机完成相应的功能了,不同的指令可以有不同的数据个数,有的指令只需要一个字节的指令码就可以完成。

在这里插入图片描述

发送指令,向SS指定的设备,发送指令(0x06):

指令0x06到是,可以由芯片厂商自己规定,在W25Q64 型面里,这个0x06 代表的是写使能。

在这里我们使用的是SPI模式0,在空闲状态是SS为高电平,SCK为低电平,MOSI和MISO的默认电平没有严格规定,然后SS产生下降沿时序开始,在这个下降沿时刻,MOSI和MISO就要开始变换数据了,MOSI由于指令码最高位仍然是0,所以这里保持低电平不变,MISO从机现在没有数据发给主机,引脚电平没有变化,实际上W25Q64不需要回弹数据时,手册里规定的是MISO仍然是高阻态,从机并没有开启输出,不过这也没问题,反正这个数据我们也不要看,那这里因STM32的MISO是上拉输入,所以这里MISO呈现高电平,之后SCK第一个上升沿进行数据采样,我这里画了一条绿线,从机采样输入得到零,主机采样输入得到一,之后继续第二个时钟,主机数据仍然是零,所以波形仍然没有变化,然后这样一位一位的发送接收发送接收。

到这一位数据才开始变化,主机要发送数据一,下降沿数据移出,主机将一移出到MOSI,MOSI变为高电平,这里因为是软件模拟的时序,所以MOSI的数据变化有些延迟,没有紧贴SCK的下降沿。
不过这也没关系,时钟是主机控制的,我们只要在下一个SCK上升沿之前完成变化就行了,然后SCK上升沿数据采样输入,在最后一位呢下降沿数据变化MOSI变为0,上升沿数据采样,从机接收数据0,SCK低电平是变化的时期,高电平是读取的时期,那时序SCK最后一个上升沿结束,一个字节就交换完毕了,因为写使能是单独的指令,不需要跟随数据,SPI只需要交换一个字节就完事了,所以最后在SCK下降沿之后,SS置回高电平结束通信。

总结一下就是,主机用0x06换来了从机的0xff,但实际上从机并没有输出,这个0xf f是默认的高电平,不过这个0xf f没有意义,我们不用管,那整个时序的功能就是发送指令,指令码是0x06 ,从机一比对事先定义好的指令集,发现0x06是写使能的指令,那从机就会控制硬件进行写使能,这样一个指令从发送到执行就完成了,就是发送单字节指令的时序。

指定地址写

在这里插入图片描述
W25Q64 芯片有8M字节的存储空间,一个字节的八位地址肯定不够,所以这里地址是24位的分三个字节传输。

在这里插入图片描述

首先ss下降沿开始时序,mosi空闲时是高电平,所以在下降沿之后,sck第一个时钟之前可以看到mosi变换数据由高电平变为低电平,然后sck上升沿数据采样输入,后面还是一样下降沿变换数据上升沿采样数据,八个时钟之后一个字节交换完成,我们用0x02换来了0xff,其中发送的0x02是一条指令,代表这是一个写数据的时序,接收到0x ff不需要看。

在这里插入图片描述

那既然是写数据的时序,后面必然还要跟着写的地址和数据,所以在最后一个下降沿时刻,因为我们后续还需要继续交换字节,所以在这个下降沿,我们要把下一个字节的最高位放到MOSI上,当然下一个字节的最高位仍然是0,所以这里数据没有变化,最后还是同样的流程交换一个字节,第二个字节我们用0x12换来了0xff,根据w25q64 芯片的规定,写指令之后的字节定义为地址高位,所以这个0x12 就表示发送地址的23~16位。

在这里插入图片描述

继续看一下交换一个字节,发送的是0x34 这个就表示发送地址的15~8位,最后还是交换一个字节发送的是0x56 ,这个表示发送地址的7~0位,通过三个字节的交换,24位的地址就发送完毕了,从机收到的24位地址是0x123456 。

在这里插入图片描述

那三位地址结束后,就要发送写入指定地址的内容了,我们继续调用交换一个字节,发送数据这里的波形是0x55 ,这个表示我要在0x123456 地址下,写入0x55 这个数据,最后如果只想写出一个数据的话,就可以SS置高电平结束通信了,当然这里也可以继续发送数据,spi里也会有和I2C一样的地址指针,每读写一个字节地址指针自动加一,如果发送一个字节之后不终止继续发送的字节就会依次写入到后续的存储空间里,这样就可以实现从指定地址开始写入多个字节了,这就是spi写入的时序。

指定地址读
在这里插入图片描述

我们看一下时序,起始之后第一个字节主机发送指令0x03 ,表示我要读取数据了,最后还是一样,主机在依次交换三个字节,分别是0x12 0x34 0x56 ,组合到一起就是0x123456代表24位地址。

0X03
在这里插入图片描述

0x12
在这里插入图片描述

0x34
在这里插入图片描述

0x56
在这里插入图片描述

0x55
在这里插入图片描述

最后这个地方就是关键点,因为我们是读取数据,指定地址之后,显然我们就要开始接收数据,所以这里三个字节的地址交换完之后,我们要把从机的数据搞过来,我们还是交换一个数据来个抛砖引玉,我们随便给从机一个数据,一般给ff就行了,从机就会乖乖的把0x123456地址下的数据通过MISO发给主机,可以看到这样的波形就表示指定地址下的数据是0x55 ,这样主机就实现了指定地址读一个字节的目的。然后如果我们继续抛砖引玉,那么从机内部的地址指针自动加一,从机就会继续把指定地址下一个位置的数据发过来,这样依次进行,就可以实现指定地址接收多个字节的目的了,最后数据传输完毕,SS置回高电平,时序结束。

在这里插入图片描述

当然时序这里也会有些细节,比如由于MISO是硬件控制的波形,所以它的数据变化都可以紧贴时钟的下降沿,另外我们可以看到miso数据的最高位实际上是在上一个字节,最后一个下降沿提前发生的,因为这是SPI模式0,所以数据变化都要提前半个周期。

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

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

相关文章

【十大排序算法】快速排序

在乱序的世界中,快速排序如同一位智慧的园丁, 以轻盈的手法,将无序的花朵们重新安排, 在每一次比较中,沐浴着理性的阳光, 终使它们在有序的花园里,开出绚烂的芬芳。 文章目录 一、快速排序二、…

profile-3d-contrib,github三维立体图的使用

图片展示: 提示: 这个profile-3d-contrib存储库有时候会出现问题,导致又有使用这个存储库svg的用户显示出现问题. 参考: https://zhuanlan.zhihu.com/p/681786778 原仓库链接: GitHub - yoshi389111/github-profile-3d-contrib: This GitHub Action creates a Gi…

【算法刷题 | 动态规划08】6.9(单词拆分、打家劫舍、打家劫舍||)

文章目录 21.单词拆分21.1题目21.2解法:动规21.2.1动规思路21.2.2代码实现 22.打家劫舍22.1题目22.2解法:动规22.2.1动规思路22.2.2代码实现 23.打家劫舍||23.1题目23.2解法:动规23.2.1动规思路23.2.2代码实现 21.单词拆分 21.1题目 给你一…

java中的异常-异常处理(try、catch、finally、throw、throws)+自定义异常

一、概述 1、java程序员在编写程序时提前编写好对异常的处理程序,在程序发生异常时就可以执行预先设定好的处理程序,处理程序执行完之后,可以继续向后执行后面的程序 2、异常处理程序是在程序执行出现异常时才执行的 二、5个关键字 1、tr…

Redis实战篇02

1.分布式锁Redisson 简单介绍: 使用setnx可能会出现的极端问题: Redisson的简介: 简单的使用: 业务代码的改造: private void handleVoucherOrder(VoucherOrder voucherOrder) {Long userId voucherOrder.getUserI…

2024真机项目

项目需求: 1. 172.25.250.101 主机上的 Web 服务要求提供 www.exam.com 加密站点,该站点在任何路由可达 的主机上被访问,页面内容显示为 "Hello,Welcome to www.exam.com !",并提供 content.exam.com/yum/A…

数据:人工智能的基石 | Scale AI 创始人兼 CEO 亚历山大·王的创业故事与行业洞见

引言 在人工智能领域,数据被誉为“新石油”,其重要性不言而喻。随着GPT-4的问世,AI技术迎来了新的浪潮。众多年轻创业者纷纷投身这一领域,Scale AI的创始人兼CEO亚历山大王(Alexander Wang)就是其中的佼佼…

什么是Java?

什么是Java?java是什么?下面我们来总结一下。 java是什么? java是一个静态编程语言,具有强大的多线程特征,目前java不仅采用c语言的优点,还去掉了一些多继承指针,等复杂的概念,我们…

Git配置 安装及使用

团队开发的神 找工作必备 环境变量 配置好环境后 打开终端环境 winr cmd 我习惯在桌面打开,然后进入相应的文件夹 (文件夹结构) (个人感觉能用cmd不用git,cmd更好用一些) 进入对应的文件夹 填写自己对…

docker安装rabbitmq详解

目录 1、安装 1-1.查看rabbitmq镜像 1-2.下载Rabbitmq的镜像 1-3.创建并运行rabbitmq容器 1-4.查看启动情况 1-5.启动web客户端 1-6.访问rabbitmq的客户端 2..遇到的问题 解决方法: 1、安装 1-1.查看rabbitmq镜像 docker search rabbitmq 1-2.下载Rabbitmq的镜像 拉…

国标GB/T 28181详解:校时流程详细说明

目录 一、定义 二、作用 1. 时间同步性 2. 事件记录的准确性 3. 跨平台、跨设备协作 4. 降低时间误差 5. 安全性提升 三、基本要求 四、命令流程 五、协议接口 六、校时效果 1、未校时的情况 2、校时后的效果 七、参考 一、定义 GB28181协议要求所有的监控设…

python后端结合uniapp与uview组件tabs,实现自定义导航按钮与小标签颜色控制

实现效果(红框内): 后端api如下: task_api.route(/user/task/states_list, methods[POST, GET]) visitor_token_required def task_states(user):name_list [待接单, 设计中, 交付中, 已完成, 全部]data []color [#F04864, …

CPP初阶:CPP的内存管理模式

目录 一.new和delete操作自定义类型 1.1C语言的内存管理 1.2CPP的内存管理方式 1.3C与CPP内存管理的差异 二.operator new和operator delete函数 三.CPP空间操作符使用深化 3.1 连续内存开辟与释放 3.2 非连续内存开辟与释放 四.new和delete的实现原理 4.1内置类型 4.2…

100道面试必会算法-32-二叉树右视图用栈实现队列

100道面试必会算法-32-二叉树右视图&用栈实现队列 给定一个二叉树的 根节点 root,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,n…

【内网攻防实战】红日靶场(一)续篇_金票与银票

红日靶场(一)续篇_权限维持 前情提要当前位置执行目标 PsExec.exe拿下域控2008rdesktop 远程登录win7msf上传文件kail回连马连上win7upload上传PsExec.exe PsExec.exe把win7 带到 2008(域控hostname:owa)2008开远程、关防火墙Win7…

OpenCV绘制直线

一 绘制图形 画线 画矩形 画圆 画椭圆 画多边形 绘制字体 二 画线 line(img,开始点,结束点,颜色…) 参数结束 img:在那个图像上画线 开始点,结束点:指定线的开始与结束位置; 颜色,线宽,线体…

Linux系统编程(十二)线程同步、锁、条件变量、信号量

线程同步: 协同步调,对公共区域数据按序访问。防止数据混乱,产生与时间有关的错误。数据混乱的原因 一、互斥锁/互斥量mutex 1. 建议锁(协同锁): 公共数据进行保护。所有线程【应该】在访问公共数据前先拿…

文心一言 VS 讯飞星火 VS chatgpt (277)-- 算法导论20.3 4题

四、如果调用 vEB-TREE-INSERT 来插入一个已包含在 vEB 树中的元素,会出现什么情况?如果调用 vEB-TREE-DELETE 来删除一个不包含在 vEB 树中的元素,会出现什么情况?解释这些函数为什么有相应的运行状况?怎样修改 vEB 树…

vs - vs2015编译gtest-v1.12.1

文章目录 vs - vs2015编译gtest-v1.12.1概述点评笔记将工程迁出到本地后,如果已经编译过工程,将工程Revert, Clean up 干净。编译用的CMake, 优先用VS2019自带的打开VS2015X64本地命令行编译gtest工程测试安装自己写个测试工程,看看编译出来的…

[vulnhub]Lin.Security主机Linux提权

Hash Crack(Hash cat) boblinsecurity:~$ cat /etc/passwd $ echo "AzER3pBZh6WZE">hash 检查哈希类型: $ hash-identifier AzER3pBZh6WZE $ hashcat -m 1500 -a 0 hash /usr/share/wordlists/rockyou.txt --force username:insecurity password:AzER3pBZh6WZE…