【STM32 CubeMX】SPI W25Q64功能实现

文章目录

  • 前言
  • 一、内部函数的实现
    • 1.1 选中和取消选中SPI Flash
    • 1.2 写使能函数
    • 1.3 获取读状态
    • 1.4 等待就绪状态
  • 二、Flash读写函数实现
    • 2.1 读Flash ID
    • 2.2 擦除某个扇区
    • 2.3 写扇区
    • 2.4 读数据
  • 三、测试代码
  • 总结


前言

SPI Flash 存储器在嵌入式系统中扮演着重要角色,它可以为微控制器提供额外的存储空间,并且具有快速的读写速度和较大的存储容量。W25Q64 是一款常见的 SPI Flash 存储器,容量为64Mb,采用 SPI 接口进行通信。在 STM32 微控制器上实现对 W25Q64 的功能使用,可以通过 STM32 CubeMX 和相关的库函数轻松完成。本文将介绍如何利用 STM32 CubeMX 和 SPI 库来实现对 W25Q64 的基本功能。


一、内部函数的实现

1.1 选中和取消选中SPI Flash

当CS引脚为GPIO_PIN_RESET为选中该设备,当CS引脚为GPIO_PIN_SET表示取消选中该设备,所以这个函数非常好实现,只需要使用HAL_GPIO_WritePin函数进行写pin即可

static void SPIFlash_Select(void)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_RESET);
}static void SPIFlash_DeSelect(void)
{HAL_GPIO_WritePin(GPIOC,GPIO_PIN_4,GPIO_PIN_SET);
}

1.2 写使能函数

如果你需要写使能,你只需要发送命令0x06即可,你可以使用查询方式来发送,也可以使用中断函数来发送。
在发送命令的时候,你需要选中该Flash设备,当你写完命令后,需要取消选中Flash设备。
在这里插入图片描述
我们可以这样实现他:

static volatile int g_spi1_tx_complete = 0;
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{if(hspi == &hspi1){g_spi1_tx_complete = 1;}
}void Wait_SPI_TxCplt(int timeout)
{while(g_spi1_tx_complete == 0 && timeout--){HAL_Delay(1);}g_spi1_tx_complete = 0;
}static int SPIFlash_WriteEnable(void)
{uint8_t buf[1] = {0x06};SPIFlash_Select();HAL_SPI_Transmit_IT(&hspi1,buf,1);Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();
}

1.3 获取读状态

当我们擦除扇区或者写扇区的时候,他并不是发送数据完成,这个数据就写进去的,我们需要等待他内部编程完。我们可以使用命令,把里面的状态拿出来
在这里插入图片描述
在这里,我们需要发送2个命令,但是有用的只有命令1(发送的命令为0x05),因为发送了2个命令,所以我们需要接收两个数据,但是有用的只有接收到的数据2。

static volatile int g_spi1_txrx_complete = 0;
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{if(hspi == &hspi1){g_spi1_txrx_complete = 1;}
}void Wait_SPI_TxRxCplt(int timeout)
{while(g_spi1_txrx_complete == 0 && timeout--){HAL_Delay(1);}g_spi1_txrx_complete = 0;
}static int SPIFlash_ReadStatus(void)
{uint8_t txbuf[2] = {0x05,0xff};uint8_t rxbuf[2] = {0,0};SPIFlash_Select();HAL_SPI_TransmitReceive_IT(&hspi1, txbuf, rxbuf, 2);Wait_SPI_TxRxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();return rxbuf[1];
}

1.4 等待就绪状态

所谓的等待就绪状态其实就是当SPIFlash_ReadStatus函数&上1他还是等于1,就代表擦除扇区或者写扇区已经完成了

static int SPIFlash_WaitReady(void)
{while(SPIFlash_ReadStatus() & 1 == 1);
}

二、Flash读写函数实现

2.1 读Flash ID

读Flash ID可以让我们知道这个SPI Flash是否有用
和前面的获取读状态一样。在这里,我们需要发送2个命令,但是有用的只有命令1(发送的命令为0x9F),因为发送了2个命令,所以我们需要接收两个数据,但是有用的只有接收到的数据2。

int SPIFlash_ReadID(void)
{uint8_t txbuf[2] = {0x9F,0xff};uint8_t rxbuf[2] = {0,0};SPIFlash_Select();HAL_SPI_TransmitReceive_IT(&hspi1, txbuf, rxbuf, 2);Wait_SPI_TxRxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();return rxbuf[1];
}

当rxbuf[1]的值为0xEF时,代码这个SPI Flash没有问题

2.2 擦除某个扇区

首先,我们要发送命令加上3个字节的地址,所以我们需要4字节的buf
如果你想擦除某个扇区,你需要使用0x20命令。
接下来,我们往buf的后3字节填充地址,地址是先发高位再发低位的。
再完成发送之后,我们还需要等待就绪,即调用SPIFlash_WaitReady函数

int SPIFlash_EraseSector(uint32_t addr)
{SPIFlash_WriteEnable();uint8_t txbuf[4] = {0x20};txbuf[1] = addr>>16 & 0xff;txbuf[2] = addr>>8 & 0xff;txbuf[3] = addr>>0 & 0xff;SPIFlash_Select();HAL_SPI_Transmit_IT(&hspi1,txbuf,4);Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();SPIFlash_WaitReady();return 0;
}

2.3 写扇区

写操作在发送命令+地址的和我们的擦除某个扇区的是一样的,只不过我们的写扇区的命令为0x02
再发送完命令+地址之后,我们就可以直接调用HAL库的发送函数进行datas的发送即可。

int SPIFlash_Write(uint32_t addr,uint8_t *datas,uint32_t len)
{SPIFlash_WriteEnable();uint8_t txbuf[4] = {0x02};txbuf[1] = addr>>16 & 0xff;txbuf[2] = addr>>8 & 0xff;txbuf[3] = addr>>0 & 0xff;SPIFlash_Select();HAL_SPI_Transmit_IT(&hspi1,txbuf,4);Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);HAL_SPI_Transmit_IT(&hspi1,datas,len);Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();SPIFlash_WaitReady();return 0;
}

2.4 读数据

读操作在发送命令+地址的和我们的擦除某个扇区的是一样的,只不过我们的写扇区的命令为0x03
在写完上面这些数据之后,我们需要等待写完,接下来我们就可以去调用HAL库的读SPI函数了

static volatile int g_spi1_rx_complete = 0;void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{if(hspi == &hspi1){g_spi1_rx_complete = 1;}
}void Wait_SPI_RxCplt(int timeout)
{while(g_spi1_rx_complete == 0 && timeout--){HAL_Delay(1);}g_spi1_rx_complete = 0;
}int SPIFlash_Read(uint32_t addr,uint8_t *datas,uint32_t len)
{uint8_t txbuf[4] = {0x03};txbuf[1] = addr>>16 & 0xff;txbuf[2] = addr>>8 & 0xff;txbuf[3] = addr>>0 & 0xff;SPIFlash_Select();HAL_SPI_Transmit_IT(&hspi1,txbuf,4);Wait_SPI_TxCplt(SPI_FLASH_TIMEOUT);HAL_SPI_Receive_IT(&hspi1,datas,len);Wait_SPI_RxCplt(SPI_FLASH_TIMEOUT);SPIFlash_DeSelect();return 0;
}

三、测试代码

char *str = "www.csdn.net\r\n";r = SPIFlash_ReadID();
SPIFlash_EraseSector(4096);
SPIFlash_Write(4096,(uint8_t*)str,strlen(str)+1);
SPIFlash_Read(4096,(uint8_t*)flash_buf,20);

总结

通过本文的介绍,我们了解了如何在 STM32 CubeMX 中配置并利用 SPI 库来实现对 W25Q64 SPI Flash 存储器的功能。首先,我们通过 CubeMX 配置了 STM32 的 SPI 外设,包括时钟分频、数据大小、模式等参数。然后,我们编写了初始化代码,将 SPI 外设与 W25Q64 进行连接,并实现了基本的读写功能。在编写代码时,我们充分利用了 STM32 的 HAL 库提供的函数,简化了通信过程的实现。最后,我们在主函数中调用了相应的读写函数,并通过调试工具验证了功能的正确性。通过本文的学习,读者可以掌握在 STM32 微控制器上使用 CubeMX 和 SPI 库来实现对 W25Q64 SPI Flash 存储器的功能,为嵌入式系统的开发提供了便利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务调用组件FeignDubbo实战

RPC概述 思考: 微服务之间如何方便优雅的实现服务间的远程调用? RPC 全称是 Remote Procedure Call ,即远程过程调用,其对应的是我们的本地调用。RPC 的目的是:让我们调用远程方法像调用本地方法一样。 //本地调用 R…

【大厂AI课学习笔记】【2.1 人工智能项目开发规划与目标】(3)数据准备初步

今天来学习数据准备。 一个AI项目要包括构建数据集、数据清理和数据融合、数据采集、特征工程、算法改进和其他步骤。 数据采集和数据清洗,也就是数据准备,要占到人工智能项目一半以上的工作量。 训练的数据量越大,模型越准确。 建立数据标…

使用redis-insight连接到服务器上的redis数据库

一、安装redis: 安装 Redis。你可以通过运行下面的命令来使用 yum 安装 Redis: sudo yum install redis 启动 Redis 服务。安装完成后,你可以通过运行下面的命令来启动 Redis 服务: sudo systemctl start redis 设置 Redis 服务…

定时器(基本定时器、通用定时器、高级定时器)

目录 一、基本定时器 二、通用定时器 三、高级定时器 一、基本定时器 1、作用:计时和计数。 二、通用定时器 1、除了有基本定时器的计时和计数功能外,主要有输入捕获和输出比较的功能,硬件主要由六大部分组成: ① 时钟源 ② 控…

美国突然致敬中本聪

作者:秦晋 有点看不懂美国的神操作。 2月16日,据《Bitcoin Magazine》报道,比特币的竞争对手、美国参议员伊丽莎白-沃伦对比特币的立场突然180度大转弯。由反对立场转为支持立场。让很多行业媒体出乎意料,甚至惊掉下巴。 报道称&a…

文件上传漏洞--Upload-labs--Pass01--前端绕过

一、前端绕过原理 通俗解释,我们将写有恶意代码的php后缀文件上传到网页,网页中的javascript代码会先对文件的后缀名进行检测,若检测到上传文件的后缀名为非法,则会进行alert警告。若想上传php后缀的文件,就要想办法对…

Html的<figure><figcaption>标签

Html的<figure><figcaption>标签 示例一: <figure><figcaption>figcaption001, fig标题1 </figcaption><figcaption>figcaption002, fig标题2 </figcaption><div style"width:calc(100px*2); height:calc(100px*2); back…

力扣经典题:环形链表的检测与返回

1.值得背的题 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode *detectCycle(struct ListNode *head) {struct ListNode*fasthead;struct ListNode*slowhead;while(fast!NULL&&fast->…

解锁Spring Boot中的设计模式—03.委派模式:探索【委派模式】的奥秘与应用实践!

委派模式 文章目录 委派模式1.简述**应用场景****优缺点****业务场景示例** 2.类图3.具体实现3.1.自定义注解3.2.定义抽象委派接口3.3.定义具体执行者3.4.定义委派者(统一管理委派任务)3.5.定义委派者管理类 4.测试4.1.controller层4.2.测试不同场景4.2.1.测试生产部门计算费用…

【GPT-2】论文解读:Language Models are Unsupervised Multitask Learners

文章目录 介绍zero-shot learning 零样本学习 方法数据Input Representation 结果 论文&#xff1a;Language Models are Unsupervised Multitask Learners 作者&#xff1a;Alec Radford, Jeff Wu, Rewon Child, D. Luan, Dario Amodei, I. Sutskever 时间&#xff1a;2019 介…

C++中.h与.hpp文件的差异问答

.h文件与.hpp文件在C编程中的区别主要基于约定和偏好&#xff0c;而不是C语言或其编译器强制执行的任何技术差异。以下是这些差异的概述&#xff1a; 约定&#xff1a; .h 文件&#xff1a;此扩展名源于C编程&#xff0c;表示头文件。它在C中常用于头文件&#xff0c;但不一定表…

四种mfc140u.dll丢失的解决方法,有效恢复mfc140u.dll丢失

mfc140u.dll文件的重要性&#xff0c;当系统中出现mfc140u.dll丢失的情况时&#xff0c;可能会导致一系列问题和影响。因此&#xff0c;保持mfc140u.dll文件的完整性对于系统和应用程序的稳定运行至关重要。一旦出现mfc140u.dll文件丢失的情况&#xff0c;我们需要采取有效的方…

怎样录屏?掌握这些方法,让你轻松驾驭!

随着科技的进步&#xff0c;如今我们可以通过屏幕录制软件来记录我们的电脑屏幕活动。无论是为了分享游戏精彩瞬间&#xff0c;还是为了制作教程或演示&#xff0c;录屏都成为了许多人的需求。可是你知道怎样录屏才是最好的吗&#xff1f;接下来&#xff0c;本文将为您介绍三种…

前端面试必备八股文——HTMLCSS

HTML src和href的区别 src和href都是用来加载外部资源&#xff0c;区别如下 src当浏览器解析到该元素时&#xff0c;会暂停其他资源的加载和处理&#xff0c;直到该资源加载完成。 它会将资源内容嵌入到当前标签所在的位置&#xff0c;将其指向的资源下载应用到文档内&#…

Mybatis速成(一)

文章目录 Mybatis速成&#xff08;一&#xff09;前言1. 快速入门1.1 入门程序分析1.2 入门程序实现1.2.1 准备工作1.2.1.1 创建springboot工程1.2.1.2 数据准备 1.2.2 配置Mybatis1.2.3 编写SQL语句1.2.4 单元测试 1.3 解决SQL警告与提示 2. JDBC介绍(了解)2.1 介绍2.2 代码2.…

本地个性化聊天机器人CHAT WITH RTX

英伟达推出了自家版本的ChatGPT Chat With RTX 是一款演示应用程序&#xff0c;可让您个性化连接到您自己的内容&#xff08;文档、笔记、视频或其他数据&#xff09;的 GPT 大语言模型 (LLM)。利用检索增强生成 (RAG)、TensorRT-LLM和 RTX 加速&#xff0c;您可以查询自定义聊…

django定时任务(django-crontab)

目录 一&#xff1a;安装django-crontab&#xff1a; 二&#xff1a;添加django_crontab到你的INSTALLED_APPS设置&#xff1a; 三&#xff1a;运行crontab命令来创建或更新cron作业&#xff1a; 四&#xff1a;定义你的cron作业 五&#xff1a;创建你的管理命令&#xff…

《学成在线》微服务实战项目实操笔记系列(P92~P120)【下】

史上最详细《学成在线》项目实操笔记系列【下】&#xff0c;跟视频的每一P对应&#xff0c;全系列18万字&#xff0c;涵盖详细步骤与问题的解决方案。如果你操作到某一步卡壳&#xff0c;参考这篇&#xff0c;相信会带给你极大启发。 四、课程发布模块 4.1 (课程发布)模块需求…

【leetcode】深搜、暴搜、回溯、剪枝(C++)3

深搜、暴搜、回溯、剪枝&#xff08;C&#xff09;3 一、解数独1、题目描述2、代码3、解析 二、单词搜索1、题目描述2、代码3、解析 三、黄金矿工1、题目描述2、代码3、解析 四、不同路径III1、题目描述2、代码3、解析 一、解数独 1、题目描述 leetcode链接 2、代码 class…

三组I/O复用函数的比较

目录 事件集最大支持文件描述符数工作模式实现原理一图 这三组I/O复用系统调用&#xff0c;这三组系统调用都能同时监听多个文件描述符&#xff0c;它们将等待由timeout参数指定超时时间&#xff0c;知道一个或者多个文件描述上面有事件发生时候返回&#xff0c;返回的就是就绪…