STM32F103学习笔记——SPI读写Flash(二)

本文档记录了STM32通过SPI与Flash交互的学习过程,包括软件设计流程、SPI的初始化设置、发送接收一字节的函数编写,以及SPI通信中对Flash的控制指令介绍。在初始化阶段,设置了SPI模式、时钟,并配置了GPIO引脚。SPI发送接收函数实现了数据的同步收发。通过对特定指令的发送,可以实现对Flash的读写和擦除操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  此系列文章是小白学习STM32的一些学习笔记。小白第一次写笔记文章,有不足或是错误之处,请多体谅和交流!

1.软件设计流程

SPI读写Flash流程:

  1. 初始化通讯引脚及端口时钟;
  2. 使能SPI时钟;
  3. 配置SPI结构体;
  4. 编写基本SPI按字节收发函数;
  5. 编写FLASH擦除及读写操作函数;
  6. 编写测试程序。

2.SPI初始化

其头文件如图:
在这里插入图片描述
  根据定义的头文件可以写如下初始化程序,初始化SPI、端口时钟,引脚;配置SPI模式。

//SPI_FLASH_Init函数
void SPI_FLASH_Init(void)
{
	SPI_InitTypeDef SPI_initStructure;
	GPIO_InitTypeDef GPIO_InitStructure;//SPI、GPIO结构体定义
	FLASH_SPI_APBxClock_FUN(FLASH_SPI_CLK,ENABLE);
	FLASH_SPI_CS_APBxClock_FUN(FLASH_SPI_CS_CLK|FLASH_SPI_SCK_CLK|FLASH_SPI_MISO_CLK|FLASH_SPI_MOSI_CLK,ENABLE);
	//配置SPI的GPIO引脚
	GPIO_InitStructure.GPIO_Pin = FLASH_SPI_CS_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(FLASH_SPI_CS_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = FLASH_SPI_SCK_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(FLASH_SPI_SCK_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MISO_PIN;
    GPIO_Init(FLASH_SPI_MISO_PORT, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = FLASH_SPI_MOSI_PIN;
    GPIO_Init(FLASH_SPI_MOSI_PORT, &GPIO_InitStructure);
    FLASH_SPI_CS_HIGH();//片选FLASH_CS为高电平
    /*SPI模式配置********************************/
    SPI_InitTypeDef SPI_InitStructure;
    // FLASH 芯片 支持 SPI 模式 0 及模式 3,据此设置 CPOL CPHA
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_CRCPolynomial = 7;
    SPI_Init(FLASH_SPIx, &SPI_InitStructure);
     /* 使能 SPI */
    SPI_Cmd(FLASH_SPIx, ENABLE);   
}

3.SPI发送接收一字节函数编写

  接下来编写SPI发送和接受一个字节数据的函数,如下:

#define Dummy_Byte 0xFF
u8 SPI_FLASH_SendByte(u8 byte)
{
	SPITimeout = SPIT_FLAG_TIMEOUT;
	//等待发送缓冲区为空,及TXE事件发生
	while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET)
	{
		if((SPITimeout--)==0)
		   return SPI_TIMEOUT_UserCallback(0);
	}
	//把数据写入发送缓冲区
	SPI_I2S_SendData(FLASH_SPIx,byte);
	SPITimeout = SPIT_FLAG_TIMEOUT;
	//等待接受缓冲区为非空,及RXNE事件发生
	while(SPI_I2S_GetFlagStatus(FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET)
	{
		if((SPITimeout--)==0)
		   return SPI_TIMEOUT_UserCallback(1);
	}
	return SPI_I2S_ReceiveData(FLASH_SPIx);
	//获取接受缓冲区数据
}

  然后使用SPI读取一个字节数据

u8 SPI_FLASH_ReadByte(void)
{
	return (SPI_FLASH_SendByte(Dummy_Byte));
}

  由于SPI通讯模式配置为全双工模式,即收发是同步进行的。发送数据通过向发送缓冲区写数据即可;接收数据即调用发送数据函数,发送任意值,再返回收到的数据即可。

4.FLASH控制指令介绍

  stm32作为主机,通过SPI向FLASH发送的数据过去,FLASH会将这些数据理解成不同指令,然后执行不同操作。

在这里插入图片描述在这里插入图片描述

  通过SPI依据指令表次序规律发送数据,即可完成相应操作。其中“A0~A23”指 FLASH 芯片内部存储器组织的地址;“M0~M7”为厂商号(MANUFACTURER ID);“ID0-ID15”为 FLASH 芯片的ID;“dummy”指该处可为任意数据;“D0~D7”为 FLASH 内部存储矩阵的内容。
  通过指令“9F h”可以获得设备的生产厂商,存储器类型,容量。其通讯时序如下图:
在这里插入图片描述

本系列笔记内容和图片基于《【野火®】零死角玩转STM32—F103-MINI》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值