stm32读写w25qxx

article/2025/11/7 13:37:19

一,w25qxx简介。

二,stm32CubeIDE配置。

三,代码

1,w25qxx.c

#include "W25Qxx.h"/*********************************************************************************** 函数功能: 模块初始化*/
uint8_t BSP_W25Qx_Init(void)
{BSP_W25Qx_Reset();return BSP_W25Qx_GetStatus();
}void    BSP_W25Qx_Reset(void)
{uint8_t cmd[2] = {RESET_ENABLE_CMD,RESET_MEMORY_CMD};W25Qx_Enable();/* Send the reset command */HAL_SPI_Transmit(&hspi1, cmd, 2, W25Qx_TIMEOUT_VALUE);W25Qx_Disable();}/*********************************************************************************** 函数功能: 获取设备状态*/
uint8_t BSP_W25Qx_GetStatus(void)
{uint8_t cmd[] = {READ_STATUS_REG1_CMD};uint8_t status;W25Qx_Enable();/* Send the read status command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);/* Reception of the data */HAL_SPI_Receive(&hspi1,&status, 1, W25Qx_TIMEOUT_VALUE);W25Qx_Disable();/* Check the value of the register */if((status & W25QxxFV_FSR_BUSY) != 0){return W25Qx_BUSY;}else{return W25Qx_OK;}
}/*********************************************************************************** 函数功能: 写使能*/
uint8_t BSP_W25Qx_WriteEnable(void)
{uint8_t cmd[] = {WRITE_ENABLE_CMD};uint32_t tickstart = HAL_GetTick();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE){return W25Qx_TIMEOUT;}}return W25Qx_OK;
}/*********************************************************************************** 函数功能: 获取设备ID*/
void BSP_W25Qx_Read_ID(uint8_t *ID)
{uint8_t cmd[4] = {READ_ID_CMD,0x00,0x00,0x00};W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);/* Reception of the data */HAL_SPI_Receive(&hspi1,ID, 2, W25Qx_TIMEOUT_VALUE);W25Qx_Disable();}/*********************************************************************************** 函数功能: 读数据* 输入参数: 缓存数组指针、读地址、字节数*/
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size)
{uint8_t cmd[4];/* Configure the command */cmd[0] = READ_CMD;cmd[1] = (uint8_t)(ReadAddr >> 16);cmd[2] = (uint8_t)(ReadAddr >> 8);cmd[3] = (uint8_t)(ReadAddr);W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);/* Reception of the data */if (HAL_SPI_Receive(&hspi1, pData,Size,W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}W25Qx_Disable();return W25Qx_OK;
}/*********************************************************************************** 函数功能: 写数据* 输入参数: 缓存数组指针、写地址、字节数*/
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size)
{uint8_t cmd[4];uint32_t end_addr, current_size, current_addr;uint32_t tickstart = HAL_GetTick();/* Calculation of the size between the write address and the end of the page */current_addr = 0;while (current_addr <= WriteAddr){current_addr += W25QxxFV_PAGE_SIZE;}current_size = current_addr - WriteAddr;/* Check if the size of the data is less than the remaining place in the page */if (current_size > Size){current_size = Size;}/* Initialize the adress variables */current_addr = WriteAddr;end_addr = WriteAddr + Size;/* Perform the write page by page */do{/* Configure the command */cmd[0] = PAGE_PROG_CMD;cmd[1] = (uint8_t)(current_addr >> 16);cmd[2] = (uint8_t)(current_addr >> 8);cmd[3] = (uint8_t)(current_addr);/* Enable write operations */BSP_W25Qx_WriteEnable();W25Qx_Enable();/* Send the command */if (HAL_SPI_Transmit(&hspi1,cmd, 4, W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}/* Transmission of the data */if (HAL_SPI_Transmit(&hspi1, pData,current_size, W25Qx_TIMEOUT_VALUE) != HAL_OK){return W25Qx_ERROR;}W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25Qx_TIMEOUT_VALUE){return W25Qx_TIMEOUT;}}/* Update the address and size variables for next page programming */current_addr += current_size;pData += current_size;current_size = ((current_addr + W25QxxFV_PAGE_SIZE) > end_addr) ? (end_addr - current_addr) : W25QxxFV_PAGE_SIZE;} while (current_addr < end_addr);return W25Qx_OK;
}/*********************************************************************************** 函数功能: 扇区擦除* 输入参数: 地址*/
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address)
{uint8_t cmd[4];uint32_t tickstart = HAL_GetTick();cmd[0] = SECTOR_ERASE_CMD;cmd[1] = (uint8_t)(Address >> 16);cmd[2] = (uint8_t)(Address >> 8);cmd[3] = (uint8_t)(Address);/* Enable write operations */BSP_W25Qx_WriteEnable();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 4, W25Qx_TIMEOUT_VALUE);/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() == W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25QxxFV_SECTOR_ERASE_MAX_TIME){return W25Qx_TIMEOUT;}}return W25Qx_OK;
}/*********************************************************************************** 函数功能: 芯片擦除*/
uint8_t BSP_W25Qx_Erase_Chip(void)
{uint8_t cmd[4];uint32_t tickstart = HAL_GetTick();cmd[0] = CHIP_ERASE_CMD;/* Enable write operations */BSP_W25Qx_WriteEnable();/*Select the FLASH: Chip Select low */W25Qx_Enable();/* Send the read ID command */HAL_SPI_Transmit(&hspi1, cmd, 1, W25Qx_TIMEOUT_VALUE);/*Deselect the FLASH: Chip Select high */W25Qx_Disable();/* Wait the end of Flash writing */while(BSP_W25Qx_GetStatus() != W25Qx_BUSY);{/* Check for the Timeout */if((HAL_GetTick() - tickstart) > W25QxxFV_BULK_ERASE_MAX_TIME){return W25Qx_TIMEOUT;}}return W25Qx_OK;
}/*************************************************//*************************************************/

2,w25qxx.h

/** w25qxx.h**  Created on: Nov 26, 2022*      Author: admin*/#ifndef INC_W25QXX_H_
#define INC_W25QXX_H_#endif /* INC_W25QXX_H_ */#ifndef __W25Qxx_H
#define __W25Qxx_H/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
//W25Q128
#define W25QxxFV_FLASH_SIZE                  0x1000000 /* 128 MBits => 16MBytes */
#define W25QxxFV_SECTOR_SIZE                 0x10000   /* 256 sectors of 64KBytes */
#define W25QxxFV_SUBSECTOR_SIZE              0x1000    /* 4096 subsectors of 4kBytes */
#define W25QxxFV_PAGE_SIZE                   0x100     /* 65536 pages of 256 bytes */
//zyd
//#define W25QxxFV_FLASH_SIZE                  0x800000 /* 64 MBits => 8MBytes */
//#define W25QxxFV_SECTOR_SIZE                 65536   /* 256 sectors of 64KBytes */
//#define W25QxxFV_SUBSECTOR_SIZE              4096    /* 4096 subsectors of 4kBytes */
//#define W25QxxFV_PAGE_SIZE                   256     /* 65536 pages of 256 bytes */#define W25QxxFV_DUMMY_CYCLES_READ           4
#define W25QxxFV_DUMMY_CYCLES_READ_QUAD      10#define W25QxxFV_BULK_ERASE_MAX_TIME         250000
#define W25QxxFV_SECTOR_ERASE_MAX_TIME       3000
#define W25QxxFV_SUBSECTOR_ERASE_MAX_TIME    800
#define W25Qx_TIMEOUT_VALUE                   1000/* Reset Operations */
#define RESET_ENABLE_CMD                     0x66
#define RESET_MEMORY_CMD                     0x99#define ENTER_QPI_MODE_CMD                   0x38
#define EXIT_QPI_MODE_CMD                    0xFF/* Identification Operations */
#define READ_ID_CMD                          0x90
#define DUAL_READ_ID_CMD                     0x92
#define QUAD_READ_ID_CMD                     0x94
#define READ_JEDEC_ID_CMD                    0x9F/* Read Operations */
#define READ_CMD                             0x03
#define FAST_READ_CMD                        0x0B
#define DUAL_OUT_FAST_READ_CMD               0x3B
#define DUAL_INOUT_FAST_READ_CMD             0xBB
#define QUAD_OUT_FAST_READ_CMD               0x6B
#define QUAD_INOUT_FAST_READ_CMD             0xEB/* Write Operations */
#define WRITE_ENABLE_CMD                     0x06
#define WRITE_DISABLE_CMD                    0x04/* Register Operations */
#define READ_STATUS_REG1_CMD                  0x05
#define READ_STATUS_REG2_CMD                  0x35
#define READ_STATUS_REG3_CMD                  0x15#define WRITE_STATUS_REG1_CMD                 0x01
#define WRITE_STATUS_REG2_CMD                 0x31
#define WRITE_STATUS_REG3_CMD                 0x11/* Program Operations */
#define PAGE_PROG_CMD                        0x02
#define QUAD_INPUT_PAGE_PROG_CMD             0x32/* Erase Operations */
#define SECTOR_ERASE_CMD                     0x20
#define CHIP_ERASE_CMD                       0xC7#define PROG_ERASE_RESUME_CMD                0x7A
#define PROG_ERASE_SUSPEND_CMD               0x75/* Flag Status Register */
#define W25QxxFV_FSR_BUSY                    ((uint8_t)0x01)    /*!< busy */
#define W25QxxFV_FSR_WREN                    ((uint8_t)0x02)    /*!< write enable */
#define W25QxxFV_FSR_QE                      ((uint8_t)0x02)    /*!< quad enable */#define W25Qx_Enable()             HAL_GPIO_WritePin(W25_CS_GPIO_Port, W25_CS_Pin, GPIO_PIN_RESET)
#define W25Qx_Disable()         HAL_GPIO_WritePin(W25_CS_GPIO_Port, W25_CS_Pin, GPIO_PIN_SET)#define W25Qx_OK            ((uint8_t)0x00)
#define W25Qx_ERROR         ((uint8_t)0x01)
#define W25Qx_BUSY          ((uint8_t)0x02)
#define W25Qx_TIMEOUT        ((uint8_t)0x03)uint8_t BSP_W25Qx_Init(void);
void    BSP_W25Qx_Reset(void);
uint8_t BSP_W25Qx_GetStatus(void);
uint8_t BSP_W25Qx_WriteEnable(void);
void BSP_W25Qx_Read_ID(uint8_t *ID);
uint8_t BSP_W25Qx_Read(uint8_t* pData, uint32_t ReadAddr, uint32_t Size);
uint8_t BSP_W25Qx_Write(uint8_t* pData, uint32_t WriteAddr, uint32_t Size);
uint8_t BSP_W25Qx_Erase_Block(uint32_t Address);
uint8_t BSP_W25Qx_Erase_Chip(void);#endif

3,测试

BSP_W25Qx_Read_ID(ID);BSP_W25Qx_Write(wr_buf,0,10);delay_ms(100);
BSP_W25Qx_Read(rd_buf,0, 10);delay_ms(100);for(i=0;i<10;i++){printf("\r\n rd_buf = %d ",rd_buf[i]);}

四,总结。

8MB=128块(64KB) 1块=16扇区(4KB) 1扇区=16页(256B)

1页(page) = 256B

1扇区(sector)=16页(256B)=16*256 = 4096B = 4KB

1块((block)=16扇区 = 16*4096B =65536B = 64KB

w25q64 大小 64Mbit 即8MByte

驱动程序只要是配置SPI,配置好以后,读写一般没有问题


http://chatgpt.dhexx.cn/article/mj63DAFU.shtml

相关文章

STM32(八)W25Q(16/32/64/128)芯片学习总结

系列文章目录 文章目录 系列文章目录前言一、硬件和数据手册部分翻译1.W25Q64硬件设计2.数据手册解读 二、指令 前言 按项目需求&#xff0c;近期调试了W25Q32芯片&#xff0c;W25Q系列芯片是华邦公司推出的大容量SPI FLASH产品&#xff0c;W25Q32是3V&#xff0c;32M-bit 串行…

STC89C52驱动W25Q32测试笔记

STC89C52是经典的C51单片机&#xff0c;该芯片不自带硬件SPI接口&#xff0c;正好有手上一块W25Q32的存储模块&#xff08;某宝上买的2.2元&#xff09;&#xff0c;试着使用89C52模拟SPI接口驱动W25Q32&#xff0c;在驱动的过程中遇到了几个问题&#xff0c;首先的问题是电平不…

SPI Flash芯片W25Q32英文版数据手册解读(二)---------存储器知识,寄存器

接着上一篇文章&#xff0c;由于W25Q32芯片是一个存储器芯片&#xff0c;先对这个芯片有关存储器的一些概念进行解读。 一、存储器相关知识 1、存储器的三个单位&#xff1a; 存储器三个等级&#xff1a;页&#xff08;Page&#xff09;&#xff0c;扇区&#xff08;sector&a…

SPI Flash芯片W25Q32英文版数据手册解读(一)---------引脚功能,工作模式

W25Q32芯片是一个可以通过SPI&#xff08;串行外围设备接口&#xff09;操作的flash存储器&#xff0c;这篇文章备忘和总结一下英文版数据手册的一些解读。有关时序及具体用STC单片机编写程序的内容等下一篇文章。 一、芯片引脚功能 我买的是8引脚、SOIC封装的芯片&#xff0…

w25q32 内存分布

说明 ESP826612F/E里面使用w25q32作为了flash存储. 提前说下哈,bit代表位 也就是 0 1 0 1 , Bit代表字节 ,一字节就是8位 w25q32的容量是32Mbit 也就是 32/8 4MB字节 4*1024 4096KB字节 然后 w25q32 这个芯片规定每 64KB字节作为一个块 所以呢w25q32总共分成了 4096…

基于STM32+SPI+W25Qxx存储芯片指令,时序和函数讲解

前言 本次我们学习一下STM32F103关于SPI对存储芯片的读写&#xff0c;介绍W25QXX芯片和对芯片内部讲解和代码解读&#xff0c;学习W25QXX芯片的各种读写指令&#xff0c;操作芯片读写&#xff0c;认识底层驱动&#xff0c;本篇内容主要目的是教会大家看手册写代码&#xf…

ButterKnife9.0.0-rc2 配置

升级了AndroidStudio到3.4之后&#xff0c;发现项目中的很多依赖库都不能用&#xff0c;原因是随着AS升级之后&#xff0c;Gradle随之升级到3.4.1&#xff0c;很多第三方库也需要更高版本的支撑&#xff0c;今天遇到ButterKnife失效的问题&#xff0c;原本是8.5.1的版本&#x…

How to install Bromine3 RC2

When I install Bromine RC2, I met bellow issues: “Server could not contact itself at the specified address: 127.0.0.1:80” “Error: Database table jobs for model job was not found.” etc. Now I show my exact way to install RC2 successfully: 1. Downl…

fabric1.4.0-rc2快速入门

软件环境 VMware 10.0.4 CentOS-7-x86_64-Minimal-1708 搭建过程 go安装 docker安装 docker-compose安装 一、fabric的编译和安装 1. 创建目录&#xff08;GOPATH变量在安装go的时候就配置好了&#xff09; mkdir -p $GOPATH/src/github.com/hyperledger 2. 下载fabri…

Cocos2d-JS v3.0 RC2发布说明

Cocos2d-JS是Cocos2d-x的Javascript版本&#xff0c;融合了Cocos2d-html5和Cocos2d-x JavaScript Bindings。它支持Cocos2d-x的所有特性并提供更简单易用的Javascript风格API。 核心特性 极大改进了ccui控件布局库的性能和稳定性&#xff0c;ccui在RC0中被大幅度重构&#xff0…

【GCC】1: RTCP RR接收端生成

m79 代码。参考bytewoods 大神的以下文章:WebRTC 基于GCC的拥塞控制(上) WebRTC 基于GCC的拥塞控制(下)虽然可以拿到估算的带宽但是rtcp 总是malformed packet个 有必要带着问题跟进下整个过程 RR报文 基于丢包率的码率控制运行在发送端,依靠RTCP RR报文进行工作。* report b…

STM32之RCC

STM32 RCC复位与时钟配置&#xff0c;我首先忽略掉复位&#xff0c;首先学习时钟配置&#xff0c;复位以后用到再学习 STM32有多个时钟源&#xff0c;分别是 HSI:上电默认启动&#xff0c;因精度不高所以先不采用&#xff0c;以后如果需要再使用 HSE&#xff1a;外部高速时钟&…

Apache ShardingSphere 4.0.0-RC2发布

处暑无三日,新凉直万金。处暑之日,Apache ShardingSphere 4.0.0-RC2已经发布,欢迎测试使用&#xff01; 本次发布的4.0.0-RC2版本将前不久发布的4.0.0-RC1版本的核心功能不断打磨优化&#xff0c;修复社区反馈的问题&#xff0c;且持续进行微内核重构打磨&#xff1b;在社区建设…

macOS Ventura 13.4 RC2(22F63)发布

系统介绍 根据黑果魏叔官网提供&#xff1a;5 月 12 日消息&#xff0c;苹果今天面向开发人员&#xff0c;发布了 macOS Ventura 13.4 的第 2 个候选 RC 版本&#xff08;内部版本号 22F63&#xff09;&#xff0c;距离上个候选版本相隔数天时间。 macOS Ventura 带来了台前调…

.NET 6 RC2 版本发布

原文&#xff1a;bit.ly/3FS9xm7作者&#xff1a;Richard日期&#xff1a;2021-10-12翻译&#xff1a;精致码农-王亮说明&#xff1a;文中有大量的超链接&#xff0c;这些链接在公众号文章中被自动剔除&#xff0c;一部分包含超链接列表的小段落被我删减了&#xff0c;如果你对…

c#加密:三、对称加密 AES、DES、RC2、Rijndael

一、c#中的对称加密概述 对称加密算法在加密和解密时使用相同的密钥。Framework提供了四种对称加密算法。AES、DES、Rijndael、RC2。 DES&#xff1a;全称为Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法&#xff0c;1977年被美…

MFC的.rc 和.rc2文件

一、介绍 rc和rc2都是资源文件,包含了应用程序中用到的所有的资源。它们两指向的是同一个资源。 两者不同在于&#xff1a;rc2文件中的资源可以直接在VS集成环境中以可视化的方法进行编辑和修改; 而rc中的资源是根据需要手工地进行编辑。 二、实例 工程 rc文件 #include …

SEO搜索引擎优化方式

SEO搜索引擎优化方式 SEO搜索引擎优化方式 文章目录 SEO搜索引擎优化方式[TOC](文章目录) 前言一、黑帽SEO1、关键字的堆叠2、隐藏文本3、门页 二、白帽SEO1、 TDK2、 提高网站语义化的html标签占比3、 SSR 总结 前言 利用搜索引擎的规则提高网站在有关搜索引擎内的自然排名&…

seo搜索引擎优化-SEO优化教程附关键词工具以及文章采集软件

seo搜索引擎优化&#xff0c;什么是SEO搜索引擎优化。简单点来说就是用户通过搜索引擎搜索想要的结果第一时间找到你的网站。那我们怎么做好搜索引擎优化呢&#xff1f;要做好搜索引擎优化首先我们得了解首页引擎。怎么才能快速的了解搜索引擎。不管是百度/360/谷歌/搜狗等搜索…

抖音seo搜索排名,源码开发部署/seo排名系统源码分析。

前言&#xff1a;抖音seo搜索排名&#xff0c;源码开发部署/seo排名系统源码分析。抖音seo源码搭建部分代码 抖音seo是什么&#xff1f;其实seo它是搜索引擎优化&#xff0c;不仅这样&#xff0c;抖音里也有搜索引擎优化&#xff0c;抖音seo其实就是优化抖音的搜索结果&#xf…