有线通信--一文弄懂SPI--(基础篇)

学完很久的通信协议具体内容总是忘记,为了方便自己随时复习以及查看,本人这里总结一份关于SPI的协议详解,分享给大家。


一、什么是SPI

每接触一个协议,我们都要明白它的优缺点,知道它的使用范围和特点,在有这些前置认识后,对后面的原理和实验才能了解的更深入和透彻。

SPI(串行外设接口)以其高速度而著称,使其成为快速通信的首选。SPI没有定义速度限制,通常能达到甚至超过10M/bps。与 I2C 不同,SPI 使用四线工作:MISO(主输入从输出)、MOSI(主输出从输入)、SCK(串行时钟)和 SS(从选择),允许全双工通信(发送和同时接收)。尽管简单且速度快,但 SPI 比 I2C 需要更多的引脚,这可能是电路设计中需要考虑的一个因素。


二、优缺点及适用范围

优点:

  • 高速:SPI通信速度较快,适用于对速度要求较高的应用

  • 全双工:SPI支持全双工通信,可以同时进行数据发送和接收。

  • 简单:SPI的通信协议相对简单,适用于快速开发和实现。

缺点:

  • 连线复杂:SPI需要多根线进行连接,可能会增加硬件设计的复杂性。

  • 没有指定的流控制,没有应答机制确认是否接收到数据

  • 长距离传输受限:SPI的传输距离受到限制,过长的线路可能导致信号衰减和干扰。

  • 主从模式限制:SPI通常采用主从模式,主设备数量受限,不适用于多主设备场景

 适用范围:

        SPI 非常适合需要快速可靠的数据传输的情况,例如 TFT 显示器、SD 存储卡和无线通信模块。但是在具有许多从站的复杂系统中,它的有效性会降低。


三、物理层

物理层就是协议的总线介绍以及电路连接图

1、 总线介绍

与IIC不同,SPI协议用到的总线一共是四个:MISOMOSISCKSS

MISO:( Master Input Slave Output)主设备数据输入,从设备数据输出(从机发送数据

MOSI:(Master Output Slave Input) 主设备数据输出,从设备数据输入(主机发送数据

SCK:  (Serial Clock):时钟信号,由主设备产生;

CS/SS:   (Chip Select/Slave Select):从设备使能信号(也叫片选信号),由主设备控制,一主多从时,CS/SS是从芯片是否被主芯片选中的控制信号,只有片选信号为预先规定的使能信号时(高电位或低电位),主芯片对此从芯片的操作才有效。

注:

2、电路连接图

SPI通信协议支持一对一一对多两种模式,一对一就是一个主机对应一个从机,一对多就是一个主机对应多个从机

PS:主从机的定义就是提供时钟的设备为主机(Master),接收时钟的设备就是从机(Slave)

箭头的指向就是我们总线的指向,以一对一为例:MOSI总线就是主机到从机,MISO就是从寄到主机,SCLK就是主机到从机。到这里有人就会问:为啥主从机都会发送和接收?因为我们是全双工,类比于打电话,我和对方既可以听也可以同时讲。

他们的电路连接图如图一所示,图源:不脱发的程序猿

图一(左:一对一、右:一对多)
图一(左:一对一、右:一对多)

 


四、协议层 

1、通信原理

到这里,我们已经知道SPI通信的优缺点、总线和连接图,那它到底是怎么通信流程呢?

① 主机发送信号,拉低CS,保证开始接收数据

②主机发送时钟信号,从机检测时钟的边沿信号进行写数据/读数据操作,它将立即写入/读取数据线上的信号,这样就得到了一位数据(1bit)。

(采集时机可能是时钟信号的上升沿(从低到高)或下降沿(从高到低),因为SPI有四种采集模式,后面2中会讲到)

③ 主机(Master)将要发送的数据写到发送数据缓存区(Menory),缓存区经过移位寄存器(缓存长度不一定,看单片机配置),串行移位寄存器通过MOSI信号线将字节一位一位的移出去传送给从机,同时MISO接口接收到的数据经过移位寄存器一位一位的移到接收缓存区。

④从机(Slave)也将自己的串行移位寄存器(缓存长度不一定,看单片机配置)中的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据,这样,两个移位寄存器中的内容就被交换。

ps:SPI主设备和从设备都有一个串行移位寄存器(Menory),主设备通过向它的SPI串行寄存器写入一个字节来发起一次传输。


SPI并没有规定数据在传输过程中是高位优先还是低位优先,为了保证数据正确传输,一般会设定好高位优先(MSB)


2、设备时钟

        看了前面我们知道SPI是全双工通信,也就是说主机在通信开始的时候配置相应的时钟信号,在每个SPI通信时钟周期内,进行全双工通信:主机通过MOSI总线发送一位数据,从机接收;从机通过MISO总线发送一位数据,主机接收。如果我只想单向数据传输,那也必须遵守全双工通信格式,也就是说本来接受数据的设备也得发送一个“虚拟数据”(也叫填充数据)以保持协议的完整性。这些数据通常被本来发送数据的设备所忽略。那我们应该探讨一下它的特点,SPI时钟特点主要包括:时钟速率、时钟极性和时钟相位三方面。

2.1、时钟频率

        SPI通信的时钟频率想多大就多大,但是这个是理想情况下,现实情况下它受到多个因素的限制,其中主要因素包括是主设备和从设备的规格:每个设备(微控制器、传感器、存储器等)都有其规定的最高SPI时钟频率,这通常在设备的数据手册中指定。时钟频率不能超过设备规定的最大值。关于如何设置的问题,像STM32的话,可以通过CubeMAX的时钟树分频设置,如32的系统时钟为8 MHz,并且你设置了一个分频值为16,则SPI的时钟频率将是500 kHz(8 MHz / 16 = 500 kHz),也可以在代码里面设置:

2.2、时钟极性(CKP、CPOL

        除了设置时钟频率之外还需要设置时钟极性,根据硬件制造商的命名规则不同,时钟极性通常写为CKPCPOL

CKP可以配置为1或0。这意味着你可以根据需要将时钟的默认状态(IDLE)设置为高或低。极性反转可以通过简单的逻辑逆变器实现。参考设备的数据手册才能正确设置CKP和CKE。

  • CKP = 0:时钟空闲IDLE为低电平 0;
  • CKP = 1:时钟空闲IDLE为高电平1;

2.3、时钟相位(CKE、CPHA)

        除了设置时钟频率和时钟极性之外还需要设置时钟相位,根据硬件制造商的不同,时钟相位通常写为CKECPHA。顾名思义,时钟相位/边沿,也就是采集数据时是在时钟信号的具体相位或者边沿;时钟极性和相位共同决定读取数据的方式,比如信号上升沿读取数据还是信号下降沿读取数据。

  • CKE = 0:在时钟信号SCK的第一个跳变沿采样;
  • CKE = 1:在时钟信号SCK的第二个跳变沿采样。

2.4、采集模式

根据SPI的时钟极性和时钟相位特性可以设置4种不同的SPI通信操作模式,它们的区别是定义了在时钟脉冲的哪条边沿转换(toggles)输出信号,哪条边沿采样输入信号,还有时钟脉冲的稳定电平值(就是时钟信号无效时是高还是低),也就是上文2.1的通信流程的②的补充讲解,详情如下所示:[CKP,CKE ]=[极性,相位]

  • Mode0:[0,0]:当空闲态时,SCK处于电平,数据采样是在第1个边沿,也就是SCK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。
  • Mode1:[0,1]:当空闲态时,SCK处于电平,数据发送是在第2个边沿,也就是SCK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。
  • Mode2:[1,0]:当空闲态时,SCK处于电平,数据采集是在第1个边沿,也就是SCK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。
  • Mode3:[1,1]:当空闲态时,SCK处于电平,数据发送是在第2个边沿,也就是SCK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。
    黑线为采样数据的时刻,蓝线为SCK时钟信号

如果有多个从设备,并且它们使用了不同的工作模式,那么主设备必须在读写不同从设备时需要重新修改对应从设备的模式。以上SPI总线协议的主要内容。 它没有规定最大传输速率,没有地址方案,也没规定通信应答机制,没有规定流控制规则。只要四根信号线连接正确,SPI模式相同,将CS/SS信号线拉低,即可以直接通信,一次一个字节的传输,读写数据同时操作,这就是SPI。

3、时序分析

每个通信协议都有自己的时序,分析时序不仅可以检验我们是否理解,也可以生动的认识总线变化曲线。举个例子,下图是SPI Mode0读/写时序,可以看出SCK空闲状态为低电平,主机数据在第一个跳变沿被从机采样,数据输出同理。 图源:不脱发的程序猿

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LiN6ISx5Y-R55qE56iL5bqP54y_,size_20,color_FFFFFF,t_70,g_se,x_16

下图是SPI Mode3读/写时序,SCK空闲状态为高电平,主机数据在第二个跳变沿被从机采样,数据输出同理。 图源:不脱发的程序猿

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5LiN6ISx5Y-R55qE56iL5bqP54y_,size_20,color_FFFFFF,t_70,g_se,x_16

上面是单独拿出来一段来分析,我们接下来以整体发送接收的流程来看,以一对一为例看一下SPI通信整体流程:主机拉低NSS片选信号,启动通信,并且产生时钟信号,上升沿触发边沿信号,主机在MOSI线路一位一位发送数据0X53,在MISO线路一位一位接收数据0X46。这里也问一下大家在下图中,时钟极性和时钟相位是多少呢?

 首先看空闲状态下,SCK处于高电平,所以时钟极性为1,然后我们看到是在第2个边沿采集,所以时钟相位是1。

 五、多从机模式

上文我们都是按照一对一的模式讲解,下面来介绍一下一对多的模式。一对多的模式其实也分为两类:多片选菊花链

1、多片选

        通常,每个从机都需要一条单独的CS线。如果要和特定的从机进行通讯,可以将相应的CS信号线拉低,并保持其他CS信号线的状态为高电平;如果同时将两个CS信号线拉低,则可能会出现乱码,因为从机可能都试图在同一条MISO线上传输数据,最终导致接收数据乱码。

2、菊花链 

菊花链:在数字通信世界中,在设备信号(总线信号或中断信号)以串行的方式从一个设备依次传到下一个设备,不断循环直到数据到达目标设备的方式
        1、菊花链的最大缺点是因为是信号串行传输,所以一旦数据链路中的某设备发生故障的时候,它下面优先级较低的设备就不可能得到服务了;
        2、另一方面,距离主机越远的从机,获得服务的优先级越低,所以需要安排好从机的优先级,并且设置总线检测器,如果某个从机超时,则对该从机进行短路,防止单个从机损坏造成整个链路崩溃的情况。图源:小麦大叔

最终数据流向图 

六、代码编程

基于STM32的SPI设置,
1.初始化GPIO口,配置相关引脚的复用功能,使能SPIx时钟。调用函数:void GPIO_Init();

2.使能SPI时钟总线:RCC_APB2PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE)

3.配置SPI初始化的参数,设置SPI工作模式:SPI_Init(SPI2,&SPI_Initstructure)

4.使能SPI外设:SPI_Cmd(SPI2,ENABLE);

void SPI2_Init(void)	
{
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	 
	//配置SPI2管脚
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_14;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
	GPIO_Init(GPIOB, &GPIO_InitStructure);  
	
	//SPI2配置选项
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
	   
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init(SPI2, &SPI_InitStructure);

	//使能SPI2
	SPI_Cmd(SPI2, ENABLE);   
}

其中不明白APB1的可以看我的这篇文章STM32单片机中AHB、APB1和APB2的区分

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

lftp客户端

设置编码 当使用FTP客户端,尤其是命令行界面时,可能会遇到文件名字符集不匹配导致的乱码问题。这通常是因为服务器和客户端使用的编码方式不同,比如一个使用UTF-8,而另一个使用ISO-8859-1或GBK等。 在Linux系统中,如果…

TinyAgent: 尝试Agent入门

最近忙了许多事,终于抽出时间学习一下Agent了,就尝试尝试了Datawhale某不要葱姜蒜作者的大作TingAgent来作为非科班的入门项目。 TinyAgent/Agent.py at master KMnO4-zx/TinyAgent GitHubhttps://github.com/KMnO4-zx/TinyAgent/blob/master/Agent.p…

什么是好用的人才测评系统?

对于企业HR来说,在人才测评是必不可少的工具,什么是好用的人才测评? 1、测评效果靠谱;2、操作实施简便。 人才测评的目的是为找到最适合企业的人选,测评就是一个方法,一个工具,能达到预期目的才…

uniapp——组件多颜色模块展示、气泡框

一、自定义颜色&#xff1a; 样式 代码 <template><view class"content"><!-- 右上角 --><view class"coverStatus" :class"[itemClass, positionClass,cornerClass,sanJiaoCss,sanJiaoCss2]":style"dynamicStyle&q…

<router-link>出现Error: No match for {“name“:“home“,“params“:{}}

在将<a></a>标签换到<router-link></router-link>的时候出现No match for {"name":"home","params":{}}这样的错误&#xff0c;其中格式并无错误&#xff0c; <router-link class"navbar-brand active" …

内存管理(C/C++)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

BYOL(NeurIPS 2020)原理解读

paper&#xff1a;Bootstrap your own latent: A new approach to self-supervised Learning third-party implementation&#xff1a;https://github.com/open-mmlab/mmpretrain/blob/main/mmpretrain/models/selfsup/byol.py 本文的创新点 本文提出了一种新的自监督学习方…

Linux配置环境变量_推荐的方式

Linux配置环境变量_推荐以下两种方法&#xff1a; (1)用户环境变量&#xff1a;编辑用户目录下 ~/.bashrc、~/.bash_profile 或 ~/.profile文件 (2)系统环境变量&#xff1a;在/etc/profile.d/目录&#xff0c;创建独立的.sh文件 环境变量脚本文件的执行顺序 /etc/profile-&g…

【Java集合进阶】数据结构(平衡二又树旋转机制)数据结构(红黑树、红黑规则、添加节点处理方案详解)

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

记一次 Java 应用内存泄漏的定位过程

问题现象 最近&#xff0c;笔者负责测试的某个算法模块机器出现大量报警&#xff0c;报警表现为机器CPU持续高占用。该算法模块是一个优化算法&#xff0c;本身就是CPU密集型应用&#xff0c;一开始怀疑可能是算法在正常运算&#xff0c;但很快这种猜测就被推翻&#xff1a;同…

如何使用云数据库GaussDB管理平台进行实例安装?

前言 随着数字经济的蓬勃发展&#xff0c;数据库也成为企业的关键技术生产力&#xff0c;也是各行各业数字化转型的必要根基。GaussDB作为新一代分布式数据库&#xff0c;核心代码100%自主创新&#xff0c;具备高可用、高安全、高性能、高弹性、高智能、易部署、易迁移的特性&…

Java作业6-Java类的基本概念三

编程1 import java.util.*;abstract class Rodent//抽象类 {public abstract String findFood();//抽象方法public abstract String chewFood(); } class Mouse extends Rodent {public String findFood(){ return "大米"; }public String chewFood(){ return "…

shm 共享内存

shm 共享内存 0,命令1&#xff0c;了解&#xff1a;2&#xff0c;程序: 0,命令 ipcs 查看分配的共享内存ipcrm -m shmid 删掉分配的共享内存1&#xff0c;了解&#xff1a; 1&#xff09;&#xff0c;进程通信的一种 2&#xff09;&#xff0c;地址映射出来后&#xff0c;就不…

C语言数据结构之顺序表

目录 1.线性表2.顺序表2.1顺序表相关概念及结构2.2增删查改等接口的实现 3.数组相关例题 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性&#xff08;数据类型相同&#xff09;的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff…

Github 2024-04-20 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-04-20统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量非开发语言项目2Python项目2Swift项目2HTML项目1CSS项目1Go项目1C项目1C++项目1Rust项目1编程面试大学:成为软件工程师的全面学习计划 创建周期…

半导体材料(三)——P-N结和金属-半导体接触

本篇为西安交通大学本科课程《电气材料基础》的笔记。 本篇为这一单元的第三篇笔记&#xff0c;上一篇传送门。 p-n结和金属-半导体接触 p-n结 无偏压开路状态 如图a所示&#xff0c;左边是n型掺杂&#xff0c;右边是p型掺杂&#xff0c;在n区和p区之间形成了一个不连续的…

WARNING: No swap limit support——查看docker状态时提示警告

环境&#xff1a;Ubuntu 20.04 1、警告详情 执行命令 service docker status如下图 2、解决办法 2.1 修改文件 执行命令 vim /etc/default/grub在GRUB_CMDLINE_LINUX中追加cgroup_enablememory swapaccount1&#xff0c;如下&#xff1a; # If you change this file…

【蓝桥杯嵌入式】蓝桥杯嵌入式第十四届省赛程序真题,真题分析与代码讲解

&#x1f38a;【蓝桥杯嵌入式】专题正在持续更新中&#xff0c;原理图解析✨&#xff0c;各模块分析✨以及历年真题讲解✨都已更新完毕&#xff0c;欢迎大家前往订阅本专题&#x1f38f; &#x1f38f;【蓝桥杯嵌入式】蓝桥杯第十届省赛真题 &#x1f38f;【蓝桥杯嵌入式】蓝桥…

攻防世界18.fileclude

18.fileclude include函数&#xff1a;包含并执行变量或者文件。 if&#xff1a;是if语句用来判断。 isset&#xff1a;判断变量是否存在&#xff0c;值是否为NULL。 $_GET&#xff1a;接收表单提交数据&#xff0c;并把数据附加到url链接当中。 逻辑运算符&&&#xff…

【提示学习论文】BlackVIP: Black-Box Visual Prompting for Robust Transfer Learning论文原理

BlackVIP: Black-Box Visual Prompting for Robust Transfer Learning BlackVIP:稳健迁移学习的黑盒视觉提示 问题 黑盒白盒&#xff1f; 黑盒和白盒的概念与对预训练模型内部参数的了解程度相关。黑盒指的是对预训练模型的参数和结构缺乏详细了解&#xff0c;通常只能通过使…
最新文章