一文教你彻底学会SPI协议

简介: 一文教你彻底学会SPI协议

一.概况SPI

SPI 协议是由摩托罗拉公司提出的通讯协议(Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、 LCD 等设备与 MCU 间,要求通讯速率较高的场合。这里可以对比我写的另外一篇博客一文教你彻底学会IIC协议

1.信号线:SPI具有SCK,MOSI,MISO ,CS线 (区别于IIC只有CLK,SDA).。

2.寻址方式: SPI是通过CS片选信号来选择从机(IIC是通过寻址找到从设备)

3.通信速率:SPI速率较快(可达fPCLK/2),一般用于高速设备之间通信(区别于IIC)

二.SPI连接

2.1 一主一从

在“一主一从”的SPI互连方式下,只有一个SPI主设备和一个SPI从设备进行通信。这种情况下,只需要分别将主设备的SCK、MOSI、MISO和从设备的SCK、MOSI、MISO直接相连,并将主设备的SS置高电平,从设备的SS接地(即置低电平,片选有效,选中该从设备)即可。

2.2 一主多从

在“一主多从”的SPI互连方式下,一个SPI主设备可以和多个SPI从设备相互通信。这种情况下,所有的SPI设备(包括主设备和从设备)共享时钟线和数据线,即SCK、MOSI、MISO 3根线,并在主设备端使用多个GPIO引脚来选择不同的SPI从设备。

三.SPI通信过程

讲通信过程之前,先讲一下极性和相位。后面才能理解后序采样过程。

3.1 CPOL(极性)和CPHA(相位)

CPHA(时钟相位)位被清“0”,数据在SCK时钟的奇数(第1、3、5…个)跳变沿采样.

CPHA(时钟相位)位被置“1”,数据在SCK时钟的偶数(第2、4、6…个)跳变沿采样.

CPOL位为“0”时就是SCK在空闲时为0, CPOL位为“1”时就是SCK空闲时为1。

所以说,CPOL决定了第一个沿是上升沿还是下降沿。如果SCK空闲是为0,那第一个沿为上升沿。如果SCK空闲时为1,那第一个沿为下降沿。

那么总的来说,CPHA和CPOL决定了是上升沿采样还是下降沿采样。

所以总共有4种组合,决定了SPI有4种模式,总的表格如下:

3.2 SPI时序图

这是一个主机的通讯时序,我们以SPI模式0为例。 NSS、 SCK、 MOSI 信号都由主机控制产生,而 MISO 的信

号由从机产生,主机通过该信号线读取从机的数据。 MOSI 与 MISO 的信号只在 NSS 为低

电平的时候才有效,在 SCK 的每个时钟周期 MOSI 和 MISO 传输一位数据。

3.1 SPI起始信号

NSS 信号线由高变低,是 SPI 通讯的起始信号。 NSS 是每个从机各自独占的信号线,当从机在自己的 NSS 线检测到起始信号后,就知道自己被主机选中了,开始准备与主机通讯。

3.2 SPI停止信号

NSS 信号由低变高,是 SPI 通讯的停止信号,表示本次通讯结束,从机的选中状态被取消。

3.3 数据的有效性

SPI 使用 MOSI 及 MISO 信号线来传输数据,使用 SCK 信号线进行数据同步。 MOSI 及MISO 数据线在 SCK 的每个时钟周期传输一位数据,且数据输入输出是同时进行的。数据传输时, MSB 先行或 LSB 先行并没有作硬性规定,但要保证两个 SPI 通讯设备之间使用同样的协定, MOSI 及 MISO 的数据在 SCK 的上升沿期间变化输出,在SCK 的下降沿时被采样。即在 SCK 的下降沿时刻, MOSI 及 MISO 的数据有效,高电平时表示数据“1”,为低电平时表示数据“0”。在其它时刻,数据无效, MOSI及 MISO 为下一次表示数据做准备。SPI 每次数据传输可以 8 位或 16 位为单位,每次传输的单位数不受限制。

四.代码实例

这里以和Flash通信为例,下面是一个初始化代码

void SPI_FLASH_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  /* 使能SPI时钟 */
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );
  /* 使能SPI引脚相关的时钟 
  1.片选引脚 2.SCK时钟引脚 3.MISO引脚 4.MOSI引脚 */
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOA|
                                       RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOA, ENABLE );
  /* 配置SPI的 CS引脚,普通IO即可 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* 配置SPI的 SCK引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* 配置SPI的 MISO引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* 配置SPI的 MOSI引脚*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /* 停止信号 FLASH: CS引脚高电平*/
  GPIO_SetBits(GPIOA,GPIO_Pin_4);
  /* SPI 模式配置 */
  // FLASH芯片 支持SPI模式0及模式3,据此设置CPOL CPHA
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//全双工模式
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;  //主机
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //8位
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;  //极性高
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;  //偶边沿
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;   //软件控制
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;  //速率4分频
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //高位先行
  SPI_InitStructure.SPI_CRCPolynomial = 7;           //数据校验 --一般不需要
  SPI_Init(FLASH_SPIx , &SPI_InitStructure);      //初始化结构体
  /* 使能 SPI  */
  SPI_Cmd(SPI1 , ENABLE);
}



目录
相关文章
|
18天前
|
Java
java实现上位机与西门子PLC的通讯设置
这段代码创建了一个ZCAN_Transmit_Data数组,初始化并设置了数组中的第一个元素,包括写入数据、传输类型为1。然后,创建了一个ZCAN_CAN_FRAME对象,指定了CAN_ID和数据长度为8,并将十六进制字符串转换为字节数组填充到数据字段。将这个帧赋值给ZCAN_Transmit_Data对象。最后通过ZLGCAN接口发送数据,如果返回值不等于1,则抛出异常,否则返回发送结果。
|
11月前
|
传感器
一文教你彻底学会IIC协议
一文教你彻底学会IIC协议
258 1
|
存储 索引
西门子S7-200SMART与变频器的通信如何设置?USS通信协议如何组态?
今天我们来介绍西门子S7-200SMART与变频器的通信如何设置,USS通信协议如何组态,下面先介绍一下变频器参数设置。
西门子S7-200SMART与变频器的通信如何设置?USS通信协议如何组态?
|
存储 人工智能
西门子S7-200 SMART Modbus RTU通信,如何编写从站程序
上篇文章中我们通过一个例子学习了西门子S7-200 SMART中断程序的编写,本篇我们开始学习S7-200 SMART的Modbus RTU通信。通过集成RS485端口或可选通信板SM CM01的RS485/RS232端口,S7-200 SMART可以作为Modbus RTU主站或者从站同多个设备进行通信。
西门子S7-200 SMART Modbus RTU通信,如何编写从站程序
|
Linux API 数据处理
USB协议架构分析
USB协议架构分析
|
安全 5G 网络性能优化
无线接口 | 带你读《5G 无线系统设计与国际标准》之五
本节对物理层、数据链路层和网络层基本功能相关内容进行一些讨论。
无线接口  | 带你读《5G 无线系统设计与国际标准》之五
台达PLC开发笔记(二):台达PLC设置主机通讯参数为RTU并成功通讯
台达PLC开发笔记(二):台达PLC设置主机通讯参数为RTU并成功通讯
台达PLC开发笔记(二):台达PLC设置主机通讯参数为RTU并成功通讯
蓝牙核心规范(V5.2)6.0-深入详解之Uart传输层
蓝牙核心规范(V5.2)6.0-深入详解之Uart传输层
485 0
蓝牙核心规范(V5.2)6.0-深入详解之Uart传输层
|
传感器 监控 网络协议
一文搞懂物联网Modbus通讯协议
一般来说,常见的物联网通讯协议众多,如蓝牙、Zigbee、WiFi、ModBus、PROFINET、EtherCAT、蜂窝等。而在众多的物联网通讯协议中,Modbus是当前非常流行的一种通讯协议。它一种串行通信协议,是Modicon公司于1979年为使用可编程逻辑控制器(PLC)通信而制定的,可以说,它已经成为工业领域通信协议的业界标准。
1749 0
一文搞懂物联网Modbus通讯协议
[连载]《C#通讯(串口和网络)框架的设计与实现》- 14.序列号的设计,不重复的实现一机一码
目       录 第十四章     序列号的设计... 2 14.1        设计原则... 2 14.2        设计思想... 3 14.3        代码实现... 4 14.4        代码混淆... 18 14.5        代码破解... 18 14.6        小结... 18   第十四章      序列号的设计     序列号作为软件使用授权方式之一,被广泛使用在应用软件方面。
802 0

热门文章

最新文章