IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> Stm32之SPI笔记(2021-08-07) -> 正文阅读

[嵌入式]Stm32之SPI笔记(2021-08-07)

Stm32之SPI笔记

1.32的SPI简介:

1)SPI简介:

  • 特点:高速(最快可达10MHZ)全双工,同步,不带应答;具有CRC校验。

  • 通讯线:

    • MISO (Master Input Slave Output) :对主机(从机)来说,数据发送(接收)线;

    • MOSI (Master Output Slave Input) :对主机(从机)来说,数据接收(发送)线;

    • SCLK (Serial Clock) :时钟线;

    • CS (Chip Select) :片选线(拉低即选中,有多少个从机就有多少个片选线);

      (在32作为主机时,此线位NSS 即 opNtional Slave Select)

注意:在SPI通讯时,作为主机的NSS线,必须一直保持高电平状态,原因见下 NSS分析

  • 需要注意的是:

    • SPI传输数据时同步的,即有8位数据送出就有8位数据传入(对于32来说可选16位或8位)。

      在我们要读数据的时候,作主机,采取的方式时发送一个空字节(0xff)以获取接收数据

    • SPI数据传输的时间通常都是在SCLK上升沿将数据放在移位寄存器上,下降沿时将数据送出;

      但对于32而言,送出数据的时间可以选择(需要根据外设的不同要求来选择),即SPI_CR1[0]的CPHA位可控制,是第一个跳变沿,还是第二个跳变沿采集数据。

2)32的SPI:

Stm32的SPI具有以下的特点:

  • 支持SPI和I2S协议;(下文只介绍SPI)
  • 可选单次传输的数据位(8/16);可选空闲极性和采集跳变沿;可选时钟频率。
  • 可选MSB(Most Significant Bit)高位在前先发,或者是LSB(Least Significant Bit)低位在前先发。
  • 可使用自动的硬件片选引脚(NSS),也可自己使用IO口软件模拟。
  • 可产生中断及DMA.

2.相关寄存器简介:

1)控制寄存器(2个):

  • SPI_CR1:主要是对SPI的主从模式[15] , 单双向[14] , CRC使能[13] , 数据帧格式DFF[11] , 设备选择管理(片选方式)SSM[9] ,帧格式(MSB还是LSB在前)[7] ,SPI使能[6] , 波特率设置[5:3] , 主从模式的选择[2] , 和时钟极性CPOL [1] 和 时钟相位CPHA [0] 的选择 等的配置;(主要介绍以下几个位):

    • BR (Baud Rate control) [ 5:3]:用于选择波特率的时钟的分频系数;(因为在与不同设备通讯时,可能需要不同的速率,常常需要改变,但库函数无对应的函数),具体分频效果如下:

      BR[5:3]000001010011100101110111
      对 fPCLK的分频系数fPLCK/2fPLCK/4fPLCK/8fPLCK/16fPLCK/32fPLCK/64fPLCK/128fPLCK/256
    • SSM: (Software Slave Management) :0时NSS引脚与外部的NSS相连,1时NSS引脚的电平状态交由软件控制。

    • SSI: (Internal slave select):当SSM为1是,NSS引脚的电平状态交由软件控制,软件即通过SSI该位配置内部NSS的电平。

      有关NSS这两位的配置,参考NSS分析

    • CPOL (Clock Polarity) 时钟极性,CPHA (Clock PHAse) 时钟极性:见下图,即数据是在一个脉冲周期内的第一个跳变沿,还是第二个跳变沿发出(或接收)的区别,而具体是上升沿还是下降沿与CPOL,空闲时的极性有关。我们的选择主要取决于从机的要求。

2)状态寄存器:

SPI_SR:只有低8位有效,是对应,总线忙[7],模式错误[5],CRC错误[4],发送缓冲区空[1],接收缓冲区非空[0]等的1标志位。

3)数据寄存器:

SPI_DR:共16位,读写的数据时均是对这个寄存器进行操作,但内部对应着读写两个缓冲区,在数据帧选择8位时,高8位将会被强制为0;

4)与CRC相关的寄存器(3个):

  • SPI_CRCPR (CRC Polynomial Register):CRC多项式寄存器,16位存放CRC计算时用到的多项式值;

  • SPI_RxCRCR:接收CRC寄存器,16位存放接收字节计算的CRC值;

  • SPI_TxCRCR:发送CRC寄存器,16位存放发送字节计算的CRC值;

5)与I2S相关的寄存器:

  • SPI_I2S_CFGR (Conficog Register) :低12位有效;只有[11]位与SPI 有关,0为SPI模式,1为I2S模式。

  • SPI_I2SPR:I2S模式下的I2S预分频寄存器,与SPI 无关。

3.有关NSS分析

  • 做主机时SPI的内部NSS必须保持高电平状态(做CS输出时不用),片选中的从机的CS通讯中要保持低电平状态;

  • 作为从机时,内部NSS充当被片选的CS线

    因为如下图(取自芯片手册):

    • 主模式时:

      • 若SSM=0,即将外部NSS与内部NSS相连,此时:

        • 1??若使能外部NSS引脚的输出,即SSOE=1,则外部的NSS可做CS来拉低从机的片选,但工作在单主模式中(其为主机);

        • 2??若没有使能外部NSS输出,即SSOE=0,则外部NSS必须保持高,以维持内部的NSS为高,保证MSTR和SPE位正常,才能保证以主模式工作;

      • 若SSM=1;即用SSI与内部的NSS相连,此时:

        • 3??只需将SSI置高,维持主模式,再用另一个IO来做CS拉低片选从机即可*(这个IO口可以时外部的NSS引脚,因为此时,外部NSS已经释放,可做普通IO使用)*
    • 从模式时:

      • 若SSM=0,即将外部NSS与内部NSS相连,此时:

        • 4??由于作为从机,不需要保持内部NSS为高,可直接将外部的CS线通过外部NSS接入内部的NSS,即可作为从机被拉低选中;
      • 若SSM=1;即用SSI与内部的NSS相连,此时:

        • 5??此时外部NSS被释放可做普通IO,而片选的CS信号,则需要由SSI来用软件负责拉低。

可以看出作为主机时使用3??比较方便*(而且因为对外是使用任意IO模拟CS,可连接多个设备)*,而作为从机时,使用4??比较方便。

需要注意作为使用硬件NSS时,可能需要反复开关SPI的操作。
以下是根据NSS画的两个示意图(第一次使用meriad画图,感觉有些乱,见谅)

从模式
SSM=0
SSM==1
被选中时拉低为0
SSM==0
SSM==1时
软件通过SSI拉低内部做为CS的NSS
图中实线表示SSM=0时,虚线表示SSM=1时
从模式
外部NSS
从模式内部NSS引脚相当CS
内部NSS
SSM
SSI
可做普通IO
主模式
SSM==1
SSM==1
SSM==1
SSM==0
SSM==0
通过外部NSS线拉低
图中实线表示SSM=0时,虚线表示SSM=1时
主模式时,需要保持作为主机的内部SPI的NSS为高,拉低从机SPI的CS
外部从机的CS
SSI
SSM
内部NSS
另一个外部IO口将CS拉低
可做普通IO使用
外部NSS
SSOE为1,即外部NSS可作为CS输出
SSOE决定外部的NSS输出状态使能
SSOE为0,外部NSS必须保持高,以维持内部NSS的高电平,同样需要另一个IO拉低CS

4.库函数使用:

Stm32中SPI的库函数使用与串口一样简单,步骤如下:

  • 使能对应IO口及时钟;

  • 使能对应SPI(1/2/3)的时钟,即初始化填入结构体;结构体成员分析如下:

    typedef struct
    {
     uint16_t SPI_Direction;//通信方式的配置,全/半双工,串行发送/接收;
     uint16_t SPI_Mode; //主Master/从Slave模式
     uint16_t SPI_DataSize; //8b/16b位数据帧
     uint16_t SPI_CPOL; //空闲极性High/Low
     uint16_t SPI_CPHA; //时钟相位1Edge/2Edge
     uint16_t SPI_NSS; //CS引脚软件Soft还是硬件控制
     uint16_t SPI_BaudRatePrescaler; //波特率的分频系数参数..._2/4/.../256
     uint16_t SPI_FirstBit; //高位MSB在前还是低位LSB在前
     uint16_t SPI_CRCPolynomial; //CRC校验多项式值,默认值为0x07,通常自己也填7
    }SPI_InitTypeDef
    
  • 使能对应的SPI,使用SPI_Cmd()。

  • 注意:在使用SPI读写数据时,用while等待对应标志位,

    • 通常在SendData 前会检查发送缓冲区是否以空,对应的标志位是否已经置位;

      SPI_SR[1]TXE:发送缓冲区空标志,1以空,0非空

      或者是SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)

    • 通常在ReceiveData 前会检查接收缓冲区是否非空,对应的标志位是否已经置位;

      SPI_SR[0]RXNE:接收缓冲区非空标志,1以非空,0空

      或者是SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE)

    • 如果使用软件控制NSS,记得在数据传输前拉低CS连接的IO,传输完成后拉高CS连接的IO.

5.Flash W25Qxx介绍:

1)简介:

  • 其中的W25QXX,XX指的是XX MBit,所以根据8Bit=1Byte,就是128MBit=16M(Byte);

  • 当其中为空时,数据为0xff;

  • 进行写操作时,先检验其中所要写的区域是否为空,

    • 不为空,则将整个扇区(Sector)复制到4k的缓存(W25QXX_BUFFER)中,在对缓存的对应地址进行改写后,将整个扇区(Sector)擦除,再将缓存写入整个扇区。

    • 如果为空,则直接从对应地址开始将数据写入覆盖即可。

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-08-08 11:29:42  更:2021-08-08 11:31:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 1:06:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计