SPI读写外部FLASH

前言

1、SPI 协议是由摩托罗拉公司提出的通讯协议 (Serial Peripheral Interface),即串行外围设备接口,是一种高速全双工的通信总线。它被广泛地使用在 ADC、LCD 等设备与 MCU 间,要求通讯速率较高的场合。
2、主机发送一个字节数据到从机,同时从机也会发送一个字节数据到主机(写操作和读操作是同步完成的,如果只想进行写操作,只需忽略接收到的字节即可。如果要读一个字节,就需要发送一个空字节来引发从机的传输)
3、W25Q128将16M的容量分为256个块(block),每个块大小为64K字节,每个块又分为16个扇区(sector),每个扇区4K字节。W25Q128的最小擦除单位为一个扇区,也就是每次必须擦除4k字节。这样我们需要给W25Q128开辟一个至少4K的缓存区,这样对SEAM要求比较高,要求芯片必须有4k以上SRAM才能很好的操作。
4、W25Q128支持标准SPI,还支持双输出/四输出的SPI,最大SPI时钟可以达到80Mhz(双输出时相当于160Mhz,四输出时相当于320Mhz)
5、我觉得HAL库的回调函数,就是不管使能了什么中断,都是进入这个回调函数中,然后通过判断中断标志位选择相应的中断回调函数。而中断和DMA应该都是直接调用一个函数就行了,看下回调函数中相应的位置有没有把相应的中断标志位给取消掉,一般都是取消了的,然后用的时候再调用。
6、接线方面,主机的MISO接从机的MISO。因为从机知道自己是从机,他的命名就是站在自己是从机的角度上命名的。

SPI讲解

在这里插入图片描述

使用简介

在这里插入图片描述
1、SPI 通讯使用 3 条总线及片选线,3 条总线分别为 SCK、MOSI、MISO,片选线为 SS

  • SS*(* Slave Select):片选信号线,也称为NSS/CS。当有多个 SPI 从设备与 SPI 主机相连时,共用SCK、MOSI 及 MISO这 3 条总线; SPI 协议中没有设备地址,它使用 NSS 信号线来寻址,当主机要选择从设备时,把该从设备的 NSS 信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行 SPI 通讯。所以 SPI 通讯以CS 线置低电平为开始信号,以NSS 线被拉高作为结束信号。
  • SCK (Serial Clock):时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 SPI 时钟频率最大为 fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。
  • MOSI (Master Output,Slave Input):主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。
  • MISO(Master Input,,Slave Output):主设备输入/从设备输出引脚。主机从这条信线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。

2、STM32 的 SPI 外设:

  • 可用作通讯的主机及从机
  • 支持最高的 SCK 时钟频率为 fpclk/2 (STM32F103 型号的芯片默认 f:sub:pclk1 为 72MHz,fpclk2 为 36MHz)
  • 完全支持 SPI 协议的 4 种模式
  • 数据帧长度可设置为 8 位或 16 位
  • 可设置数据 MSB 先行或 LSB 先行。
  • 支持双线全双工 (前面小节说明的都是这种模式)、双线单向以及单线模式。
  • 其中双线单向模式可以同时使用 MOSI 及 MISO 数据线向一个方向传输数据,可以加快一倍的传输速度。
  • 而单线模式则可以减少硬件接线,当然这样速率会受到影响。我们只讲解双线全双工模式。

3、收发流程

  • 在发送的不同阶段会对状态寄存器SR的不同数据位写入参数,我们通过读取这些寄存器标志来了解通讯状态
  • (1)控制NSS,产生起始信号(NSS置低电平)
  • (2)将数据写入到“数据寄存器 DR”中,该数据会被存储到发送缓冲区;
  • (3)通讯开始,SCK 时钟开始运行。MOSI 把发送缓冲区中的数据一位一位地传输出去;MISO则把数据一位一位地存储进接收缓冲区中
  • (4) 当发送完一帧数据的时候,“状态寄存器 SR”中的“TXE 标志位”会被置 1,表示传输完一帧,发送缓冲区已空;类似地,当接收完一帧数据的时候,“RXNE 标志位”会被置 1,表示传输完一帧,接收缓冲区非空
  • (5)等待到“TXE 标志位”为 1 时,若还要继续发送数据,则再次往“数据寄存器 DR”写入数据即可;等待到“RXNE 标志位”为 1 时,通过读取“数据寄存器 DR”可以获取接收缓冲区中的内容。
  • 注:假如我们使能了 TXE 或 RXNE 中断,TXE 或 RXNE 置 1 时会产生 SPI 中断信号,进入同一个中断服务函数,到 SPI 中断服务程序后,可通过检查寄存器位来了解是哪一个事件,再分别进行处理。也可以使用 DMA 方式来收发“数据寄存器 DR”中的数据。

通信模式

1、SPI 一共有四种通讯模式,它们的主要区别是总线空闲时 SCK 的时钟状态以及数据采样时刻,所以共有四种模式。由时钟极性和时钟相位决定。在SPI_CR1寄存器中设置

  • 时钟极性 CPOL:是指 SPI 通讯设备处于空闲状态时,SCK 信号线的电平信号 (即 SPI 通讯开始前、NSS 线为高电平时 SCK 的状态)。CPOL=0 时,SCK 在空闲状态时为低电平,CPOL=1 时,则相反。
  • 时钟相位 CPHA :是指数据的采样的时刻,当 CPHA=0 时,MOSI 或 MISO 数据线上的信号将会在SCK 时钟线的“奇数边沿”被采样。当 CPHA=1 时,数据线在 SCK 的“偶数边沿”采样。

2、在 SPI_CR1 寄存器中进行设置

配置
位1 CPOL:时钟极性 (Clock Polarity) 0:空闲状态时,SCK保持低电平。 1:空闲状态时,SCK保持高电平
位 0 CPHA:时钟相位 (Clock Phase) 0:从第一个时钟边沿(奇数边沿)开始采样数据 。1:从第二个时钟边沿(偶数边沿)开始采样数据

在黑色箭头(采样时间点)被采集

在这里插入图片描述

在这里插入图片描述
3、由 CPOL 及 CPHA 的不同状态,SPI 分成了四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式 0”与“模式 3”
在这里插入图片描述

数据控制逻辑

1、SPI 的 MOSI 及 MISO 都连接到数据移位寄存器上,数据移位寄存器的数据来源及目标接收、发送缓冲区以及MISO、MOSI 线。

2、当向外发送数据的时候,数据移位寄存器以“发送缓冲区”为数据源,把数据一位一位地通过数据线发送出去;当从外部接收数据的时候,数据移位寄存器把数据线采样到的数据一位一位地存储到“接收缓冲区”中。

3、通过写 SPI 的“数据寄存器 DR”把数据填充到发送 F 缓冲区中,通讯读“数据寄存器 DR”,可以获取接收缓冲区中的内容。

4、其中数据帧长度可以通过“控制寄存器 CR1”的“DFF 位”配置成 8 位及 16 位模式;

5、配置“LSBFIRST位”可选择 MSB 先行还是 LSB 先行(先发送高位还是先发送低位)

CR1

配置
位 7 LSBFIRST:帧格式 (Frame format) 0:先发送 MSB。1:先发送 LSB
位 11 DFF:数据帧格式 (Data frame format) 0:为发送/接收选择 8 位数据帧格式。1:为发送/接收选择 16 位数据帧格式

状态标志

在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR)”,我们只要读取状态寄存器相关的寄存器位,就可以了解 SPI 的工作状态了。应用程序通过三个状态标志,可以完全监控SPI总线的状态。

SPI_SR

  • 发送缓冲区空闲标志(TXE)
    位 1 TXE:发送缓冲区为空 (Transmit buffer empty)
    0:发送缓冲区非空
    1:发送缓冲区为空,可以写下一个待发送的数据进入缓冲器。
    当写入SPI_DR时,TXE标志被清除
  • 接收缓冲器非空(RXNE)
    位 0 RXNE:接收缓冲区非空 (Receive buffer not empty)
    0:接收缓冲区为空
    1:接收缓冲区非空,表明在接收缓冲器中包含有效的接收数据。读SPI数据寄存器可以清除此标志
  • 忙(Busy)标志
    0:SPI(或 I2S)不繁忙
    1:SPI(或 I2S)忙于通信或者发送缓冲区不为空
    此标志由硬件置 1 和清零(写入此位无效果),此标志表明SPI通信层的状态

SPI中断

控制逻辑还根据要求,负责控制产生 SPI 中断信号、DMA 请求及控制 NSS 信号线。

SPI_CR2
在这里插入图片描述

时钟

SPI1用的是APB2的时钟(84Mhz),HAL库中直接有了
在这里插入图片描述
需要对时钟进行分频(至少二分频),才能用
在这里插入图片描述

Flash

硬件

正点原子使用的是W25Q128,野火用的是W25Q64
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

W25QXX指令

根据下面命令,编写函数。一般情况下,主机传输的第一个数据,会被Flash视为操作指令
在这里插入图片描述

状态寄存器

通过状态寄存器可以检测和配置器件的状态
在这里插入图片描述

注意事项

1、需要先擦除才能再写入,按扇区操作,最小需要擦除一个扇区
2、CPOL和CPHA一定要配对,不然读不了数据,我读出来是ffff,不同设备不一样,野火就是第一个边沿,所以用的正点的就出错了
在这里插入图片描述

读写

根据不同的指令,按照给定的时序进行功能的操作,这个DI就是输入给器件的,DO就是器件输出给32的,需要我们读取的数据
在这里插入图片描述

SPI配置

SPI结构体讲解

配置也就是配置结构体中的东西

/* SPI1 init function */
void MX_SPI1_Init(void)
{
   

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;						/* 设置 SPI 的主/从机端模式 */
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;	/* 设置 SPI 的单双向模式 */
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置 SPI 的数据帧长度,可选 8/16 位 */
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;/* 设置时钟极性 CPOL,可选高/低电平 */
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; /* 设置时钟相位,可选奇/偶数边沿采样 */
  hspi1.Init.NSS = SPI_NSS_SOFT;/* 设置 NSS 引脚由 SPI 硬件控制还是软件控制 */
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;/* 设置时钟分频因子,fpclk/分频数 =fSCK */
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;/* 设置 MSB/LSB 先行 */
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;/* 指定是否启用 TI 模式 */
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;/* 指定是否启用 CRC 计算 */
  hspi1.Init.CRCPolynomial = 10;/* 设置 CRC 校验的表达式 */
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
   
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

	__HAL_SPI_ENABLE(&hspi1);     //使能SPI1,CubeMX只是配置好,需要自己使能(添加这一句就可以了,到时候再试试看直接操作寄存器怎么样)。
	
//	(hspi1.Instance->CR1) |= (0x00000040);//0100 0000  第六位,也可以从上面的函数中一步一步查看下去

	
  /* USER CODE END SPI1_Init 2 */

}

结构体成员说明:

  • Mode:本成员设置 SPI 工作在主机模式 (SPI_MODE_MASTER) 或从机模式 (SPI_MODE_SLAVE ),这两个模式的最大区别为 SPI 的 SCK 信号线的时序,SCK 的时序是由通讯中的主机产生的。若被配置为从机模式,STM32 的 SPI 外设将接受外来的 SCK 信号。
  • Direction:本成员设置 SPI 的通讯方向,可设置为双线全双工 (SPI_DIRECTION_2LINES),双线只接收 (SPI_DIRECTION_2LINES_RXONLY),单线 SPI_DIRECTION_1LINE。
  • DataSize:本成员可以选择 SPI 通讯的数据帧大小是为 8 位 (SPI_DATASIZE_8BIT) 还是 16位 (SPI_DATASIZE_16BIT)。
  • CLKPolarity 和 CLKPhase:这两个成员配置 SPI 的时钟极性 CLKPolarity 和时钟相位CLKPhase,这两个配置影响到 SPI 的通讯模式。时钟极性 CLKPolarity 成员,可设置为高电平 (SPI_POLARITY_HIGH)或低电平 (SPI_POLARITY_LOW)。时钟相位 CPHA 则可以设置为 SPI_PHASE_1EDGE(在SCK 的奇数边沿采集数据) 或 SPI_PHASE_2EDGE ( 在 SCK 的偶数边沿采集数据) 。
  • NSS:本成员配置 NSS 引脚的使用模式,可以选择为硬件模式 (SPI_NSS_HARD ) 与软件模式 ( SPI_NSS_SOFT ),在硬件模式中的 SPI 片选信号由 SPI 硬件自动产生,而软件模式则需要我们亲自把相应的 GPIO 端口拉高或置低产生非片选和片选信号。实际中软件模式应用比较多。
  • BaudRatePrescaler:本成员设置波特率分频因子,分频后的时钟即为 SPI 的 SCK 信号线的时钟频率。这个成员参数可设置为 fpclk 的 2、4、6、8、16、32、64、128、256 分频。
  • FirstBit:所有串行的通讯协议都会有 MSB 先行 (高位数据在前) 还是 LSB 先行 (低位数据在前) 的问题,而 STM32 的 SPI 模块可以通过这个结构体成员,对这个特性编程控制。
  • TIMode :指定是否启用 TI 模式。可选择为使能 ( SPI_TIMO DE_ENABLE ) 与不使能( SPI_TIMODE_DISABLE )。
  • CRCCalculation :指定是否启用 CRC 计算。
  • SPI_CRCPolynomial:这是 SPI 的 CRC 校验中的多项式,若我们使用 CRC 校验时,就使用这个成员的参数 (多项式),来计算 CRC 的值。

配置完这些结构体成员后,我们要调用 HAL_SPI_Init 函数把这些参数写入到寄存器中,实现 SPI的初始化,然后调用 __HAL_SPI_ENABLE 来使能 SPI 外设

HAL库配置讲解

1、模式:

  • 全双工主机,全双工从机
  • 半双工主,半双工从。只使用一条数据线的全双工,同一时间只能收或者发
  • 后面四个单工,就是一条线上只能收或者发
    在这里插入图片描述

2、选择NSS引脚控制是硬件模式 (SPI_NSS_HARD ) 还是软件模式 ( SPI_NSS_SOFT ),在硬件模式中的 SPI 片选信号由 SPI 硬件自动产生,而软件模式则需要我们亲自把相应的 GPIO 端口拉高或置低产生非片选和片选信号。实际中软件模式应用比较多。例程中使用的就是软件控制
当需要使用硬件模式时:
(1)主模式下是否支持多主的模式,如果支持就要选择input,不支持则选择output这个选项
(2)当作为从设备,就选择input
在这里插入图片描述

3、对于SPI有两种帧格式,一种是摩托罗拉,一种TI约定的SPI协议。用摩托罗拉就行。当上面选择硬件管理NSS引脚的时候,这里才能选择TI模式
在这里插入图片描述

4、每一帧的数据传输是传输8位的还是16位的。第一个传输的位是高位还是低位(高位先传输还是低位先传输)
在这里插入图片描述

5、空闲时保持高电平,第二个边沿采集,这个一定要配置 对,不然无法正常通信
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DSP28377是德州仪器(Texas Instruments)公司推出的一款数字信号处理器(DSP),具有强大的计算能力和丰富的外设接口。其中,SPI(Serial Peripheral Interface)是一种串行外设接口协议,可以用于与外部器件进行数据交换。 要实现DSP28377与外部闪存(flash)的SPI读写,可以按照以下步骤进行操作: 1. 配置SPI接口:使用DSP28377的I/O口配置寄存器(GPIOxDIR)设置所需的引脚为SPI功能。通过SPI控制器的配置寄存器(SPIxCTL)设置SPI接口的传输速度、数据位宽、时钟极性和相位等参数。 2. 发送读写命令:在SPI控制器的数据寄存器(SPIxDAT)中写入要发送的读写命令,包括读取或写入地址、读写模式(例如,单线程或四线程)、字节顺序等。 3. 数据传输:按照SPI协议的要求,将要读取或写入的数据按照一定顺序发送或接收。可以使用DSP28377的SPI控制器的数据缓冲区(SPIxDAT)进行数据传输。 4. 数据处理:根据需求进行数据处理,例如将读取到的数据保存到变量中,或者将要写入的数据从变量中提取出来。 5. 关闭SPI接口:在SPI读写完成后,可以通过SPI控制器的配置寄存器(SPIxCTL)关闭SPI接口,以节省功耗或释放引脚。 需要注意的是,在使用SPI接口进行读写时,需要根据外部闪存的规格和通信协议进行相应的配置和操作。此外,还需要了解DSP28377的SPI接口的详细特性和寄存器设置,以及外部闪存的读写规范,才能正确实现SPI读写外部闪存的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

成草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值