stm32----SPI协议

news2024/11/17 7:44:48

一、概述

SPI(Serial Peripheral Interface,串行外围设备接口),是Motorola公司提出的一种同步串行接口技术,是一种高速、全双工、同步通信总线,在芯片中只占用四根管脚用来控制及数据传输,节约了芯片pin的数目,同时为PCB在布局上节省了空间。正是由于这种简单易用的特性,现在越来越多的芯片上都集成了SPI技术。这4根线分别是:MOSI(主机输出从机输入)、MISO(主机输入从机输出)、SCLK(时钟同步)、CS(片选线)。

寻址方式:和IIC不同的是,IIC采用的是通过广播目标从机ID的方式来找到想要通信的从机设备。而SPI里面则是通过使能片选线CS(即chip select)的方式来选择目标从机,至于片选信号是高电平还是低电平则需视实际情况而定,通常采用较多的是低电平进行片选操作。还需要注意一点,同一时刻主机只能与一个从机进行通信。

二、特点

  1. 采用主从模式(Master-Slave)的控制方式,支持单Master多Slave

SPI规定了两个SPI设备之间通信必须由主设备Master来控制从设备Slave。一个Master可以通过提供clock以及对Slave进行片选(Slave Select)来控制多个Slave,但同一时刻只能选择一个从机进行通信。SPI协议还规定Slave设备的clock由Master通过SCK管脚提供给Slave,Slave本身不能产生或控制clock,没有clock则Slave不能正常工作。

2、采用同步方式(Synchronous)传输数据

Master会根据将要交换的数据产生相应的时钟脉冲,组成时钟信号,时钟信号通过时钟极性(CPOL)和时钟相位(CPHA)控制两个SPI设备何时交换数据以及何时对接收数据进行采样,保证数据在两个设备之间是同步传输的。

3、数据交换

SPI设备间的数据传输被称为数据交换,因为SPI协议规定一个SPI设备不能在数据通信过程中仅仅充当一个发送者(Transmitter)或者接受者(Receiver)。在每个clock周期内,SPI设备都会发送并接收1 bit数据,相当于有1 bit数据被交换了。数据传输高位在前,低位在后(MSB first)。

在数据传输过程中,每次接收到的数据必须在下一次数据传输之前被采样也就是要马上从信号线中读取过来,可以理解为一个只能存放一个快递的快递站中的快递到了,得马上去取,不然会影响接下来的快递,如果之前接收到的数据没有被读取,那么这些已经接收完成的数据将有可能被丢弃,导致SPI物理模块最终失效。因此在程序中一般都会在SPI传输完数据后,读取SPI设备里的数据,即使这些数据在程序里是无效的。

SPI总线四种工作方式 

SPI 模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响。

   时序详解:

CPOL:时钟极性选择,为0时SPI总线空闲为低电平,为1时SPI总线空闲为高电平

CPHA:时钟相位选择,为0时在SCK第一个跳变沿采样,为1时在SCK第二个跳变沿采样

通信过程举例 

比如当CPOL = 1,CPHA=1的时候,此时,SCK空闲电平状态为高电平,并在第二个时钟沿开始采样,第一个时钟沿开始进行输出。

在时钟线第一个跳变沿,发送器将会在数据线上发送一位数据,如果要发送1则将数据线拉高,如果要发送0则将数据线拉低,过段时间以后,此时数据线上的状态已经确定,即数据已经发出了,紧接着在第二个跳变沿,接收器将会从数据线上接收一位数据。一个字节占8位,所以只需要8个时钟周期(一个时钟周期有两个边沿)即可完成一个字节数据的传输。与IIC不同的是,SPI是没有应答信号的

三、数据传输

SPI是一个环形总线结构,由SS (CS)、SCK、SDI、SDO构成,时序很简单,在SCK的控制下,两个双向移位寄存器进行数据交换。寄存器中的内容全部移出时,相当于完成了两个寄存器内容的交换。SSPSR控制数据移入移出SSPBUF,controller确定SPI总线的通信模式。

SSPBUF:Synchronous Serial Port Buffer,泛指SPI设备里面的内部缓冲区,一般在物理上是以FIFO的形式,保存传输过程中的临时数据;

SSPSR:Synchronous Serial Port Shift Register,泛指SPI设备里面的移位寄存器,根据设置好的数据位宽把数据移入或移出SSPBUF;

Controller:泛指SPI设备里面的控制寄存器,通过配置寄存器来设置SPI总线的传输模式。

通常情况下,只需要对四个pin进行编程即可控制SPI设备之间的数据通信:

SCK(Serial Clock):主要作用是Master向Slave传输时钟信号,控制数据交换的时机和速率;

SS/CS(Slave Select/Chip Select):用于Master片选Slave,使被选中的Slave能够被Master访问;

SDO/MOSI(Serial Data Output/Master Out Slave In):在Master上也被称为Tx-channel,作为数据的出口,主要用于SPI设备发送数据;

SDI/MISO(Serial Data Input/Master In Slave Out):在Master上也被称为Rx-channel,作为数据的入口,主要用于SPI设备接收数据。

四线制SPI:CS,SCK(同步时钟),MOSI(master out slaver in),MISO:全双工

三线制SPI:CS,SCK,DIO:半双工,只能分时进行收发

注意在主机开始接收从机数据的时候,同时要发一个0xFF给从机。

原来是spi 主机在接收的时候也把移位寄存器中的数据通过mosi发送出去了,从slave看,它通过miso发送数据给master的同时也接收来自master mosi上的数据。因为spi协议是没有反馈信号的,所以slave在发送数据的同时接收到的数据如果是slave能够识别的一个命令值的话那么这时就会对slave产生影响了。这时slave就会按照新的命令运行,然而这个命令是master在接收slave数据时不经意发送出去的,它本身是不打算发送出去的。为了解决master在接收数据的同时误发命令,所以在接收数据之前先写0xff进入移位寄存器。这样master在接收来自slave的数据的同时发送0xffslaveslave不识别0xff这个命令自然就不会影响它本身的运行了。

上面说了一大堆东西,现在你就会发送其实也不一定要写0xff是不是啊?是的,只要接收数据之前往移位寄存器写一个slave无法识别的数据就行了。

四、IIC和SPI协议之间的异同

相同点:

  1. 均采用串行同步的通信方式
  2. 均采用TTL电平,传输举例和应用场景较为类似。(RS232则采用负逻辑电平)
  3. 均采用主从工作方式。

不同点:

  1. IIC为半双工,SPI为全双工(也可配置为半双工模式)
  2. IIC有应答机制、SPI无应答机制
  3. IIC通过总线广播从机设备地址方式进行寻址,SPI通过片选线进行寻址
  4. IIC空闲电平状态固定为高电平(上拉电阻),SPI的SCLK空闲电平状态取决于时钟极性CPOL。

五、STM32F1芯片上的SPI

1、STM32F1的SPI 接口提供两个主要功能,支持 SPI 协议或 I2S 音频协议。STM32F1的SPI时钟最高可以到 36MHz,支持 DMA功能。STM32F1的SPI内部结构图:

标号1

SPI接口引脚,其中有MOSI、MISO、SCK、NSS(即CS)。

我们在配置的时候,需要查看原理图,其中MOSI、MISO、SCK需要单独配置,至于片选线NSS我们通常使用一个普通IO口就可以了,具体引脚参考电路原理图通过软件拉高拉低来产生片选信号。

我们可以查看中文参考手册关于芯片架构章节发现SPI1是挂接在APB2总线上的,SPI2和SPI3挂接在APB1总线上,根据SPI工作频率特性,SPI理论最大频率是其所在总线的一半,即SPI1理论最大工作频率可达72/2=36MHz,SPI2和SPI3理论最大工作频率可达36/2=18MHz。

标号2

是用于产生SCK频率的波特率发生器,我们是SCK时钟信号是波特率发生器根据SPI_CR1寄存器的BR0~BR2这几个位进行控制的。这几个位可以绝对时钟分频因子。

具体可以查看中文参考手册:

 

 

标号3

数据控制逻辑。SPI的MOSI和MISO都连接在数据移位寄存器当中。数据移位寄存器内容来源于接收缓冲区和发送缓冲区,还有MOSI和MISO。

假设将此SPI设备(即单片机)配置为主模式,如果是发送数据,则数据通过发送缓冲区进入到移位寄存器,再通过MOSI将数据发送出去。接收数据则是通过MISO将数据接收进来,接收到移位寄存器并进入接收缓冲区,再进入到总线进行传输。

 

 

标号4

寄存器单元。用于控制SPI的相关工作模式,包括主从模式,低位先行还是高位先行,波特率分频是多少,一次传送8位还是16位等等,具体的参考中文参考手册。

  1. SPI配置步骤(只是例子,具体的还得看实际芯片原理图和手册)

(1)使能SPI及对应GPIO端口时钟并配置引脚的复用功能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //PB13/14/15复用推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOB, &GPIO_InitStructure);

(2)初始化SPI,包括数据帧长度、传输模式、MSB和LSB顺序等

void SPI_Init(SPI_TypeDef* SPIx, SPI_InitTypeDef* SPI_InitStruct);

typedef struct

{

uint16_t SPI_Direction;   //设置SPI的单双向模式

uint16_t SPI_Mode;       //设置 SPI 的主/从机端模式

uint16_t SPI_DataSize;  //设置 SPI 的数据帧长度,可选 8/16 位

uint16_t SPI_CPOL;     //设置时钟极性 CPOL,可选高/低电平

uint16_t SPI_CPHA;    //设置时钟相位,可选奇/偶数边沿采样

uint16_t SPI_NSS;  //设置 NSS 引脚由 SPI 硬件控制还是软件控制

uint16_t SPI_BaudRatePrescaler;//设置时钟分频因子

uint16_t SPI_FirstBit;   //设置 MSB/LSB 顺序

uint16_t SPI_CRCPolynomial; //设置 CRC 校验的表达式

}SPI_InitTypeDef;

SPI_Direction:用于设置 SPI 的通信方向,可设置为双线全双工(SPI_Direction_2Lines_FullDuplex),双线只接收(SPI_Direction_2Lines_RxOnly),单线只接收(SPI_Direction_1Line_Rx)、单线只发送模式(SPI_Direction_1Line_Tx)。

SPI_Mode:用于设置 SPI 工作在主机模式(SPI_Mode_Master)或从机模式(SPI_Mode_Slave ),这两个模式的最大区别为 SPI 的 SCK 信号线的时序, SCK 的时序是由通讯中的主机产生的。若被配置为从机模式, STM32 的 SPI 外设将接受外来的 SCK 信号。

SPI_DataSize:用于设置SPI通信的数据帧长度,可以选择8位(SPI_DataSize_8b)或者 16 位(SPI_DataSize_16b)。

SPI_CPOL:用于设置时钟极性,可设置为高电平(SPI_CPOL_High)或低电平(SPI_CPOL_Low )。

SPI_CPHA:用于设置时钟相位,也就是选择在串行同步时钟的第几个跳变沿(上升或下降)数据被采样,可以为 SPI_CPHA_1Edge(在 SCK 的奇数边沿采集数据) 或SPI_CPHA_2Edge (在 SCK 的偶数边沿采集数据) 。

SPI_NSS:用于设置NSS引脚的使用模式,可以选择为硬件模式(SPI_NSS_Hard )与软件模式(SPI_NSS_Soft ),在硬件模式中的 NSS信号由 SPI 硬件自动产生,而软件模式则需要我们使用相应的 GPIO 端口来控制。

SPI_BaudRatePrescaler:用于设置波特率分频因子,分频后的时钟即为 SPI 的 SCK 信号线的时钟频率。可设置为 fpclk 的 2、 4、 6、 8、 16、 32、 64、 128、 256 分频。

SPI_FirstBit:用于设置数据传输顺序是 MSB 位在前还是 LSB 位在前。

SPI_CRCPolynomial:用于设置 CRC 校验多项式,提高通信可靠性。

举例

SPI_InitTypeDef  SPI_InitStructure;

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工

SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI

SPI_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; //定义波特率预分频的值:波特率预分频值为256

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始

SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式

SPI_Init(SPI1, &SPI_InitStructure);  //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

(3)使能(开启)SPI

void SPI_Cmd(SPI_TypeDef* SPIx, FunctionalState NewState);

(4)SPI数据传输

void SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);

uint16_t SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);

(5)查看SPI传输状态

FlagStatus SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);

使用较多的是发送完成标志(SPI_I2S_FLAG_TXE)和接收完成标志(SPI_I2S_FLAG_RXNE)

SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE);

  1. EN25QXX介绍

EN25QXX 是大容量 SPI FLASH 产品,EN25Q64的容量是64Mb(8M字节),EN25Q128 的容量为 128Mb(16M字节),该系列还有EN25Q08/16/32/64 等。我们开发板上使用的是EN25Q16,学习这个芯片可以参考华邦公司的W25Q128芯片,因为它们是完全兼容的。所以我们以W25Q128进行介绍。

W25Q128 将 16M 的容量分为 256 个块( Block),每个块大小为 64K 字节,每个块又分为16 个扇区( Sector),每个扇区 4K 个字节。 W25Q128 的最小擦除单位为一个扇区,也就是每次必须擦除 4K 个字节。这样我们需要给 W25Q128 开辟一个至少 4K 的缓存区,这样对 SRAM 要求比较高,要求芯片必须有 4K 以上 SRAM 才能很好的操作。

W25Q128 的擦写周期多达 10W 次,具有 20 年的数据保存期限,支持电压为 2.7~3.6V,W25Q128 支持标准的 SPI,还支持双输出/四输出的 SPI,最大 SPI 时钟可以到 80Mhz(双输出时相当于 160Mhz,四输出时相当于 320M)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/947146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter性能测试入门完整版

1. Jmeter简介 Apache JMeter是一款纯java编写负载功能测试和性能测试开源工具软件。相比Loadrunner而言,JMeter小巧轻便且免费,逐渐成为了主流的性能测试工具,是每个测试人员都必须要掌握的工具之一。 本文为JMeter性能测试完整入门篇&…

IT项目标准实施流程

一、IT项目标准实施流程、参与角色与职责架构图 二、IT项目阶段交付文档明细目录 NO. 阶段 中文名称 英文名称 缩写 是否必须 1 1.分析 1.1 项目业务需求分析文档 Business Requirement analysis Document BRD X 2 2.设计 2.1 硬件&软件配置清单 Bill Of Ma…

Excel:如何实现分组内的升序和降序?

一、POWER 1、构建辅助列D列,在D2单元格输入公式: -POWER(10,COUNTA($A$2:A2)3)C2 2、选中B1:D10,注意不能宣导A列的合并单元格,进行以下操作: 3、删除辅助列即可 二、COUNTA 第一步,D2建立辅助列&#xf…

6.Redis-hash

hash 哈希类型中的映射关系通常称为field-value,⽤于区分 Redis 整体的键值对(key-value),注意这⾥的value是指field对应的值,不是键(key)对应的值,请注意 value 在不同上下⽂的作⽤…

同源策略与解决方法

同源策略与解决方法 1.浏览器的同源策略 1.1 同源策略 同源策略(same origin policy),一种安全策略,用于限制一个源的文档或者它加载的脚本如何能与另一个源的资源进行交互。 浏览器默认两个不同的源之间是可以互相访问资源和…

reactantd(12)动态表单的默认值问题

最近遇到一个需求是有一个表单可以输入各种信息,然后还需要有一个编辑功能,点击编辑的时候需要把当前数据填入到表单里面。在网上查了很多种方法,然后我的思路是使用initialValues搭配setState()使用。默认值都为空,然后点击单条数…

Microsoft Edge 主页启动diy以及常用的扩展、收藏夹的网站

一、Microsoft Edge 主页启动diy 二、常用的扩展 1、去广告:uBlock Origin 2、翻译: 页面翻译:右键就有了,已经内置了划词翻译 3、超级复制 三、收藏夹的网站

函数(个人学习笔记黑马学习)

1、函数定义 #include <iostream> using namespace std;int add(int num1, int num2) {int sum num1 num2;return sum; }int main() {system("pause");return 0; } 2、函数的调用 #include <iostream> using namespace std;int add(int num1, int num2…

java内存模型讨论及案例分析

常用内存选项 -Xmx&#xff1a; 最大堆大小 -Xms&#xff1a;最小堆大小 -Xss &#xff1a;线程堆栈大小&#xff0c;默认1M 生产环境最好保持 Xms Xmx java内存研究 内存布局 可见&#xff1a; 堆大小 新生代 老年代&#xff0c;新生代EFrom SurvivorTo Survivor。新…

【数学建模竞赛】各类题型及解题方案

评价类赛题建模流程及总结 建模步骤 建立评价指标->评价体系->同向化处理&#xff08;都越多越好或越少越少&#xff09;->指标无量纲处理 ->权重-> 主客观->合成 主客观评价问题的区别 主客观概念主要是在指标定权时来划分的。主观评价与客观评价的区别…

Vulnhub内网渗透DC-6靶场通关

个人博客 xzajyjs.cn IP DC-6: 192.168.168.4 Kali: 192.168.168.5 信息搜集 arp-scan -l # nmap -sn 192.168.168.0/24进行主机发现&#xff0c;探测到靶机IP。 使用nmap进行端口扫描 nmap -sV -A 192.168.168.4开放了一个ssh和http端口&#xff0c;80端口是wordpress5.1…

MinIO框架安装使用+实现上传需求

MinIO框架 什么是MinIO框架如何安装&#xff08;Docker版&#xff09;安装步骤1. 查询MinIO的服务版本2. 拉取MinIO3.启动报错在docker中没有操作文件的权限 4. 访问 简单配置1.找到创建用户界面2. 设置用户信息3. 创建一个桶 使用MinIO依赖搭建MinIO的初始化API存储桶的基本操…

uniapp 开发小程序,封装一个方法,让图片使用线上地址

1.在main.js文件中&#xff0c;添加以下代码&#xff1a; 复制使用&#xff1a; // 图片使用网络地址 Vue.prototype.localImgSrc function(img){//项目的地址域名&#xff0c;例如百度return "https://baidu.cn/static/index/images/" img; }2.在页面中直接使用&…

PMP是什么?项目管理证书好考吗?

PMP是由项目管理协会&#xff08;Project Management Institute&#xff0c;简称PMI&#xff09;发起的项目管理专业人士资格认证&#xff0c;严格评估项目管理人员知识技能是否具有高品质的资格认证考试。PMP证书究竟难不难考呢&#xff1f;接下来的文章将简要讨论PMP证书的考…

git 基础

1.下载安装Git&#xff08;略&#xff09; 2.打开git bash窗口 3.查看版本号、设置用户名和邮箱 用户名和邮箱可以随意起&#xff0c;与GitHub的账号邮箱没有关系 4.初始化git 在D盘中新建gitspace文件夹&#xff0c;并在该目录下打开git bash窗口 git init 初始化完成后会…

【微服务部署】06-日志集成

文章目录 1. EFK日志三件套集成1.1 核心组件1.2 部署 2. Exceptionless日志系统2.1 Exceptionless核心特性2.2 Exceptionless部署文件2.3 K8s中使用Exceptionless 1. EFK日志三件套集成 1.1 核心组件 Elasticsearch&#xff08;存储&#xff09;Fluentd&#xff08;收集器&am…

文件上传漏洞-upload靶场3-4(全网最详细解读)

文件上传漏洞-upload靶场3-4关通关笔记&#xff08;全网最详细解读&#xff09; upload 第三关&#xff08;特殊后缀&#xff09; 思路 按照第一关和第二关的思路&#xff0c;先随便上传一个文件用burpsuite工具抓包&#xff0c;看它到底是前段验证还是后端验证。 上传一个we…

ADB安装及命令-自用查询

常用ADB命令整理 ADB简介常用命令整理查看设备及安装卸载屏幕事件⽇志查询查询系统服务情况其它 adb 命令 ADB安装ADB连接设备Android 实体机连接准备Android 虚拟机连接准备 ADB简介 ADB&#xff0c;即 安卓调试桥 (Android Debug Bridge, adb)&#xff0c;它是 Android 开发…

分布式系统的多数据库,实现分布式事务回滚(1.7.0 seata整合2.0.4nacos)

正文 1、解决的应用场景是分布式事务&#xff0c;每个服务有独立的数据库。 2、例如&#xff1a;A服务的数据库是A1&#xff0c;B服务的数据库是B2&#xff0c;A服务通过feign接口调用B服务&#xff0c;B涉及提交数据到B2&#xff0c;业务是在B提交数据之后&#xff0c;在A服…

数学建模:层次分析法

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 层次分析法 步骤描述 将问题条理化&#xff0c;层次化&#xff0c;构建出一个有层次的结构模型。层次分为三类&#xff1a;目标层&#xff0c;准则&#xff08;指标&#xff09;层&#xff0c;方案层。比…