【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 存储器的功能,为嵌入式系统的开发提供了便利。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

django定时任务(django-crontab)

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

模拟电子技术——同相比例运算放大电路、反向运算比例放大电路、反向加法器电路、差分减法器电路

文章目录 一、同相比例运算放大电路什么是比例运算放大电路线性区与非线性区电压跟随器 二、反向运算比例放大电路什么是反比例运算放大器电路及特点 三、反向加法器电路什么是反向加法器电路及特点及参数计算电路及特点及参数计算 四、差分减法器电路什么是差动减法器 总结 提…

【JVM】打破双亲委派机制

📝个人主页:五敷有你 🔥系列专栏:JVM ⛺️稳中求进,晒太阳 打破双亲委派机制 打破双亲委派机制三种方法 自定义类加载器 ClassLoader包含了四个核心方法 //由类加载器子类实现,获取二进制数据调用…

使用Erlang/OTP构建容错的软实时Web应用程序

简单介绍 OTP (Open Telecom Platform) OTP 是包装在Erlang中的一组库程序。OTP构成Erlang的行为机制(behaviours),用于编写服务器、有限状态机、事件管理器。不仅如此,OTP的应用行为(the appl…

MySQL之json数据操作

1 MySQL之JSON数据 总所周知,mysql5.7以上提供了一种新的字段格式json,大概是mysql想把非关系型和关系型数据库一口通吃,所以推出了这种非常好用的格式,这样,我们的很多基于mongoDB的业务都可以用mysql去实现了。当然…

js设计模式:观察者模式

作用: 和发布订阅模式基本类似。 当某一对象状态发生变化时,所有的观察者都会收到通知。 vue响应式原理就是很经典的案例,数据发生变化,通知各个依赖。 示例: class TaobaoShop{constructor(){this.list []}addSub(name,data){this.list.push({name,data})}pubUser(name,d…

学习数据结构和算法的第9天

题目讲解 移除元素 ​ 给你一个数组nums和一个值 val,你需要 原地 移除所有数值等于 val的元素,并返回移除后数组的新长度。 ​ 不要使用额外的数组空间,你必须仅使用0(1)额外空间并 原地 修改输入数组。 ​ 元素的顺序可以改变。你不需要…

Mouse Anti-HDM IgE Antibody Assay Kit

哮喘作为一种常见的慢性炎症类疾病,影响着全世界约3亿各年龄段的人。哮喘一般是由于暴露于过敏原(尘螨、宠物皮屑、花粉及霉菌等)引起的,其特征是气流阻塞和支气管痉挛。屋尘螨(house dust mite, HDM)是最常…

ASUS华硕枪神8笔记本电脑G614JIR,G814JVR,G634JYR,G834JZR工厂模式出厂Windows11系统 带重置还原功能

适用ROG枪神8系列笔记本型号: G614JIR、G614JVR、G634JYR、G634JZR G814JIR、G814JVR、G834JYR、G834JZR 链接:https://pan.baidu.com/s/1tYZt6XFNC2d6YmwTbtFN7A?pwd3kp8 提取码:3kp8 带有ASUS RECOVERY恢复功能、自带所有驱动、出厂主…

人工智能学习与实训笔记(十六):OpenAI SORA模型技术报告全文中英对照 (GPT4翻译+人工润色)

目录 Video generation models as world simulators(视频生成模型作为世界模拟器) Turning visual data into patches (将视觉数据转换为图像块) Video compression network (视频压缩网络) Spacetim…

2.16日学习打卡----初学Dubbo(一)

2.16日学习打卡 目录: 2.16日学习打卡一. 什么是分布式?二. 什么是RPC?三. Dubbo概念_简介四. Dubbo核心组件五.Dubbo配置开发环境六. Dubbo配置开发环境_管理控制台 一. 什么是分布式? 可以看我的这篇文章–2.14日学习打卡----初学Zookeeper(一) 二.…

Code Composer Studio (CCS) - Comment (注释)

Code Composer Studio [CCS] - Comment [注释] References Add Block Comment: 选中几行代码 -> 鼠标右键 -> Source -> Add Block Comment shortcut key: Ctrl Shift / Remove Block Comment: 选中几行代码->鼠标右键->Source->Remove Block Comment s…

Chrome 关闭F12 网络选项下的大时间段图

把所有的按钮点了一遍,终于找到了 点开F12点右上的小齿轮,把概览取消勾选就可以了 英文的控制台中叫Overview

Android 13.0 SystemUI下拉状态栏定制二 锁屏页面横竖屏通知栏都居中功能实现

1.前言 在13.0的系统rom定制化开发中,在关于systemui的锁屏页面功能定制中,由于在平板横屏通知栏功能中,通知栏总是显示在右边,并且是在右边居中显示的, 由于需要和竖屏显示一样,所以就需要用到在时钟下面显示通知栏,然后同样需要居中显示通知栏,所以就来分析下相关的…

12 个顶级音频转换器软件(免费)

当涉及不受支持的音乐文件时,音频文件转换器软件总是会派上用场。当您希望缩小大量大型音乐文件的大小以节省设备存储空间时,它也很有帮助。您在寻找传输音频的软件吗?好吧,请仔细选择音频转换器,因为最好的音乐转换器…

定制你的【Spring Boot Starter】,加速开发效率

摘要: 本文将介绍如何创建一个自定义的 Spring Boot Starter,让您可以封装常用功能和配置,并在多个 Spring Boot 项目中共享和重用。 1. 简介 Spring Boot Starter 是 Spring Boot 框架中的一种特殊的依赖项,它用于快速启动和配置…

媒体邀约能干什么?

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 新的一年首先祝大家好运连连,万事兴龙! 媒体邀约能够为企业带来多方面的好处,具体包括: 1. 提升品牌知名度:通过媒体邀约&…

移动机器人的控制逻辑全解析。

你是否曾对那些在工厂中穿梭自如的移动机器人感到好奇?它们是如何准确无误地执行任务的?这一切都归功于移动机器人的控制逻辑!今天,就让我们深入探讨一下移动机器人控制逻辑的重点。 一、环境感知与建模技术是移动机器人实现自主导…

【Vue前端】vue使用笔记0基础到高手第2篇:Vue知识点介绍(附代码,已分享)

本系列文章md笔记(已分享)主要讨论vue相关知识。Vue.js是前端三大新框架:Angular.js、React.js、Vue.js之一,Vue.js目前的使用和关注程度在三大框架中稍微胜出,并且它的热度还在递增。Vue.js是一个轻巧、高性能、可组件…

多元统计分析课程论文-聚类效果评价

数据集来源:Unsupervised Learning on Country Data (kaggle.com) 代码参考:Clustering: PCA| K-Means - DBSCAN - Hierarchical | | Kaggle 基于特征合成降维和主成分分析法降维的国家数据集聚类效果评价 目录 1.特征合成降维 2.PCA降维 3.K-Mean…