嵌入式通信协议-----SPI协议详解

目录

一、简介

1.概念

2.特点

3.优缺点

 4.应用场景

二、通信原理

三、通信特性

1.时钟频率

2.时钟极性(CPOL)

3.时钟相位(CPHA)

4.四种模式

5.多主机模式

(1)多片选

(2)菊花链

四、编程实现

五、三种SPI比较

1.Dual SPI

2.Queued SPI

3.三者的区别


一、简介

1.概念

      SPI(Serial Peripheral Interface)总线协 议是一种全双工同步串行总线通信协议,用于在 集成电路之间进行数据传输。SPI 总线通常由 一个主设备和多个从设备组成,,每个从设备都 有一个单独的片选信号,最高可以工作 在上百 MHz,一般 SPI 需要 4 根线,但是也可以使用三根线。

2.特点

  • 同步通信:SPI是同步通信协议,数据传输由主设备(Master)提供的时钟信号(SCLK)控制,保证数据同步传输。

  • 全双工通信:SPI支持全双工通信,主设备和从设备可以同时发送和接收数据。

  • 多从设备支持:一个主设备可以连接多个从设备,通过片选信号(Chip Select, CS)来选择具体的从设备进行通信。

  • 简单硬件连接:相比其他协议,如I²C,SPI的硬件连接相对简单,不需要复杂的握手信号。

3.优缺点

优点:

①高速传输:由于没有复杂的握手信号,SPI可以实现高速数据传输,几乎比IIC快两倍。

全双工通信:主从设备可以同时发送和接收数据,提高通信效率。

②灵活性高:可以轻松连接多个从设备,支持多种通信模式,数据传输更加灵活,可以传输任意大小的字。

③硬件结构简单:从站不需要唯一地址(与I2C不同)。从机使用主机时钟,不需要精密时钟振荡器/晶振(与UART不同)。不需要收发器(与CAN不同)。

缺点:

①引脚占用较多:每个从设备需要一个片选信号,如果有多个从设备,需要占用较多的GPIO引脚。

②无流控制和确认机制:SPI协议没有内置的流控制和数据确认机制,需要在应用层实现。

③传输距离短:与RS-232和CAN总线相比,只能支持非常短的距离。

④只允许一个主设备。

 4.应用场景

SPI协议广泛应用于需要高速数据传输和可靠性的场景,如:

①显示器驱动

②存储器(如SD卡、Flash存储器)

③传感器数据采集

④音频编解码器

⑤电机驱动

二、通信原理

SPI 一般应用由四个引脚组成(一主一从):

 SCLK(Serial Clock):串行时钟,由主机发出。

 MOSI(Master Output Slave Input):主机输出从机输入信号,由主机发出。

 MISO(Master Input Slave Output):主机输入从机输出信号,由从机发出。

 NSS(Slave Selected):选择信号,由主机发出,一般是低电位有效。

不同的芯片厂家命名不同除此之外还有:

 SCLK/SCK

 MOSI/SOMI/DIN/DI/SDI/SI/SIN

 MISO/SIMO/DOUT/SDO/SO/SOUT

 NSS/CE/CS/SSEL/PCS

SPI 的主从连接图如图1所示

图1 

其通信过程可分为以下几步:

        起始条件(Chip Select):主设备通过片 选信号(Chip Select)选择从设备,并发送 低电平信号,表示开始数据传输。

        传输方式:主设备和从设备之间使用 MOSI 和 MISO 两根线传输数据。主设备通过 MOSI 发送数据,从设备通过 MISO 接收数据,采集时机要根据模式选择来判定。

        时钟信号:主设备通过 SCLK 时钟信号控制 数据传输速率,同时从设备也按照同样的时钟 频率来接收数据。

        数据长度:SPI 总线没有固定数据长度的限 制,可以发送任意长度的数据块。

        结束条件(Chip Deselect):主设备通过 片选信号(Chip Deselect)取消对从设备的 选择,结束数据传输。

如下图2所示发送0x53为例:主机拉低NSS片选信号,启动通信,并且产生时钟信号,上升沿触发边沿信号,当主机在MOSI信号线一位一位开始发送0x53时(因为0101=0x5,0011=0x3所以根据低位在前先发送应为11001010),在MISO线路一位一位接收数据0X46(此处我也不懂为什么是01100010,有大佬解释一下就好了

图2

三、通信特性

        SPI 是一种非常灵活的通信协议,我们可以配置它的时钟极性、时钟相位等。

1.时钟频率

SPI的时钟频率是指用于同步数据传输的时钟信号的频率。它决定了数据传输的速度。时钟频率的配置需要考虑主设备和从设备的硬件限制以及通信距离等因素。

配置SPI时钟频率主要有以下步骤:

①确定主设备的最大时钟频率:查阅主设备的技术手册,找出SPI模块支持的最大时钟频率。

②确定从设备的最大时钟频率:查阅从设备的技术手册,找出从设备支持的最大时钟频率。

③选择合适的时钟频率:在主设备和从设备的最大支持频率之间选择一个合适的频率。这个频率不应超过任何一个设备的最大支持频率。

示例:以STM32微控制器为例,SPI时钟频率由APB时钟和波特率预分频器(Baud Rate Prescaler)决定。以下是一个配置示例

①假设APB2时钟频率为84MHz。

②波特率预分频器可以设置为2、4、8、16、32、64、128或256。假设我们希望配置SPI时钟频率为5.25MHz:

③SPI时钟频率 = APB时钟频率 / 波特率预分频器

5.25MHz = 84MHz / 16

④因此,波特率预分频器应设置为16。

2.时钟极性(CPOL)

        时钟极性用于设置时钟在空闲时的电平状态,

CPOL 为“1”则时钟空闲时为高电平。

CPOL 为“0”,则时钟空闲时为低电平。

如图 3 所示。这就直接导致了第一个信号沿是下降沿还是上升沿,通常 CPOL 和时钟相位(CPHA)配合使用。

图3


3.时钟相位(CPHA)

        时钟相位用于设置在第几个时钟沿发生对数据线就行采样,

当 CPHA=1 是表示第二个 时钟沿对数据线进行采样。

当 CPHA=0 时,在第一个时钟沿对数据进行采样。

如图 4 所 示:
 

图4

4.四种模式

上面我们知道了什么是相位和极性,为此我们可以根据他们之间的不同组合来将SPI分为四种模式主机与从机需要工作在相同的模式下才可 以正常通讯。实际中采用的较多的“模式 0”和“模式 3”。

SPI模式CPOLCPHA空闲时CLK时钟采样时刻
000低电平奇数边沿
101低电平偶数边沿
210高电平奇数边沿
311高电平偶数边沿

四种模式的具体解释:

Mode0:CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿(准备数据),(发送数据)数据发送是在下降沿。

Mode1:CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。

Mode2:CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。

Mode3:CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

具体采样数据如图5所示:

5.多主机模式

前面说到SPI总线必须有一个主机,可以有多个从机,那么具体连接到SPI总线的方法有以下两种多片选和菊花链。

(1)多片选

①通常,每个从机都需要一条单独的CS线。

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

(2)菊花链

菊花链(Daisy Chain)是一种常见的连接拓扑结构,用于串行连接多个设备,使得每个设备与前一个设备和下一个设备相连。菊花链连接在许多应用中都有广泛的使用,例如串行通信、计算机总线、音频设备和LED灯串等。

特点:

  • 串行连接:每个设备通过输入和输出端口与链上的下一个和上一个设备连接。
  • 单一通道:数据通过单一通道传输,依次通过每个设备。
  • 简化布线:相比星形拓扑结构,菊花链减少了布线的复杂度,因为不需要从每个设备到中心节点的独立连接。
  • 扩展方便:增加或移除设备相对简单,只需连接或断开相应的设备。

优点

  • 简化布线:减少了物理连线的复杂性。
  • 扩展方便:可以轻松增加或移除设备。

缺点

  • 延迟累积:每个设备增加了数据传输的延迟。
  • 可靠性问题:如果链中的一个设备出现故障,可能影响整个链的通信。

四、编程实现

​ 以国产芯片智芯半导体的Z20K118芯片为例,其例程为了实现使用SPI主机传输和接收数据其具体工程文件放在资源里:

硬件框图如图所示

软件代码如下

1.SPI结构体配置

const SPI_Config_t tSpiMasterCfgStruct = 
{
    SPI_MODE_MASTER,                     /* 模式选择 */
    32,                                  /* 数据帧的大小 */
    SPI_CLK_PHASE_FIRST,                 /* 时钟相位 */
    SPI_CLK_INACTIVE_LOW,                /* 始终极性 */
    SPI_TMOD_TR,                         /* 传输模式 */
    350,                                 /* 时钟分频 */
    2,                                   /* 发送FIFO阈值电平 */
    2                                    /* 接收FIFO阈值 */
};

2.系统初始化


    
    /* 选择osc时钟作为spi0的函数时钟 */
    CLK_ModuleSrc(CLK_SPI0, CLK_SRC_OSC40M);
    /* 设置spi0函数时钟的分频比 */
    CLK_SetClkDivider(CLK_SPI0, CLK_DIV_1);  
    /* 启用spi0的时钟 */
    SYSCTRL_EnableModule(SYSCTRL_SPI0);    
    /* 使能GPIO口引脚 时钟*/
    CLK_ModuleSrc(CLK_PORTB, CLK_SRC_OSC40M);   

    CLK_ModuleSrc(CLK_PORTE, CLK_SRC_OSC40M);

    SYSCTRL_EnableModule(SYSCTRL_PORTB);       

    SYSCTRL_EnableModule(SYSCTRL_PORTE);  
    
    /* 配置各IO口复用*/
    PORT_PinmuxConfig(PORT_B, GPIO_2, PTB2_SPI0_SCK);

    PORT_PinmuxConfig(PORT_E, GPIO_1, PTE1_SPI0_SIN);

    PORT_PinmuxConfig(PORT_B, GPIO_4, PTB4_SPI0_SOUT);

    PORT_PinmuxConfig(PORT_B, GPIO_5, PTB5_SPI0_PCS0); 

 3.使能SPI并下拉PCS选择从节点

    /* 初始化结构体配置 */
    SPI_Init(SPI0_ID, &tSpiMasterCfgStruct);
    /* 下拉PCS0选择从机 */
    SPI_SelectSlave(SPI0_ID, SPI_SS_PCS0);
    /* 使能SPI */
    SPI_Enable(SPI0_ID);

4.发送数据

 for(i=0; i<TRANS_LEN; i++)
    {
        localCnt = 0 ;
        /* 发送数据 */
        while (RESET == SPI_GetStatus(SPI0_ID, SPI_STATUS_TFNF));
        SPI_SendData(SPI0_ID, i);
        /* 等待状态寄存器的RFNE标志位被置位 */
        while(RESET == SPI_GetStatus(SPI0_ID, SPI_STATUS_RFNE))
        { 
            if(localCnt > 0xFFFF)
            {
                return RESET;
            }
            localCnt++;
        }
        /* 接收数据 */
        data[i] = SPI_ReceiveData(SPI0_ID);  
    }  

五、三种SPI比较

三种SPI通常是指标准SPI,Dual SPI,和Queued SPI 三种,标准SPI已经介绍过了不做过多介绍主要介绍后面两种SPI,以及三者的区别。

1.Dual SPI

        Dual SPI是一种增强的SPI通信模式,主要用于提高数据传输速率。它增加了数据传输通道,使得每个时钟周期可以传输更多的数据。

          Dual SPI只是针对SPI Flash而言,不是针对所有SPI外设。对于SPI Flash,全双工并不常用,因此扩展了mosi和miso的用法,让它们工作在半双工,用以加倍数据传输。也就是对于Dual SPI Flash,可以发送一个命令字节进入dual mode,这样MOSI变成SIO0(serial io 0),MISO变成SIO1(serial io 1),这样一个时钟周期内就能传输2个bit数据,加倍了数据传输。                 

特点

  • 双通道数据传输:使用两条数据线同时传输数据,通常是MOSI和MISO共同传输数据。
  • 更高的传输速率:在相同的时钟频率下,Dual SPI可以比标准SPI传输更多的数据。
  • 硬件要求高:需要支持Dual SPI模式的主设备和从设备。

2.Queued SPI

        Queued SPI是一种高级的SPI通信模式,通常用于需要高效管理多个SPI传输事务的场景。它在标准SPI的基础上增加了硬件队列(Queue)功能,可以预先配置多个SPI传输事务,主设备可以自动依次执行这些事务。

        在Dual SPI的基础上增加了两根I/O线(SIO2,SIO3),目的是一个时钟内传输4个bit,而QSPI就是Queued SPI的简写;

特点

  • 硬件队列:可以预先配置多个传输事务,并由硬件自动执行。
  • 高效管理:减少CPU干预,提高数据传输效率。
  • 适用于复杂场景:特别适用于需要频繁且复杂SPI传输的应用,如存储器访问。

Dual SPI和Queued SPI是针对flash的接口,根据flash工作的特性,将全双工改为半双工,提高通信的速率。 

3.三者的区别

(1)标准SPI是通用的,Dual SPI和QSPI只适用于flash;
(2)标准SPI:标准4线连接,全双工,同时收和发;
(3)Dual SPI:标准4线连接,半双工,2根数据线,并线发和收,双方向切换;
(4)QSPI:标准4线连接,半双工,4根数据线,并线发和收,双方向切换。

特性标准SPIDual SPIQueued SPI
数据通道单通道双通道单通道或者双通道
数据速率常规更高高效管理
硬件复杂度简单需要支持Dual SPI的设备需要支持QSPI的设备
传输速率普通更高最高
应用场景通用SPI通信高速数据传输复杂、频繁SPI传输

代码配置上的区别以stm32f4的HAl库为例:

①标准SPI代码配置

#include "stm32f4xx_hal.h"

SPI_HandleTypeDef hspi1;

void SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES;
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
    HAL_SPI_Init(&hspi1);
}

②Dual SPI代码配置

配置Dual SPI时,需要额外设置数据线的双通道模式:

#include "stm32f4xx_hal.h"

SPI_HandleTypeDef hspi1;

void Dual_SPI1_Init(void)
{
    hspi1.Instance = SPI1;
    hspi1.Init.Mode = SPI_MODE_MASTER;
    hspi1.Init.Direction = SPI_DIRECTION_2LINES_RXONLY; // 双通道接收
    hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
    hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
    hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
    hspi1.Init.NSS = SPI_NSS_SOFT;
    hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
    hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
    hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
    hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    hspi1.Init.CRCPolynomial = 10;
    HAL_SPI_Init(&hspi1);

    // 额外的Dual SPI模式配置,根据具体芯片文档进行设置
}

③Queued SPI代码配置

QSPI配置较为复杂,需要配置队列管理和多通道模式

#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_qspi.h"

QSPI_HandleTypeDef hqspi;

void QSPI_Init(void)
{
    hqspi.Instance = QUADSPI;
    hqspi.Init.ClockPrescaler = 1;
    hqspi.Init.FifoThreshold = 4;
    hqspi.Init.SampleShifting = QSPI_SAMPLE_SHIFTING_NONE;
    hqspi.Init.FlashSize = 1;
    hqspi.Init.ChipSelectHighTime = QSPI_CS_HIGH_TIME_1_CYCLE;
    hqspi.Init.ClockMode = QSPI_CLOCK_MODE_0;
    hqspi.Init.FlashID = QSPI_FLASH_ID_1;
    hqspi.Init.DualFlash = QSPI_DUALFLASH_DISABLE;
    HAL_QSPI_Init(&hqspi);

    // 额外的队列和多通道配置,根据具体芯片文档进行设置
}

图片以及部分内容引自:SPI协议详解(图文并茂+超详细)-CSDN博客

  • 25
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 嵌入式ARM协议中的LIN总线是一种低成本、低速率的串行通信协议,主要用于汽车电子系统中的设备通信。LIN总线主要用于连接车辆的各个电子控制单元(ECU),如仪表盘、门控制模块、座椅调节模块等,以实现数据的传输和控制。 LIN总线协议基于主从结构,其中一个ECU充当主节点,负责发送指令和协调通信,而其他ECU则作为从节点,负责接收指令并执行相应的操作。主节点通过发送特定的帧让从节点执行特定的任务,从而实现控制和通信。 LIN总线的通信速率相对较低,通常在20kbps到20Mbps之间。这是为了满足低成本和低功耗的需求而设计的。此外,LIN总线还采用了不同的物理层电压标准,如12V和5V。这样可以适应不同的应用场景和硬件要求。 在嵌入式ARM系统中,LIN总线可以通过软件和硬件实现。通过使用ARM处理器的UART通信接口,可以将指令转化为LIN总线的帧格式,实现数据的发送和接收。同时,还可以使用专用的LIN总线驱动芯片来简化通信的实现。这些芯片通常具有LIN总线协议的硬件支持,可以提供更高的性能和稳定性。 总的来说,嵌入式ARM协议中的LIN总线是一种用于汽车电子系统的通信协议,通过低成本、低速率的串行通信实现ECU之间的数据传输和控制。它提供了灵活和可靠的通信方式,使得车辆系统的各个模块能够协同工作,实现更高的性能和功能。 ### 回答2: 嵌入式ARM协议中的LIN(Local Interconnect Network)总线是一种低成本、低速率的串行通信协议,常用于汽车和工业领域中。 LIN总线主要用于连接车辆不同的电子控制单元(ECU),包括车身电子系统、信息娱乐系统等。它的设计目标是为了提供可靠的数据传输,并保持较低的硬件和软件成本。 在LIN总线中,通讯由一个主节点(Master)和若干从节点(Slave)组成。主节点负责控制总线的访问和数据传输的时序,从节点则是被动响应主节点的指令。主节点通过发送帧(Frame)来控制从节点的操作,并接收从节点上报的数据。 LIN总线的通信速率相对较低,通常在20kbps至20Mbps之间,这是为了满足成本和可靠性的要求。它使用单线通信,通过追加校验位和帧头来确保数据的完整性和正确性。 作为一种低成本的通信协议,LIN总线在汽车和工业控制应用中发挥着重要作用。它常用于门锁系统、车窗控制、座椅调节、仪表盘等模块的通信。LIN总线的主要优点包括低成本、低功耗、简单的网络拓扑和更低的研发成本。 总而言之,嵌入式ARM协议中的LIN总线是一种低成本、低速率的串行通信协议,用于连接车辆不同的电子控制单元。它通过主节点和从节点的通信方式来实现数据传输和控制,具备低成本、低功耗等优点,广泛应用于汽车和工业控制领域。 ### 回答3: 嵌入式ARM协议——LIN总线,全称是局域网互连网络(Local Interconnect Network),是一种用于汽车电子控制系统的串行通信总线协议。 LIN总线是针对在车内各种电子设备之间进行通信而设计的低成本、低速率数据传输网络。它可以连接车内电子控制单元(ECU)之间的传感器、执行器和其他外设,例如仪表板、门锁、窗户控制器和座椅调节器等。 LIN总线采用了单一主节点和多个从节点的拓扑结构。主节点负责发送消息,而从节点是被动接收消息并执行相应的操作。主从节点之间的通信通过单线半双工方式进行,使得LIN总线在成本和可靠性方面都得到了优化。 LIN总线的通信速率相对较低,一般在20kbps至20Mbps之间。由于车内电子设备通常只要求低速率的数据传输,因此LIN总线可以满足大部分应用的需求。 LIN总线的协议栈包含物理层、数据链路层和应用层。物理层负责定义信号和电气特性,例如电压和线缆类型。数据链路层负责提供错误检测和纠正机制,以确保数据的可靠传输。应用层定义了消息的格式和内容,包括标识符、数据字节和校验位等。 相比于其他汽车网络协议,如CAN总线,LIN总线具有更低的成本和更简单的实现。它适用于一些较简单的车内电子设备,不需要高速数据传输的场景。 总而言之,嵌入式ARM协议——LIN总线是一种适用于车内电子控制系统的低成本、低速率的串行通信协议,通过单一主节点和多个从节点的拓扑结构实现通信。它的简单实现和性价比使得它在一些简单车内电子设备中得到广泛应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值