有线通信--一文弄懂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的区分

  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
张正友标定法是一种常用的相机标定方法,广泛应用于计算机视觉领域。该方法通过采集一系列已知的三维物体在相机坐标系下的二维投影点,来计算相机内外参数矩阵,从而实现相机的几何校正和测量。 具体步骤如下: 1. 初始化标定板:选择一个特定的标定板,例如棋盘格,然后在每个方格的交叉点上贴上黑白相间的标志。 2. 放置标定板:将标定板放置在计算机视觉系统所见范围内,保证标定板能够在不同角度、位置下被相机观察到。 3. 拍摄标定图像:使用相机对标定板进行拍摄,至少需要12-20幅图像,图像应该包含不同的姿态和视角。 4. 检测标志物:从每个标定图像中提取特征点,通常使用角点检测算法来检测标志物的位置。 5. 计算相机参数:根据提取的特征点,通过最小二乘法来计算相机的内部参数(焦距、主点坐标)和外部参数(旋转矩阵、平移向量)。 6. 优化结果:根据计算得到的相机参数,利用优化算法来进一步提高标定的精度。 7. 验证标定结果:使用标定结果对图像进行校正,并测量标定板上的特征点,通过计算误差指标来验证标定结果的准确性。 总之,张正友标定法通过采集已知物体在相机坐标系下的二维投影点,实现了相机参数的计算和校正,对于计算机视觉中的三维重建、目标检测等任务具有重要意义。掌握这种标定方法可以帮助我们更好地理解相机成像过程,提高图像处理和计算机视觉算法的精度和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岂有此李呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值