良许Linux教程网 干货合集 STM32F0单片机快速入门十 用 SPI HAL 库读写W25Q128

STM32F0单片机快速入门十 用 SPI HAL 库读写W25Q128

1.W25Q128 介绍

当我们需要存储比较大量的数据时,上一篇文章所介绍的 24C02 (256个字节的EEPROM)已经不能满足需求。这时,我们会使用另一种类型的存储器,即 Flash。例如,具有SPI接口的 W25Q128。尽管这个小芯片只有简单的8个引脚,但它的存储容量达到了128M-bit,也就是16M字节,同时它的读写速度可以达到66MB/s。但是由于STM32F030不支持Quad/Dual SPI,只能以标准SPI模式进行读写,所以速度会稍慢一些。以下是W25Q128的主要特点:

a. 133MHz的SPI时钟速率。

b. 具有10万次擦写寿命,数据保持时间长达20年。

c. 每颗芯片具有64位的唯一序列号,也被称为Unique ID。

d. 每次可以写入1到256字节的数据。

e. 在写入数据之前,需要对目标地址所在的扇区进行擦除操作。

image-20231016214003877
image-20231016214003877

( Winbond W25Q128 datasheet )

我们通过以下连线使 W25Q128 连至 STM32F030 的 SPI1:

W25Q128 STM32F030

Pin 1 /CS PA4 也可以用其它 GPIO 引脚

Pin 2 DO PA6 SPI1_MISO

Pin 3 /WP ( VCC )

Pin 4 GND ( GND )

Pin 5 DI PA7 SPI1_MOSI

Pin 6 CLK PA5 SPI1_SCK

Pin 7 /HOLD or /RESET ( VCC )

Pin 8 VCC ( VCC )

2.代码

代码的开发如果想提高效率,一个方法就是充分利用前人的成果,而不是自己一再的去造轮子。

对于W25Q128 我们可以从Github上找到驱动代码:

https://github.com/nimaltd/w25qxx

GNU General Public License v3.0

我们把它集成进SPI例程里,完成 W25Q128 的读写功能。

Step 1,下载后把解压的文件夹 w25qxx-master 放在 STM32Cube_FW_F0_V1.11.0\Drivers\BSP\Components

image-20231016214007602
image-20231016214007602

Step 2, 我们用 Keil 打开下面这个工程:

STM32Cube_FW_F0_V1.11.0\Projects\STM32F030R8-Nucleo\Examples\SPI\SPI_FullDuplex_ComPolling\MDK-ARM\Project.uvprojx

在项目(STM32F030R8-Nucleo)上点鼠标右键,选择Add Group…

新建 Group 并改名称为 Drivers\BSP\Components\w25qxx-master

Step 3, 在 Drivers\BSP\Components\w25qxx-master上点右键,选择Add Existing Files to Group “Drivers\BSP\Components\w25qxx-master”…,

找到 Drivers/BSP/components/w25qxx-master/w25qxx.c 点击Add,然后可以看到w25qxx.c已经添加进项目中:

image-20231016214013489
image-20231016214013489

Step 4, 在 Options for Target 里添加路径,这里使用的是工程所在路径的相对路径,也可以使用绝对路径,但如果工程拷贝到别的地方的时候,此包含路径就需要跟随更改。

Add include path ../../../../../../Drivers/BSP/components/w25qxx-master

image-20231016214016605
image-20231016214016605

Step 5, 驱动头文件 w25qxx.h 中原来包含的的 spi.h, 因为我们使用的 Cube 库,头文件需要做如下替换:

//#include “spi.h”

#include “stm32f0xx_hal.h”

Step 6, main.h 里根据实际情况配置引脚,把驱动头文件 #include “w25qxx.h” 包含进来。片选信号 CS 可以由任意一个 GPIO 控制,在函数

HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)

里把CS引脚配置为GPIO输出就行了,实际的拉低拉高是驱动代码实现的。

image-20231016214019831
image-20231016214019831
image-20231016214023472
image-20231016214023472

Step 7, 在 main.c 里定义了 SpiHandle 并指向 SPI1, 我们在 w25qxx.c里也要用到这个 Handle,所以通过 extern 来引用一下。

image-20231016214026585
image-20231016214026585

Step 8, 初始化 SPI1,然后调用 w25qxx 驱动的初始化代码 W25qxx_Init( ); 然后就可以用擦除,读写等函数了。

image-20231016214031349
image-20231016214031349
image-20231016214034498
image-20231016214034498

在代码的修改过程中,我们可以再次体会 Cube 库的这种分层结构带来的好处,特别是如何与第三方驱动代码融合。各个模块就像积木一样,我们只需要把它们搭建起来就可以快速的实现我们想要的功能。

下面是读出数据时实际抓取的波形:

image-20231016214037374
image-20231016214037374

以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !

137e00002230ad9f26e78-265x300
本文由 良许Linux教程网 发布,可自由转载、引用,但需署名作者且注明文章出处。如转载至微信公众号,请在文末添加作者公众号二维码。
良许

作者: 良许

良许,世界500强企业Linux开发工程师,公众号【良许Linux】的作者,全网拥有超30W粉丝。个人标签:创业者,CSDN学院讲师,副业达人,流量玩家,摄影爱好者。
上一篇
下一篇

发表评论

联系我们

联系我们

公众号:良许Linux

在线咨询: QQ交谈

邮箱: yychuyu@163.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部