• MCU常见通信总线串讲(四)—— SPI总线协议


    🙌秋名山码民的主页
    😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪
    🎉欢迎关注🔎点赞👍收藏⭐️留言📝
    获取源码,添加WX


    前言

    首先明确一个概念,关于MCU中通信总线和通信协议,通信总线是一种用于连接各种外设和模块的物理接口,它可以传输数据和控制信息。通信协议则是指在通信总线上传输数据时所遵循的规则和约定,以确保不同设备之间能够正确地交换信息,我们也可以把他叫做通信总线协议。

    系列文章,主要讲解以下几个总线协议,读者可以按需选择:

    1. UART和USART
    2. RS232、RS485总线
    3. IIC总线
    4. SPI总线
    5. CAN总线
    6. USB总线

    一、SPI总线协议基本概念

    SPI是一种高速全双工的通信总线。
    在这里插入图片描述
    如上图所示,SPI有三根总线,和一根片选线组成,3条总线分别为SCK、MOSI、MISO,片选线为SS

    1. SS(Slave Select):从设备选择信号线,常称为片选信号线
    2. SCK(Serial Clock):时钟信号线,用于通信数据同步
    3. MOSI(Master Output,Slave Input):主设备输出/从设备输入引脚
    4. MISO(Master Input,Slave Output):主设备输入/从设备输出引脚

    二、SPI协议层

    在这里插入图片描述
    NSS、SCK、MOSI信号都由主机控制产生,而MISO的信号由从机产生,主机通过该信号线读取从机的数据。MOSI与MISO的信号只在NSS为低电平的时候才有效,在SCK的每个时钟周期,MOSI和MISO传输一位数据。

    1. NSS信号线由高变低,是SPI通信的起始信号,NSS信号线由低变高是SPI通信的停止信号
    2. 数据有效性:观察图中的②③④⑤标号处,MOSI及MISO的数据在SCK的上升沿期间变化输出,在SCK的下降沿时被采样。即在SCK的下降沿时刻,MOSI及MISO的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。在其他时刻,数据无效,MOSI及MISO为下一次表示数据做准备。
    3. CPOL/CPHA及通信模式:
      在这里插入图片描述

    三、I2C和SPI的区别

    I2C(Inter-Integrated Circuit)和SPI(Serial Peripheral Interface)都是两种常见的串行通信协议,它们在硬件接口、数据传输方式和应用场景上有一些明显的区别。

    1. 硬件接口:

      • I2C需要两根线,即时钟线(SCL)和数据线(SDA)。它使用开漏输出来实现总线的双向数据通信。
      • SPI通信需要至少四根线,包括时钟线(SCLK)、数据输入线(MISO)、数据输出线(MOSI)和片选线(SS)。
    2. 数据传输方式:

      • I2C使用一个主从架构,允许多个设备连接到同一总线上。数据是以帧的形式进行传输,每个帧包括一个起始位、7或8位数据位、一个可选的ACK位和一个停止位。
      • SPI通常采用一对主从设备的方式,其中一个设备作为主控制器,其他设备作为从设备。它通过全双工通信进行数据传输,可以实现高速数据传输。
    3. 应用场景:

      • I2C通常用于连接低速外设,如传感器、EEPROM和实时时钟等,因为它比较简单并且支持多主机连接。
      • SPI通常用于连接高速外设,如存储器芯片、显示器、AD/DA转换器等,因为它可以提供更高的数据传输速率和灵活性。

    四、SPI的定义

    初始化结构体及函数定义在库文件stm32f10x_spi.h及stm32f10x_spi.c中,

    typedef struct
    {
         uint16_t SPI_Direction;           /*设置SPI的单双向模式 */
         uint16_t SPI_Mode;                /*设置SPI的主/从机端模式 */
         uint16_t SPI_Data Size;           /*设置SPI的数据帧长度,可选8位或16位 */
         uint16_t SPI_CPOL;                /*设置时钟极性CPOL,可选高或低电平*/
         uint16_t SPI_CPHA;                /*设置时钟相位,可选奇或偶数边沿采样 */
         uint16_t SPI_NSS;                 /*设置NSS引脚由SPI硬件控制还是软件控制*/
         uint16_t SPI_Baud Rate Prescaler; /*设置时钟分频因子,fpclk/分频数=f SCK */
         uint16_t SPI_First Bit;           /*设置MSB/LSB先行 */
         uint16_t SPI_CRCPolynomial;       /*设置CRC校验的表达式 */
    } SPI_Init Type Def;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    最后

    如果本文对你有所帮助,还请三连支持一下博主!
    请添加图片描述

  • 相关阅读:
    【C++11】多线程
    4、运算符
    自定义注解
    Wireshark的数据包它来啦!
    Python 三维姿态估计+Unity3d 实现 3D 虚拟现实交互游戏
    循环神经网络 - 循环神经网络的从零开始
    马士兵-郑金维—并发编程—3.锁
    Java日志系列——规范化日志
    (1)bark-ml
    IVF-PQ 基于量化的向量检索算法
  • 原文地址:https://blog.csdn.net/weixin_45920495/article/details/134294335