[10min速通]🦏STM32CubemMX配置W25Q128
文章目录
- [10min速通]🦏STM32CubemMX配置W25Q128
- 1、下载源码
- 2、配置Cube
- 2.1 基础配置
- 2.2 SPI配置
- 3、配置MDK
- 3.1 添加源文件
- 3.2 管理源文件
- 3.3 完成接口配置
- 4、接口介绍
- 4.1 初始化
- 4.2 擦除
- 4.3 写入
- 4.4 读取
- 5、代码示例
- 6、其他
- 6.1 芯片擦除
- 6.2 没有掉电功能
- 6.3 这个开源代码适用其他w25qxx型号
- 6.4 FatFs
- 配套例程和源码
1、下载源码
下载github开源驱动代码。
GitHub - nimaltd/w25qxx: w25qxx SPI FLASH driver for stm32 HAL
此处声明此工程不是本人所作。
这个工程的作者在Readme中提供的视频教程配置非常详细了,会魔法的同学可以直接去看视频进行配置,不用看此文。
如果访问不了github,可以直接下载文末的资料,打包好了。
2、配置Cube
2.1 基础配置
内容包含,时钟树、串口、SW下载接口等基础配置。此处不再赘述。
2.2 SPI配置
SW25Q128支持三种SPI通信模式:标准SPI,Dual SPI,Quad SPI。速度依次增加,每种模式所用到的通信时序也不一样,目前使用的是标准SPI。
SPI工作模式选择模式0或者3。写入时钟最大133M,读取时钟最大50M,这里我们把时钟控制在50M以内。
下面是依据硬件电路配置接口。以下是我的接口:
特别注意的是CS引脚,因为配置SPI的时候,没有选择硬件NSS引荐,因此我们这里单独把PB14设置为CS引脚。
3、配置MDK
3.1 添加源文件
github上下载下来的文件如下:
w25qxx就是我们需要加入到MDK里的驱动文件。
我们把w25qxx.c加入到…/Core/Src文件夹下。把w25qxx.h和w25qxxConf.h加入到…/Core/Inc文件夹。
3.2 管理源文件
接下来把文件导入到工程中。
如果找不到.h文件,需要设置下面的文件类型为All file
最终的文件结构如下:
3.3 完成接口配置
作者已经将所有的顶层配置集中在了w25qxxConf.h中,我们只需要更改其中的接口就可以完成基础的配置。
下面用代码注释的方式,讲解下如何配置:
#ifndef _W25QXXCONFIG_H
#define _W25QXXCONFIG_H
#define _W25QXX_SPI hspi1 //使用到的是spi几
#define _W25QXX_CS_GPIO GPIOB //CS引脚的端口
#define _W25QXX_CS_PIN GPIO_PIN_14 //CS引脚的引脚号
#define _W25QXX_USE_FREERTOS 0 //是否使用到了FreeRTOS,0为不使用。如果用到了其他RTOS,需要改动他的源码
#define _W25QXX_DEBUG 0 //是否开启DEBUG模式,开启的话,需要提前配置好printf函数,工程运行时,会打印出运行过程。
#endif
此处我们用到的是spi1,CS引脚是PB14,关闭了RTOS跟DEBUG调试功能。
4、接口介绍
作者写的代码并没有提供多少注释,不过变量的命名已经可以做到见名知意。我通读了W25Qxx.c后,给大家介绍下常用的几个函数功能。
4.1 初始化
bool W25qxx_Init(void);
/*
函数功能:初始化芯片。成功就返回1,失败返回0。
*/
4.2 擦除
void W25qxx_EraseChip(void);
void W25qxx_EraseSector(uint32_t SectorAddr);
void W25qxx_EraseBlock(uint32_t BlockAddr);
上面三种擦除分别是:芯片全部擦除,擦除值定扇区,擦除值定块。SectorAddr是指扇区的编号,BlockAddr是指块的编号,编号不是地址。不太明白这句话可以接着往下看。
W25Q128有256个块(block),每个块由16个扇区(Sector)构成。一个块有64KB存储空间,一个扇区有4KB。下图是W25Q64的示意图,W25Q128内部也是这样的,就是block多一点。
我们想擦除第3个块,只需要:
W25qxx_EraseBlock(2);
如果我们想要擦除第2个块中的第3个扇区。只需要:
W25qxx_EraseSector(15+3);
解释以下,15是因为第一个块中包含了0-15,总共16个扇区,编号16对应着第二个块中的第1个扇区,那么18就对应着第2个块中的第3个扇区。
4.3 写入
void W25qxx_WritePage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_PageSize);
void W25qxx_WriteSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_SectorSize);
void W25qxx_WriteBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToWrite_up_to_BlockSize);
下面以W25qxx_WriteSector
为例讲解。
参数 | 含义 |
---|---|
pBuffer | 待写入的数据组指针 |
Sector_Address | 想要写入的扇区编号 |
OffsetInByte | 写入地址的字节偏置 |
NumByteToWrite_up_to_SectorSize | 想要写入的字节数 |
如果我想要写入第19个扇区的第二个字节位置,写入一个两字节的变量。那么代码是:
uint8_t WriteBuff[]={0x11,0x22};
...
W25qxx_WriteSector(WriteBuff, 18, 1,2);
4.4 读取
void W25qxx_ReadPage(uint8_t *pBuffer, uint32_t Page_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_PageSize);
void W25qxx_ReadSector(uint8_t *pBuffer, uint32_t Sector_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_SectorSize);
void W25qxx_ReadBlock(uint8_t *pBuffer, uint32_t Block_Address, uint32_t OffsetInByte, uint32_t NumByteToRead_up_to_BlockSize);
下面以W25qxx_ReadSector
为例讲解。
参数 | 含义 |
---|---|
pBuffer | 待读取的数据组指针 |
Sector_Address | 想要读取的扇区编号 |
OffsetInByte | 读取地址的字节偏置 |
NumByteToWrite_up_to_SectorSize | 想要读取的字节数 |
如果我想要写入第19个扇区的第二个字节位置,写入一个两字节的变量。那么代码是:
uint8_t ReadBuff[2];
...
W25qxx_ReadSector(ReadBuff, 18, 1,2);
5、代码示例
首先要包含头文件
#include "w25qxx.h"
再定义读写变量:
uint8_t WriteBuff[] = {0x11, 0x22};
uint8_t ReadBuff[2];
最后编写服务代码
W25qxx_Init(); // 初始化Flash芯片
W25qxx_EraseChip(); // 擦除整个芯片
W25qxx_WriteSector(WriteBuff, 18, 1, 2); // 写入两字节数据
W25qxx_ReadSector(ReadBuff, 18, 1, 2); // 读取两字节数据
printf("read data is 0x%x, 0x%x\n", ReadBuff[0], ReadBuff[1]);
6、其他
6.1 芯片擦除
由于FLASH存储器的特性决定了它只能把原来为“1”的数据位改写成“0”,而原来为“0”的数据位不能直接改写为“1”。 所以这里涉及到数据“擦除”的概念,在写入前,必须要对目标存储矩阵进行擦除操作,把矩阵中的数据位擦除为“1”, 在数据写入的时候,如果要存储数据“1”,那就不修改存储矩阵,在要存储数据“0”时,才更改该位。
作为测试,我们更改示例代码的内容,,读取一个擦除后,没有被编程的地址:
W25qxx_Init(); // 初始化Flash芯片
W25qxx_EraseChip(); // 擦除整个芯片
W25qxx_WriteSector(WriteBuff, 18, 1, 2); // 写入两字节数据
W25qxx_ReadSector(ReadBuff, 18, 0, 2); // 读取两字节数据
printf("read data is 0x%x, 0x%x\n", ReadBuff[0], ReadBuff[1]);
会发现,打印的结果是
0xff, 0x11
0xff的出现正是擦除后,每一位都变成了1。
6.2 没有掉电功能
这个开源代码包含了常用的功能,但是没有power down等不常用的功能。
6.3 这个开源代码适用其他w25qxx型号
6.4 FatFs
用flash存储少量信息没有问题,如果存储大量信息,可以考虑上文件系统,可以关注我的文章。
配套例程和源码
配套资源,0积分下载