简介
W25QXXX系列的flash是一款经典的存储介质, 在很多嵌入式系统中,都会被做为外部的flash设备来保存数据等。 其中有不同的型号等, 比如说Q16, Q32,Q64,Q128, 容量分别是2MB,4MB,8MB 和 16MB。 那么在日常使用中,我们需要为其编写不同的驱动函数来进行驱动。 这是一个非常繁琐的过程。 那么在本篇文章中我将给大家分享一个来自于GITHUB上的Q-SPI falsh 驱动库。 可以用于快速的驱动上述的flash芯片。来减少搭建在驱动开发时的繁琐程度。 同时我还将分享一个Flash的经典电路来供大使用(亲测无误)
驱动介绍
这款驱动库来自GITHUB用户nimaltd Nima Askar (https://github.com/nimaltd/spif) 目前已经收获了616个stars可见当前的驱动库受欢迎程度。
我们可以使用GIT clone 命令clone 当前的仓库到本地,或者直接点击下载。而我们需要关注的文件只有下面三个
1 - NimaLTD.I-CUBE-SPIF_conf.h
2- spif.c
3- spif.h
其中NimaLTD.I-CUBE-SPIF_conf.h 文件是属于配置文件, 大家可以按需修改, 在我的工程中我是保持了默认。
spif.c 则是驱动函数的源码文件, 而spif.h 则是定义了所有的驱动函数。
使用方式
1- 创建Group , 并且添加上述的文件到项目中
2 - 在魔术棒工具的C++ 路径下配置Include path
3-在include path 中增加本地文件系统中的库文件的目录,如下图所示
4 - 主程序中调用 bool SPIF_Init(SPIF_HandleTypeDef *Handle, SPI_HandleTypeDef *HSpi, GPIO_TypeDef *Gpio, uint16_t Pin); 来初始化flash。 首先我们来介绍一下这个方法。SPIF_Init 方法一共接受四个参数,如下所示:
SPIF_HandleTypeDef *Handle : 库函数接口体的指针, 只需要定义,不需要初始化。
SPI_HandleTypeDef *HSpi : 已经初始化好的SPI句柄。
GPIO_TypeDef *Gpio : SPI CS 的 端口, 比如GPIOA,GPIOB,GPIOC等
uint16_t Pin : CS PIN 的编号,比如GPIO_PIN_4
代码如下:
SPIF_HandleTypeDef hspif; // 只需要定义, 不需要初始化 extern SPI_HandleTypeDef hspi; // 已经初始化好的SPI句柄。 SPIF_Init(&hspif, &hspi1, GPIOA, GPIO_PIN_4); // 初始化SPI
可以看到,上述操作逻辑非常简单, 当你初始化好Flash之后,句柄hspif就会被赋值(由于传递的是一个指针,可以改变原本的苏剧)。此时这个句柄就已经拿到了当前设备的所有信息。如下图所示(Debug模式)
4- 测试QSPI读写
// 测试数据 #define TEST_DATA_SIZE 64 uint8_t test_data[TEST_DATA_SIZE] = "This is a test message to verify the SPI Flash read and write operations."; uint8_t read_data[TEST_DATA_SIZE]; /** * @brief SPI Flash读写测试 * @param None * @retval None */ void Test_SPIF_Read_Write(void) { // 初始化SPI Flash if (!SPIF_Init(&hspif, &hspi1, GPIOA, GPIO_PIN_4)) { printf("SPI Flash initialization failed.\n"); return; } printf("SPI Flash initialized successfully.\n"); // 擦除整个芯片 if (!SPIF_EraseChip(&hspif)) { printf("SPI Flash chip erase failed.\n"); return; } printf("SPI Flash chip erased successfully.\n"); // 写入测试数据到指定地址 uint32_t write_address = 0x0000; // 起始地址 if (!SPIF_WriteAddress(&hspif, write_address, test_data, TEST_DATA_SIZE)) { printf("SPI Flash write failed.\n"); return; } printf("Data written successfully to address: 0x%08X\n", write_address); // 从指定地址读取数据 if (!SPIF_ReadAddress(&hspif, 0x0000, read_data, TEST_DATA_SIZE)) { printf("SPI Flash read failed.\n"); return; } printf("0x%X\r\n",read_data[0]); // 验证读取的数据是否与写入的数据匹配 if (memcmp(test_data, read_data, TEST_DATA_SIZE) == 0) { printf("Data verification successful!\n"); } else { printf("Data verification failed!\n"); printf("Expected: %s\n", test_data); printf("Received: %s\n", read_data); } }
效果展示:
测试工程如下:
设计原理图如下: