SPI 通信协议

article/2025/9/21 12:00:57

在这里插入图片描述

文章目录

  • 【 1. 概述 】
  • 【 2. 原理 】
    • 1. 全双工特征下的传输特点
    • 2. 二线式、三线式的SPI
    • 3. SPI 模式
      • CPOL(Clock Polarity),时钟极性
      • CPHA (Clock Phase),时钟相位
      • 通信模式_时序
    • 4. 通信过程
    • 5. 底层数据传输演示
  • 【 3. SPI底层驱动 】

【 1. 概述 】

  • SPI ( Serial Peripheral interface),串行外围设备接口。由摩托罗拉公司设计并实现。
  • 特点
    SPI 是一种 高速、全双工、同步、串行 的通信总线,采用主机(Master)-从机(Slave)的通信方式
  • SPI 接口
    • MISO (Master Input Slave Output):主设备数据输入,从设备数据输出。
    • MOSI (Master Output Slave Input):主设备数据输出,从设备数据输入。
    • SCLK (Serial Clock),也叫做SCK:串行时钟信号。SPI规定只能由主设备产生,并根据此时钟信号一位一位地传输。
    • SS (Slave Select),也叫做NSS、CS、SSEL:从设备片选信号,由主设备控制,为一个主设备连接多个从设备提供了可能。

【 2. 原理 】

1. 全双工特征下的传输特点

  • 没有只进行读操作或者只进行写操作的说法,因为是全双工的传输方式:写操作和读操作是同步完成的。每次SPI传输数据时,主从设备都是在互相交换信息,即主/从机发一个数据必然会收到一个数据。
    在这里插入图片描述
  • 数据交换与移位寄存器
    SPI总线的主机和从机都有一个移位寄存器。当主机向自己的移位寄存器写入数据时,数据会通过MOSI信号线进入到从机的移位寄存器;类似地,从机移位寄存器里的数据,通过MISO信号线进入到主机的移位寄存器。这样,主机和从机就完成了一次数据交换。下面这张图,是SPI通信的简明原理图:
    在这里插入图片描述
  • 如果只进行写操作,主机只需忽略接收到的字节;反之,若主机要读取从机的一个字节,就必须发送一个空字节来引发从机的发送。

2. 二线式、三线式的SPI

  • 如果主机只给从机发送命令,从机不需要回复数据的时候,那MISO就可以不要。
  • 而在主机只读取从机的数据,不需要给从机发送指令的时候,那MOSI可以不要。
  • 当一个主机一个从机的时候,从机的片选有时可以固定为有效电平而一直处于使能状态,那么CS可以不要;此时如果再加上主机只给从机发送数据,那么CS和MISO都可以不要;如果主机只读取从机送来的数据,CS和MOSI都可以不要。

3. SPI 模式

        SPI共有4种通信模式,主机和从机需要工作在相同的模式下才能正常通信。
        这4种模式是基于CPOL和CPHA进行划分:
在这里插入图片描述在这里插入图片描述

CPOL(Clock Polarity),时钟极性

用于决定空闲时刻的电平状态。

  • 通信的整个过程分为空闲状态和通信状态,SCLK在数据发送之前和数据发送之后的状态为 空闲状态
  • 如果CPOL=0,那么空闲状态SCLK是低电平。
  • 如果CPOL=1,那么空闲状态SCLK是高电平。

CPHA (Clock Phase),时钟相位

用于决定何时进行信号采样。

  • 主机和从机要交换数据,就牵涉到一个问题,即主机在什么时刻输出数据到MOSI上而从机在什么时刻采样这个数据,或者从机在什么时刻输出数据到MISO上而主机什么时刻采样这个数据。同步通信的特点就是所有数据的变化和采样都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近变化或被采样。那么,如果一方在上升沿输出数据到MOSI上,另一方就只能在下降沿去采样这个数据;反之如果一方在下降沿输出数据,那么另一方就必须在上升沿采样这个数据。
  • CPHA=1,就表示数据的输出是在一个时钟周期的第一个沿上,至于这个沿是上升沿还是下降沿,这要是CPOL的值而定,CPOL=1那就是下降沿,CPOL=0就是上升沿。那么数据的采样自然就是在第二个沿上了。
  • CPHA=0,就表示数据的采样是在一个时钟周期的第一个沿上,如果CPHA=1就取下降沿,CPHA=0就取上升沿。那么数据的输出自然就在第二个沿上了。

仔细想一下,当CPHA=0时,这里会有一个问题:就是当一帧数据开始传输第一bit时,在第一个时钟沿上就采样该数据了,那么它是在什么时候输出来的呢?有两种情况:一是SSEL使能的边沿,二是上一帧数据的最后一个时钟沿,有时两种情况还会同时生效。

通信模式_时序

我们对CPOL=1,CPHA=1即 SPI 模式3进行讲解:
在这里插入图片描述

  • 当数据发送前以及发送后,SCK都是高电平,因此也可以直接通过时序图推出CPOL=1。
  • 可以看出,在SCK第一个沿的时候,MOSI和MISO的数据会发生变化,而在SCK第二个沿的时候,MOSI和MISO的数据是稳定的。又因为 SPI 只能在数据稳定时进行采样,数据不稳定时输出,所以图中是在第一个边沿输出第二个边沿采样,即CPHA=1。
  • 注意最后最隐蔽的SSEL片选,一般情况下,这个引脚通常用来决定是哪个从机和主机进行通信。

4 种 SPI 通信模式的部分时序
在这里插入图片描述在这里插入图片描述

4. 通信过程

  • 主机先将NSS信号拉低,这样保证开始接收数据。
  • 当从机接收端检测到时钟的边沿信号时,它将立即读取数据线上的信号,这样就得到了一位数据(1bit);
  • 由于时钟是随数据一起发送的,因此指定数据的传输速度并不重要,尽管设备将具有可以运行的最高速度。

  • 主机发送到从机时:主机产生相应的时钟信号,然后数据一位一位地将从MOSI信号线上进行发送到从机;
  • 主机接收从机数据:如果从机需要将数据发送回主机,则主机将继续生成预定数量的时钟信号,并且从机会将数据通过MISO信号线发送;

在这里插入图片描述

5. 底层数据传输演示

  • SPI是一个环形总线结构,主要是在sck的控制下,两个双向移位寄存器进行数据交换。
  • 假设下面主机的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。那么第一个上升沿来的时候 MOSI 数据将=1,主机寄存器=0101010x。下降沿到来的时候,MISO上的电平将锁存到从机寄存器中去,那么这时从机寄存器=0101010+MISO,这样在 8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个 SPI 时序。
    在这里插入图片描述

【 3. SPI底层驱动 】

/以下是SPI模块的初始化代码,配置成主机模式 						  
//SPI口初始化
//这里是对SPI1的初始化
void SPI1_Init(void)
{	 GPIO_InitTypeDef  GPIO_InitStructure;SPI_InitTypeDef  SPI_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟//GPIOFB3,4,5初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//PB3~5复用功能输出	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO_PinAFConfig(GPIOB,GPIO_PinSource3,GPIO_AF_SPI1); //PB3复用为 SPI1GPIO_PinAFConfig(GPIOB,GPIO_PinSource4,GPIO_AF_SPI1); //PB4复用为 SPI1GPIO_PinAFConfig(GPIOB,GPIO_PinSource5,GPIO_AF_SPI1); //PB5复用为 SPI1//这里只针对SPI口初始化RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//设置SPI工作模式:设置为主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//设置SPI的数据大小:SPI发送接收8位帧结构SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;		//串行同步时钟的空闲状态为高电平SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;	//串行同步时钟的第二个跳变沿(上升或下降)数据被采样SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//定义波特率预分频的值:波特率预分频值为256SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRC值计算的多项式SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器SPI_Cmd(SPI1, ENABLE); //使能SPI外设SPI1_ReadWriteByte(0xff);//启动传输		 
}   
//SPI1速度设置函数
//SPI速度=fAPB2/分频系数
//@ref SPI_BaudRate_Prescaler:SPI_BaudRatePrescaler_2~SPI_BaudRatePrescaler_256  
//fAPB2时钟一般为84Mhz:
void SPI1_SetSpeed(u8 SPI_BaudRatePrescaler)
{assert_param(IS_SPI_BAUDRATE_PRESCALER(SPI_BaudRatePrescaler));//判断有效性SPI1->CR1&=0XFFC7;//位3-5清零,用来设置波特率SPI1->CR1|=SPI_BaudRatePrescaler;	//设置SPI1速度 SPI_Cmd(SPI1,ENABLE); //使能SPI1
} 
//SPI1 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
u8 SPI1_ReadWriteByte(u8 TxData)
{		 			 while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空  SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte  数据while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte  return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据	}

http://chatgpt.dhexx.cn/article/7VsZwtpR.shtml

相关文章

SPI通信协议基础

文章目录 引言正文串行与并行通信SPI通信简介SPI如何运作?时钟从机选择多个从机MOSI和MISOSPI数据传输步骤 SPI的优缺点优点缺点 好文推荐参考 引言 当您将微控制器连接到传感器,显示器或其他模块时,您是否考虑过这两种设备如何相互通信&…

SPI、I2C、UART(即串口)三种串行总线详解

以下内容均来源于网络资源的学习与整理,如有侵权请告知删除。 参考博客 几个串口协议学习整理 UART IIC SPI_mainn的博客-CSDN博客 SPI、I2C、UART三种串行总线的原理、区别及应用_嵌入式Linux,的博客-CSDN博客 RS-232 和 UART 之间有什么区别? - 知乎…

uart、spi、i2c通信协议详解

文章目录 前言一、uart(串口)介绍使用rs232、rs485拓展 二、I2C介绍1.宏观流程2.时序上3.典型操作 三、spi(串行外设接口)介绍使用1.宏观上2.微观上 总结1.i2c和spi对比 前言 之前对于各种通信协议学习了就忘,学了就忘…

普通GPIO模拟SPI通信协议(软件SPI)

在工作中偶尔会遇到SPI不够用的情况,而我们又要去使用SPI通信协议,此时就需要我们自己去模拟SPI通信协议。我们知道SPI通信协议有四种模式,它们分别如下所示: 下面是我基于ATSAM4SD16B芯片在Atmel Studio上用普通GPIO模拟的SPI…

SPI 协议

一. 概念 1. 通常SPI通信要求4根线,分别是MOSI(mast output salve input), MISO, CLK, CS。 2. 当发送和接受数据的工作都准备好了,只要有时钟CLK,就发送数据,没有时钟就不发送,而且一个时钟周期发送一位(bit)数据,所…

SPI通信协议(SPI总线)学习

转载自:https://www.cnblogs.com/deng-tao/p/6004280.html 1、什么是SPI? SPI是串行外设接口(Serial Peripheral Interface)的缩写。是 Motorola 公司推出的一 种同步串行接口技术,是一种高速的,全双工,同步的通信总…

SPI通信

1 SPI的简介及基本特点 1 SPI的简单介绍 最近工作中使用了SPI通信方式来做TM4C129和STM32之间的通信,为了更好地解决问题就学习了SPI原理的相关内容,完成了项目之后,也对这种通信方式有了较为深入的了解,现在来对SPI的使用方法进…

详解SPI通信协议

一、SPI简介 SPI,即Serial Peripheral Interface的英文缩写。从字面意思看就是串行外部设备接口,是一种全双工、高速、同步的通信总线。 SPI最早是摩托罗拉公司开发的全双工同步串行总线,用于微控制器(MCU)连接外部设…

stm32中常见的通信协议之SPI

目录 1.SPI总线2.SPI的寻址方式3.SPI的工作原理总结4.SPI的通讯过程5.SPI的极性和相位6.IIC和SPI的异同7.stm32中SPI配置中常用的寄存器8.stm32中相关库函数 1.SPI总线 SPI是串行外设接口的缩写,SPI是一种高速的、全双工、同步的串行通信协议;SPI采用主…

【通信协议】一文搞懂SPI

SPI总线简介 SPI(Serial Peripheral Interface)是 Motorola 公司推出的一种同步串行接口技术,是一种高速的,全双工,同步的通信总线。 接口定义 SPI接口共有4根信号线,分别是:片选信号、时钟信号、串行输出信号、串行…

SPI 通信协议 最详细解读!!!

SPI(Serial Peripheral Interface,串行外围接口)是一种高速、全双工、同步的通信总线,主要应用在EEPROM、FLASH、实时时钟、AD转换器上,以及数字信号处理器和数字信号解码器之间。 信号线 SPI有四根信号线:…

SPI 通信协议详解

SPI通信协议详解 写在最前: 本文讲述了SPI通信协议的基本内容包括如下 SPI的基础知识SPI的读写时序 本文重点参考 英文维基百科 中文维基百科 百度百科 注意: 倘若读者有足够的耐心和英文水平,强烈建议自行去英文维基百科去阅读相关知识。 相关链接: SPI…

通信协议篇——SPI通信

通信协议篇——SPI通信 1.简介 SPI(Serial Peripheral Interface)是一种高速、同步、全双工串行通信总线,采用主从机通信模式,主要应用在EEPROM,FLASH,实时时钟,AD转换器等。 2.原理 通信方…

SPI接口通信协议详解:SPI时序、2线、3线、4线SPI及4种常用工作模式

简介 SPI通信原理比I2C要简单,它主要是主从方式通信。这种模式通常只有一个主机和一个或者多个从机,标准的SPI是4根线,分别是SSEL(片选,也写作 SCS)、SCLK(时钟,也写作SCK)、MOSI(主机输出从机输入Master Output/Slav…

详解UART、I2C、SPI常用通信协议(全是细节)

前言 UART、I2C和SPI是我们在嵌入式开发中比较常见的通信协议了,没有最好的通信协议,每个通信协议都有自己的优缺点。如果想要通信速度快,SPI 将是理想的选择;如果用户想要连接多个设备而不是过于复杂,I2C 将是理想的选…

【总线】SPI 通信协议

目录 SPI总线协议概述 串行与并行通信 SPI通信介绍 SPI的工作原理 时钟 从属选择 多个从机 常规方法 菊花链方法 MOSI 和 MISO SPI 数据传输的步骤 SPI 的优缺点 优点 缺点 文章参考 SPI总线协议概述 SPI是许多不同设备使用的通用通信协议。例如,SD卡…

SPI通信协议详解,一篇就够!

一、什么是SPI? SPI 的英文全称为 Serial Peripheral Interface,顾名思义为串行外设接口。SPI 是一种同步串行通信接口规范,主要应用于嵌入式系统中的短距离通信。该接口由摩托罗拉在20世纪80年代中期开发,后发展成了行业规范。 …

2021年游戏项目的十大编程语言:C++、Java、C#均上榜

在这个技术驱动的世界里,游戏行业是全球增长最快的行业之一。在每一款华丽精美的电子游戏背后,都有一种编程语言,为用户提供优质的体验。游戏开发者利用顶级的编程语言来构建游戏。不同的游戏项目使用了不同的编程语言,这取决于游…

2021 编程语言排行榜

点击“终码一生”,关注,置顶公众号 每日技术干货,第一时间送达! IEEE Spectrum 发布了 2021 年编程语言排行榜,官方的标题是:Python 在新技术领域依然是主导地位。 Python 近几年随着大数据、数据挖掘、人…

2020 年最牛逼的 10 门编程语言

先看再点赞,给自己一点思考的时间,微信搜索【沉默王二】关注这个有颜值却假装靠才华苟且的程序员。 本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试题。 对于很多初学编程的人来说,尤其是马上要入…