SPI总线协议基本原理及相关配置

2023-05-16

单片机应用中,最常用的通信协议主要有三个,即USART、IIC和SPI。关于前两个的介绍在之前文章学习过,这次介绍一下第三个通信协议——SPI。

 

SPI(Serial Peripheral Interface Bus)由摩托罗拉公司开发,它是高速全双工同步串 行通信协议。SPI 支持一主多从,这点类似于 IIC,但是又与 IIC 选通从设备的方式不同, IIC 是通过发送从机地址来选通从机,而 SPI 则是通过拉低连接到从机的 NSS 引脚对从机进行选通的。SPI 一般应用由四个引脚组成(一主一从):

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

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

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

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

SPI与IIC主要的区别:

SPI是高速(高达30Mbps)远距离全双工同步串行同行的,IIC是低速(最大4Mbps)近距离半双工同步串行通行的,
■相同点
1、均采用串行,同步的方式
2、均采用TTL电平,传输距离和应用场景类似
3、均采用主从方式工作
■不同点
1、IIC为半双工,SPI为全双工(MOSI,MISO同时收发)
2、IIC有应答机制,SP1无应答机制
3、IC通过向总线广播从机地址来寻址,SP1通过向对应从机发送使能信号来寻址

4、IIC总线读写时序比较固定统一,设备驱动编写方便;而SPI则需要根据不同的设备的datasheet来实现读写,相对要复杂一些。

SPI特点:

1、SPI的寻址方式是主设备向从设备的片选线上发送使能信号,表示选中该从设备,注意如果 在单片机的接口当中只有一个NSS接口,因此是只能够连接一个外部设备的,如果我们要连接多个外设就需要通过利用单片机中的其它IO口来模拟NSS接口。因此在接多个设备的情况下就要占用多个IO口了,这也是SPI通信的一个缺点,这一点就不如IIC的寻址方式。
2、SPI总线在进行数据传输时,先发高位,后发低位(这一点跟USART有区别),而且发完一个字节不用应答。

3、时钟线在上升沿或者下降沿是发送数据,然后在下降沿或者上升沿接收数据

SPI主从连接示意图

         图中可以看出虽然 SPI 也是串行通信协议,但是主机所占用的引脚依然比 IIC 和 UART 的多,而且主机引脚数量会随着从机数量的增加而增加(增加对从机的选通部分)。

        主机在通过 MOSI 数据线发送数据的同时,从机也会通过 MISO 将数据传输给主机(收发 同时进行),它们以虚拟环形拓扑连接。数据通常先移出最高位,在时钟边沿,主机和从机 均移出一位,然后在传输线上输出给对方(改变数据)。在下一个时钟沿,主从设备的接收 器都从传输线接受该位,并设置为移位寄存器的新的最低有效位(采样数据)。在完成这样 一个移出-移入的周期后,主机和从机就交换了寄存器中的一位,传输可能会持续任意数量的时钟周期。传输完成后,主设备会停止时钟信号,并拉高 NSS 选通线。下图是 SPI 通信时序:

 SPI通信时序图

 SPI 是一种非常灵活的通信协议,我们可以配置它的时钟极性、时钟相位、一次传输的 数据位数等。我们依次来看一下:

⚫ 时钟极性(CPOL) 时钟极性用于设置时钟在空闲时的电平状态,CPOL 为 1 则时钟空闲时为高电平,CPOL 为 0,时钟空闲时为低电平,如下图。这就直接导致了第一个信号沿是下降沿还是上升沿, 通常 CPOL 和时钟相位(CPHA)配合使用。

⚫ 时钟相位(CPHA) 时钟相位用于设置在第几个时钟沿发生时对数据线进行采样,当 CPHA=1 时表示在第二 个时钟沿对数据线进行采样,当 CPHA 为 0 时,在第一个时钟沿对数据进行采样,如下图:

 另外在图中可以看到,CPOL 和 CPHA 的组合能够产生 4 中不同的工作模式,以适应不同 的使用场景。具体的模式由具体的芯片手册参考设置,一般建议 CPOL=CPHA=0,CPOL=CPHA=1。

SPI 内部结构框图:

 STM32 的 SPI 外设包含两种通信协议,第一个是 SPI 协议,第二个是 I2S 协议,他们通过 SPI_I2S 配置寄存器(SPI_I2S_CFGR)的 11 位 I2SMOD 进行选择。SPI 接口默认工作在 SPI 方式,可以通过软件把功能从 SPI 模式切换到 I2S 模式。在小容量和中容量产品上,不支持 I2S 音频协议。因为 STM32 将 SPI 和 I2S 合并到了一起,因此我们在使用 SPI 时要先设置该寄存器的 位 11 来指定使用 SPI 功能。 但是这些配置已经在固件库中定义好了,我们直接利用固件库中对应SPI函数库或者I2S函数库即可。

SPI 固件库:

ST 固件库主要使用 SPI_TypeDef 这个结构体类型来管理 SPI 外设。通过配置这个结构体来实现对 SPI 外 设的配置,并调用固件库提供接口函数中的初始化函数,实现将配置参数写入 STM32 寄存器中。SPI 外设的 接口函数如下所示:

配置 SPI 步骤如下:

1. 初始化 SCK、MOSI 引脚为复用推挽输出,初始化 MISO 引脚为浮空输入;

2. 初始化 NSS 引脚为推挽输出并默认拉高(使用软件 NSS 情况下);

3. 配置 SPI 初始化结构体,内容包括:主/从模式,高/低位在前,数据帧位数(8 位/16 位),配置时钟极性(CPOL)、时钟相位(CPHA)、软件 NSS、时钟分频值等。

SPI初始化配置:

void SPI2_Init(void){ //SPI2初始化
	SPI_InitTypeDef  SPI_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);//使能SPI_2时钟

	GPIO_InitStructure.GPIO_Pin = SPI2_MISO;  //SPI2的MISO(PB14)为浮空输入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(SPI2PORT,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = SPI2_MOSI | SPI2_SCK;	//SPI2的MOSI(PB15)和SCLK(PB13)为复用推免输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(SPI2PORT,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = SPI2_NSS;	 //SPI2的NSS(PB12)为推免输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(SPI2PORT,&GPIO_InitStructure);

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//双线输入输出全双工模式
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为SPI的主机模式(SCK主动产生时钟)
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//SPI数据大小:发送8位帧数据结构;8位还是16位需要根据需要根据具体的芯片手册参考来确定
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//空闲状态时SCK的状态,High为高电平,Low为低电平
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;//时钟相位,1表示在SCK的奇数沿边采样,2表示偶数沿边采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS由软件控件片选,只是针对点对点通信的情况下,如果是连接了多个设备,就要使用硬件模式,在通信之前手动选择哪一个设备通信。
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;//时钟的预分频值(0~256),保证总线的稳定性,如果总线稳定性不好就可以相对应加大预分频值
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //MSB高位在前
	SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC较验和的多项式,例如CH376芯片没有校验功能
	SPI_Init(SPI2,&SPI_InitStructure); //初始化SPI2的配置项
	SPI_Cmd(SPI2,ENABLE); //使能SPI2  
}

 接收发送函数:

//SPI2数据发+收程序(主要用于发送)
u8 SPI2_SendByte(u8 Byte){ //通过SPI2口发送1个数据,同时接收1个数据
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE) == RESET); //如果发送寄存器数据没有发送完,循环等待
	SPI_I2S_SendData(SPI2,Byte);  //往发送寄存器写入要发送的数据
	while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE) == RESET); //如果接受寄存器没有收到数据,循环
	return SPI_I2S_ReceiveData(SPI2);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SPI总线协议基本原理及相关配置 的相关文章

  • STM32的SPI

    1 SPI硬件层共有4个引脚SCK MISO MOSI NSS 不需要接上拉及下拉电阻等 2 SPI跟I2C一样是一种通讯总线 所以可以挂载多个从机 通过NSS片选引脚控制从机 3 SPI主模式时钟与挂载总线相关 STM32时钟为fpclk
  • RTT WK2412 spi-uart

    1 添加软件包 xff0c 打开硬件 2 代码里根据硬件配置spi span class token macro property span class token directive hash span span class token
  • i.MX6U SPI浅析

    1 SPI简介 SPI 全称是 SerialPerripheral Interface xff0c 也就是串行外围设备接口 SPI 是 Motorola 公司推出的一种同步串行接口 技术 xff0c 是一种高速 全双工的同步通信总线 xff
  • 一文搞懂——软件模拟SPI

    关于stm32通信协议 xff1a 软件模拟SPI 软件模拟I2C的总结 xff08 fishing 8 xff09 To be a fisher的博客 CSDN博客 stm32 软件spi 发现一篇写的软件模拟SPI的比较容易理解的博客
  • Linux SPI 驱动示例

    一 Linux 下 SPI 驱动框架 SPI 驱动框架分为主机控制器驱动和设备驱动 xff0c 主机控制器也就是 SOC 的 SPI 控制器接口 1 1 SPI 主机驱动 SPI 主机驱动就是 SOC 的 SPI 控制器驱动 xff0c L
  • Linux Platform总线+SPI总线分析

    2015 07 1 11 20 本文以MPC8308 powerpc架构 xff0c HX软件包为依据 xff0c 详细内容可参考源码 CPU e300c3MPC8308 400MHz BOARD Freescale MPC8308ERDB
  • spi,iic,uart,pcie区别

    一 spi SPI 是英语Serial Peripheral interface的缩写 xff0c 顾名思义就是串行外围设备接口 xff0c 是同步传输协议 xff0c 特征是 xff1a 设备有主机 xff08 master xff09
  • 什么是SPI通信

    ARM体系 SPI通信 一 什么是SPI通信 1 SPI是串行外设接口 Serial Peripheral Interface xff0c 可以理解为一种通信协议 xff0c 也就是用来传输数据的 2 SPI 是由摩托罗拉 Motorola
  • 总线协议一(UART/RS232/RS485/IIC/SPI)

    目录 基础概述 xff1a 一 UART xff08 为串口通信方式 xff09 二 RS232协议 三 RS485协议 四 I2C总线协议 五 SPI总线 六 I2C和SPI的区别 基础概述 xff1a 总线的本质就是一根导线 xff0c
  • STM32采集问答式串口传感器数据写入SD卡(spi模式)

    文章目录 1 实验工具2 接线说明3 部分代码说明1 文件的覆盖问题1 文件系统的文件打开方式2 移动文件初始写入指针位置 2 变量的转换及写入问题1 sprintf函数2 CSV文件创建 3 数据采集流程 xff08 主函数 中断函数处理
  • day3. -2 NX的SPI操作

    1 NVIDIA在线文档 https docs nvidia com jetson l4t index html page Tegra 20Linux 20Driver 20Package 20Development 20Guide hw
  • 沁恒CH32V307使用记录:SPI基础使用

    文章目录 目的 基础说明 使用演示 其它补充 总结 目的 SPI是单片机中比较常用的一个功能 这篇文章将对CH32V307中相关内容进行说明 本文使用沁恒官方的开发板 CH32V307 EVT R1沁恒RISC V模块MCU赤兔评估板 进行
  • Linux SPI 总线 和设备驱动架构之三:SPI控制器驱动

    通过第一篇文章 我们已经知道 整个SPI驱动架构可以分为协议驱动 通用接口层和控制器驱动三大部分 其中 控制器驱动负责最底层的数据收发工作 为了完成数据收发工作 控制器驱动需要完成以下这些功能 1 申请必要的硬件资源 例如中断 DMA通道
  • SPI总线verilog hdl实现(1)SPI通信

    SPI总线传输只需要4根线就能完成 这四根线的作用分别如下 SCK Serial Clock SCK是串行时钟线 作用是Master向Slave传输时钟信号 控制数据交换的时机和速率 MOSI Master Out Slave in 在SP
  • CH347读写SPI Flash

    前面耽搁了几天 今天终于把CH347 SPI接口调试好了 CH347动态库中SPI接口函数如下 typedef struct SPI CONFIG UCHAR iMode 0 3 SPI Mode0 1 2 3 UCHAR iClock 0
  • Linux,spidev:为什么它不应该直接在设备树中?

    我想定义一个具有用户模式访问权限的 SPI 设备 如中所述http linux sunxi org SPIdev 按照这些示例 我在设备树中添加了以下内容 ecspi1 other stuff mydev 0 compatible spid
  • 谁在驱动程序代码中调用“probe”函数?

    我试图理解thisomap2 panda 板的 mcspi 驱动程序代码 我不明白谁打电话probe函数以及调用链是什么this驱动代码 设备连接时如何通知驱动程序 探针函数由spi omap2 mcspi c保存在static struc
  • Arm 板上有两个以上的 SPI 设备,但只支持两个?

    我们其中一块板上的 Arm 处理器有一个 spi 端口 带有两条片选线 该处理器的数据表中提到它最多可以控制两个 spi 设备 是否可以使用 GPIO 作为附加 spi 设备的从选择 如何修改现有的库 设备驱动程序以支持此更改 到目前为止
  • 树莓派 pico rfid rc522 (Micropython)

    我想使用 RPi Pico 从 mfrc522 Iduino RFID rc522 读卡器读取数据 但我不知道如何操作 我试图使用为此目的制作的 mfrc522 py MicroPython 库 阅读器正在通过 SPI 与 Pi 通信 我将
  • 在 ARM 处理器上执行存储在外部 SPI 闪存中的程序

    我有一个 ARM 处理器 能够与外部闪存芯片连接 写入芯片的是为 ARM 架构编译的程序 可供执行 我需要知道如何将这些数据从外部闪存获取到 ARM 处理器上以供执行 我可以提前运行某种复制例程 将数据复制到可执行内存空间吗 我想我可以 但

随机推荐

  • 多旋翼飞行器设计与控制(二)—— 基本组成

    多旋翼飞行器设计与控制 xff08 二 xff09 基本组成 一 机架 1 机身 指标参数 xff1a 重量 xff1a 尽可能轻轴距 xff1a 外圈电机组成圆的直径材料 xff1a 冲碳纤维就完了布局 xff1a 2 起落架 作用 xf
  • 多旋翼飞行器设计与控制(六)—— 动态模型和参数测量

    多旋翼飞行器设计与控制 xff08 六 xff09 动态模型和参数测量 一 多旋翼控制模型 刚体运动学模型 跟质量与受力无关 xff0c 只研究位置 速度 姿态 角速度等参量 xff0c 常以质点为模型 刚体动力学模型 它与一般刚体动力学模
  • 多旋翼飞行器设计与控制(七)—— 传感器标定和测量模型

    多旋翼飞行器设计与控制 xff08 七 xff09 传感器标定和测量模型 一 三轴加速度计 三轴加速度计是一种惯性传感器 xff0c 能够测量物体的比力 xff0c 即去掉重力后的整体加速度或者单位质量上作用的非引力 当加速度计保持静止时
  • 【STM32】stm32通过地址操作寄存器

    stm32通过地址操作寄存器 0x01 stm32数据类型所占字节数0x02 如何查看寄存器地址 xff08 基地址 43 偏移地址 xff09 0x03 操作寄存器地址控制LED闪烁 xff08 代码 xff09 0x04 通过定义结构体
  • ARM裸机开发——启用SDRAM的按键中断控制灯实验

    写在前面 本文承接前文嵌入式系统学习 嵌入式系统 Linux环境搭建和LED灯闪烁实验 以S3C2440A作为开发平台 xff0c 以Linux中ARM Linux gcc交叉编译器作为编译环境进行学习 xff0c 由于本课程为单片机基础的
  • 二维vector

    span class token macro property span class token directive keyword include span span class token string lt iostream gt s
  • 13.request-session,验证码

    使用session使得请求变成一个对象 注意登录页面隐藏的参数 爬取古诗文登录页面 span class token keyword import span requests span class token keyword from sp
  • STM32-串口通信(串口的接收和发送)

    文章目录 STM32的串口通信一 STM32里的串口通信二 串口的发送和接收串口发送串口接收 三 串口在STM32中的配置四 串口接收的两种实现方式1 需要更改的地方2 查询RXNE标志位3 使用中断 总结 STM32的串口通信 本文在于记
  • quick sort(c++)以及k选取

    include lt iostream gt include lt vector gt using rank 61 int using namespace std int dash 61 0 int swap vector lt int g
  • STLINK CONNECTION ERROR 问题的解决

    打开STLINK UTILITY 连接芯片也连接不上 在settings里面 选择这个连接模式 xff0c 按下芯片复位键的同时 xff0c 点击连接 st link的灯闪烁红蓝相间的光表示连接成功 松开芯片reset xff0c 既连接成
  • 解决ros2安装出现的问题

    Cannot locate rosdep definition for python3 pytest 解决方法是输入弹幕命令 然后输入安装功能依赖的命令 如果有占用进程问题 xff0c 就重启 http t csdn cn WwqJa
  • conda activate 出错

    问题及解决办法 1 使用conda activate出错 在cmd中使用 conda bat activate 进入环境后在进行操作 2 conda install出错 xff0c 使用pip install 3 在cmd 中使用tenso
  • 树莓派4b 安装ubuntu20.04server和图形化界面遇到的问题

    树莓派安装图形界面参考教程 树莓派4b安装Ubuntu 18 04系统及图形桌面 树莓派4B安装 ubuntu20 04 amp VNC远程桌面 amp 安装ROS noetic 树莓派4b安装Ubuntu和ROS的完整爬坑记录 2021年
  • 【STM32】串口接收任意字符串

    目录 前言cube配置usart h xff1a usart cmain xff1a 效果 前言 之前写了一篇STM32hal库串口中断接收任意字符 实际上是不完美的 xff0c 他接收到换行符就完蛋了 花了点时间深入研究了一下hal库的串
  • 使用封装的axios发送请求

    使用封装的axios发送请求 1 src api api js 定义请求路由方法 span class token function import span URLS from span class token string 39 conf
  • STM32串口驱动

    首先了解串口通信的一些基本原理 xff1a 串口通信 xff1a 串口通信是指数据通过一条数据线 xff08 或者两条差分线 xff09 一位接着一位的传输出去 串口通信的优点是占用硬件资源少 xff0c 且传输距离较远 xff0c 缺点是
  • IIC 驱动OLED

    IIC总线可以驱动很多器件 xff0c 比较常见的有OLED EEPROM存储器 xff08 AT24C02 xff09 温度传感器 xff08 LM75A xff09 温湿度传感器 xff08 DHT11 xff09 等 有关IIC总线协
  • Stm32-使用TB6612驱动电机及编码器测速

    这里写目录标题 起因一 电机及编码器的参数二 硬件三 接线四 驱动电机1 TB6612电机驱动2 定时器的PWM模式驱动电机 五 编码器测速1 定时器的编码器接口模式2 定时器编码器模式测速的原理3 编码器模式的配置4 编码器模式相关代码5
  • CAN总线协议入门基础原理

    CAN 是 Controller Area Network 的缩写 xff08 以下称为 CAN xff09 xff0c 是 ISO 1 国际标准化的串行通信协议 CAN 通过 ISO11898 及 ISO11519 进行了标准化 xff0
  • SPI总线协议基本原理及相关配置

    单片机应用中 xff0c 最常用的通信协议主要有三个 xff0c 即USART IIC和SPI 关于前两个的介绍在之前文章学习过 xff0c 这次介绍一下第三个通信协议 SPI SPI Serial Peripheral Interface