SPI又是另一个超级常见的外设通信方式。

大部分图片来源:正点原子HAL库课程

 专栏目录:记录自己的嵌入式学习之路-CSDN博客


目录

1    基本概念

1.1    与IIC的区别

1.2    引脚

1.3    移位原理

1.4    四种工作模式

2    NOR Flash

2.1    25Q128系列 NOR Flash

2.2    25Q128存储结构

2.3    常用指令及其时序

2.4    重要的状态寄存器

2.5    读操作步骤

2.6    擦除扇区

2.7    写操作(极简版)

3    配置

3.1    相关HAL库函数

3.2    关键结构体

3.3    NOR Flash基本驱动步骤

4    QSPI

4.1    基本概念

4.2    SPI的分类


1    基本概念

SPI:串行外设设备接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线。主要应用在存储芯片、AD转换器以及LCD中。

1.1    与IIC的区别

  • SPI是边沿协议(以边沿的产生为信号),IIC是电平协议(以电平的高低为信号);
  • SPI可以选择MSB(高位)先发和LSB(低位)先发两种模式,一般是根据从机的需要进行选择;
  • SPI也可以只使用一根数据线,实现半双工通信。

1.2    引脚

MOSI(Master Out / Slave In):输出数据线

MISO(Master In / Slave Out):输入数据线

SCK(Serial Clock):时钟

NSS\overline{CS}):片选线,上方的横线代表低电平有效。实现上一般使用软件管理NSS,而将硬件的NSS引脚省下来用作他用。

软件管理CS的意思是:将主机配置为软件管理NSS,而从机的CS在物理上就可以连接MCU的任意一个IO了,只要和该从机通信的时候拉低该IO的电平即可。

1.3    移位原理

如上图,当时钟线产生一个上升沿触发时,主机和从机的最高位都会被传输到发送引脚上;当时钟线产生一个下降沿触发时,接收引脚上的数据将被写进移位寄存器中。通过8个时钟脉冲,一个字节的数据就被发送/接收完成了。也就是说,收发是同时进行的。所以:

  • 若主机只向从机进行写操作,可以忽略接收到的从机数据;
  • 若主机要对从机进行读操作,需要发送一个空数据来引发从机发送数据。

1.4    四种工作模式

  • 主机SPI的工作模式的选择要结合从机支持的模式来,因为从机不一定支持这么多模式;

2    NOR Flash

2.1    25Q128系列 NOR Flash

  • HOLD用于一主多从的通信;

2.2    25Q128存储结构

一片25Q128有256个块(Block),一个块有16个扇区(Sector),一个扇区有16页,一页有256个字节。最终算出来就是16M Byte/128M bit。

  • 擦除的单位:扇区、块、片
  • 写的单位:页写,与EEPROM的页写一样存在写完一页需要翻页的情况,否则再写会发生覆盖;
  • 地址长度:根据原件数据手册可知,为0- FFFFFFH;

2.3    常用指令及其时序

NOR FLASH的指令总数比较多, 但是如果只需要实现基本操作,还是比较简单的,一般我们只需要:5条指令即可完成对NOR FLASH的基本使用(以NM25Q128为例):

  • 写使能
    拉低片选→发送06H→拉高片选
  • 读SR1
    拉低片选→发送05H→返回SR1的值→拉高片选
    • 其中,05H、35H、15H分别对应SR1、SR2、SR3三个状态寄存器;
    • 若拿到SR1数据后不拉高片选,从机会持续发送SR1的数值;
  • 读数据
    拉低片选→发送03H→发送24位地址→读取数据1~n→拉高片选
    • 与读SR1类似,在发送完地址后,要是时钟线一直给脉冲,就会一直读数据;
  • 页写
    拉低片选→发送02H→发送24位地址→发送数据1~n→拉高片选
    • 页写命令最多可以向FLASH传输256个字节的数据,因为一页就256字节;
    • 与上面的命令一样,只要保持片选和时钟脉冲就可以持续写入;
  • 扇区擦除
    拉低片选→发送20H→发送24位地址→拉高片选
    • FLASH存储器的特性决定了它只能把原来为“1”的数据位改写成“0”,而原来为“0”的数据位不能直接改写为“1”;
    • 写入数据前,检查内存空间情况是否满足,不满足需擦除;

2.4    重要的状态寄存器

  • 除了上图所述的BUSY位和WEL位外,对大容量FLASH进行操作时还需要对ADP位进行操作;

2.5    读操作步骤

  • 分三次发送是因为帧格式那里设置了每帧8位;
  • 发送空字节是因为读写是同时进行的,要读就要发送写数据;

2.6    擦除扇区

  • 注意:发送要擦除的字节地址即可,Flash芯片会自动擦除该地址所在扇区;

2.7    写操作(极简版)


3    配置

3.1    相关HAL库函数

  • 使能时钟也可以放在HAL_SPI_MspInit()函数中;

3.2    关键结构体

  • Direction:选择双线全双工,SPI_DIRECTION_2LINES;
  • NSS:选择软件,SPI_NSS_SOFT;
  • TIMode:选择不开启,即默认的摩托罗拉模式,SPI_TIMode_DISABLE;
  • CRCCalculation:关闭CRC校验;
  • CRCPolynomial:找寄存器的默认值,7;

3.3    NOR Flash基本驱动步骤

  • 关键的函数:HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
    • pTxData:发送数据的指针;
    • pRxData:接收数据的指针;
    • Size:发送数据的数目,要是帧格式是字节就是字节数,帧格式是半字就是半字数;
    • Timeout:超时时间,例程内设置为1000;
  • 如果需要一次性发送16位数据(SPI的单帧数据格式可以设置为16位)
    • 方法1:在配置SPI时配置好16位帧格式,在发送数据时,则将数据指针强转为8位指针发送:
    • 方法2:配置SPI时依然配置为8位,但发送两个字节:
  • 一般SPI初始化完毕后最好发送一个0xFF,以达到清空数据寄存器的作用;
  • 注意️:GPIO应设置为初始上拉,以保证对一些有上下拉电阻功能的MCU,不会因为初始拉低而发生片选;
  • 注意️:设置传输速度前必须__HAL_SPI_DISABLE,失能SPI才行;
     

  • 读取数据时应发送一个空的8位数据出去,从而获得返回值,因为根据19.1.3,需要发送空数据以启动移位操作;
  • 发送24位地址需要分开三次发,高8位→中8位→低8位;
  • 每次操作完毕后记得拉高片选;
  • 这里的GPIO初始化指的是Flash芯片的片选引脚初始化;
  • 读、改、写的步骤是为了避免要写入的扇区原来就有数据,因此要先将扇区的数据读出来,然后放到一个大数组中;在大数组中写入自己需要写入的数据,然后擦除扇区,再将数组的数据写入扇区中;
  •  如在写入前不进行数据读取与比对,那么直接写入后与写入地址同扇区的数据将被擦除,因为擦除的最小单位是扇区;

4    QSPI

4.1    基本概念

STM32F1系列并没有QSPI的外设。了解有更快的SPI传输数据的方式即可。

4.2    SPI的分类

  • SPI加速的思路:复用更多的引脚做IO,以提高一次性传输的数据;

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部