当前位置: 首页 > news >正文

通用外设-W25Q64

前言

一、SPI通信

二、W25Q64基初时序

1.各种命令代码

2.代码

1.写使能指令

2.读取芯片是否忙碌状态并等待

3.写入数据

4.擦除函数操作

5.读取代码

三.验证

四.擦除说明

总结


前言

在单片机中一般32K FLASH就够用了,但是当我们使用图片或其他大量数据时就不够用了,又因为数据为固定数据,不需要为此而换大容量芯片。因此用外挂存储芯片来解决这个问题。

本篇文章采用SPI软件通信的方式进行讲解,了解存储芯片同时加深SPI通信了解。

环境:

芯片:STM32F103C8T6

Keil:V5.24.2.0

外设:4针OLED屏,W25Q64芯片


一、SPI通信

关于SPI通信简介看我之前文章:

写文章-CSDN创作中心

还包含了读ID指令。本篇就不在赘述。

二、W25Q64基初时序

1.各种命令代码

标黄色的为重要代码,我们应尽量掌握。

各个代码进行宏定义,方便我们使用,也方便我们以后查阅

#define W25Q64_WRITE_ENABLE							0x06
#define W25Q64_WRITE_DISABLE						0x04
#define W25Q64_READ_STATUS_REGISTER_1				0x05
#define W25Q64_READ_STATUS_REGISTER_2				0x35
#define W25Q64_WRITE_STATUS_REGISTER				0x01
#define W25Q64_PAGE_PROGRAM							0x02
#define W25Q64_QUAD_PAGE_PROGRAM					0x32
#define W25Q64_BLOCK_ERASE_64KB						0xD8
#define W25Q64_BLOCK_ERASE_32KB						0x52
#define W25Q64_SECTOR_ERASE_4KB						0x20
#define W25Q64_CHIP_ERASE							0xC7
#define W25Q64_ERASE_SUSPEND						0x75
#define W25Q64_ERASE_RESUME							0x7A
#define W25Q64_POWER_DOWN							0xB9
#define W25Q64_HIGH_PERFORMANCE_MODE				0xA3
#define W25Q64_CONTINUOUS_READ_MODE_RESET			0xFF
#define W25Q64_RELEASE_POWER_DOWN_HPM_DEVICE_ID		0xAB
#define W25Q64_MANUFACTURER_DEVICE_ID				0x90
#define W25Q64_READ_UNIQUE_ID						0x4B
#define W25Q64_JEDEC_ID								0x9F
#define W25Q64_READ_DATA							0x03
#define W25Q64_FAST_READ							0x0B
#define W25Q64_FAST_READ_DUAL_OUTPUT				0x3B
#define W25Q64_FAST_READ_DUAL_IO					0xBB
#define W25Q64_FAST_READ_QUAD_OUTPUT				0x6B
#define W25Q64_FAST_READ_QUAD_IO					0xEB
#define W25Q64_OCTAL_WORD_READ_QUAD_IO				0xE3#define W25Q64_DUMMY_BYTE							0xFF        //无用数据(不是无用)

2.代码

1.写使能指令

在写入数据时必须进行的操作,防止误操作

void W25Q64_WriteEnable(void)		//书写使能命令
{MySPI_Start();MySPI_SwapByte(W25Q64_WRITE_ENABLE);MySPI_Stop();
}

2.读取芯片是否忙碌状态并等待

也是比较简单:

开始传输,发送读取指令,等待芯片忙碌结束,停止。

void W25Q64_WaitBusy(void)		//读取芯片是否忙碌状态并等待
{uint32_t Timeout;MySPI_Start();MySPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);Timeout =1000000;			//防死循环措施,时间可以加长while((MySPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01){Timeout --;if(Timeout == 0){break;}}MySPI_Stop();
}

3.写入数据

1.地址:指定写入的地址

2.数据:需要写入的数据,根据芯片描述,每页写入数据不大于64K,大于64K需要进行分页写入

3.数组的大小,方便进行循环

/**************************
@:地址
@:要写入的数据
@:数组数
***************************/
void W25Q64_PageProgram(uint32_t Address,uint32_t *DataArray,uint16_t Count)//写入代码
{uint16_t i;W25Q64_WriteEnable();MySPI_Start();MySPI_SwapByte(W25Q64_PAGE_PROGRAM);MySPI_SwapByte(Address >> 16);	//总共24位地址,右移16后剩高8位MySPI_SwapByte(Address >> 8);	//右移8位后剩高位16,但是只能发送8位,高8位舍弃MySPI_SwapByte(Address);for(i = 0;i < Count ;i ++)	//对数组进行写入{MySPI_SwapByte(DataArray[i]);}MySPI_Stop();W25Q64_WaitBusy();				//等待芯片空闲,在读写后进行等待

注:因为芯片写入数据需要时间,不是我们MCU发送完那边就全部写入了。因此我们要等待其数据全部存储完,不然后果就是我们的下次写入操作会数据不准确。当然我们也可以把这行代码放在操作函数前。判断芯片是否忙碌状态。

4.擦除函数操作

 代码注释较全。

void W25Q64_SectorErase(uint32_t Address)	//擦除函数操作
{W25Q64_WriteEnable();W25Q64_WaitBusy();MySPI_Start();MySPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);MySPI_SwapByte(Address >> 16);	//总共24位地址,右移16后剩高8位MySPI_SwapByte(Address >> 8);	//右移8位后剩高位16,但是只能发送8位,高8位舍弃MySPI_SwapByte(Address);MySPI_Stop();W25Q64_WaitBusy();				//等待芯片空闲,需要在读写后进行等待
}

5.读取代码

void W25Q64_ReadData(uint32_t Address,uint32_t *DataArray,uint32_t Count)//读取代码
{uint32_t i;W25Q64_WaitBusy();MySPI_Start();MySPI_SwapByte(W25Q64_READ_DATA);MySPI_SwapByte(Address >> 16);	//总共24位地址,右移16后剩高8位MySPI_SwapByte(Address >> 8);	//右移8位后剩高位16,但是只能发送8位,高8位舍弃MySPI_SwapByte(Address);for(i = 0;i < Count ;i++){DataArray[i] = MySPI_SwapByte(W25Q64_DUMMY_BYTE);//以此来置换回需要的数据}MySPI_Stop();
}

三.验证

写入和读取

uint32_t ArrayWrite[] = {0x01,0x02,0x03};
uint32_t ArrayRead[3];int main(void)
{	OLED_Init();W25Q64_Init();W25Q64_SectorErase(0x000000);        //擦除操作W25Q64_PageProgram(0x000000,ArrayWrite,3);        //写入数据W25Q64_ReadData(0x000000,ArrayRead,3);        读取数据OLED_ShowHexNum(2, 1, ArrayWrite[0], 2);    //显示写入的三个数据OLED_ShowHexNum(2, 5, ArrayWrite[1], 2);OLED_ShowHexNum(2, 9, ArrayWrite[2], 2);OLED_ShowHexNum(3, 1, ArrayRead[0], 2);       //显示读取的三个数据OLED_ShowHexNum(3, 5, ArrayRead[1], 2);OLED_ShowHexNum(3, 9, ArrayRead[2], 2);while (1){}
}

四.擦除说明

因芯片设计问题,数据在写入时,只能从1转为0,不可以从0转为1,如果要想从0 转为1,就只能进行擦除作业。擦除分整个擦除,扇区,块擦除三个等级,范围大小不一样,看需要进行操作

因此。我们在写入数据前应尽量进行扇区擦除来保证数据的准确性。大家可以屏闭擦除函数进行验证。


总结

W25Q64芯片存储数据还是比较好用,原理比较清楚。但还是有一些问题待解决

1.写入大数据(如200KB)而MCU除了必要的程序数据(不包含要写入W25Q64的数据)外还剩40K数据。我们需要对200K数据进行5次分割才能写入数据,比较麻烦且不方便量产

2.因芯片每页数据最大64K,因此我们还需对数据进行准确分割,不能超过。

相关文章:

通用外设-W25Q64

前言 一、SPI通信 二、W25Q64基初时序 1.各种命令代码 2.代码 1.写使能指令 2.读取芯片是否忙碌状态并等待 3.写入数据 4.擦除函数操作 5.读取代码 三.验证 四.擦除说明 总结 前言 在单片机中一般32K FLASH就够用了&#xff0c;但是当我们使用图片或其他大量数据时…...

Spring MVC MVC介绍和入门案例

1.SpringMVC概述 1.1.MVC介绍 MVC是一种设计模式&#xff0c;将软件按照模型、视图、控制器来划分&#xff1a; M&#xff1a;Model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;作用是处理数据 JavaBean分为两类&#xff1a; 一类称为数据承载Bean&#xf…...

android使用ndk开发

ndk ndk sdk要单独下载和android sdk不同 https://developer.android.google.cn/ndk/downloads?hl=zh-cn 解压后添加ndk路径到path即可 gradle gradle下载太慢使用国内镜像 distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-6.7.1-all.zip 执行gradlew.ba…...

行为型设计模式——模板方法模式

学习难度&#xff1a;⭐ &#xff0c;比较常用 模板方法模式 在面向对象程序设计过程中&#xff0c;程序员常常会遇到这种情况&#xff1a;设计一个系统时知道了算法所需的关键步骤&#xff0c;而且确定了这些步骤的执行顺序&#xff0c;但某些步骤的具体实现还未知&#xff0…...

曲面上偏移命令的查找

今天学习老王的SW绘图时&#xff0c;遇到一个命令找不到&#xff0c;查询了一会终于找到了这个命令&#xff0c;防止自己忘记&#xff0c;特此记录一下&#xff0c;这个命令就是“曲面上偏移”&#xff0c;网上好多的教程都是错误的&#xff0c;实际上这个命令没有在曲面里面&a…...

世邦spon IP网络对讲广播系统任意文件上传漏洞

产品介绍 世邦通信IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统存在任意文件上传漏洞&#xff0c;攻击者可以通过构造特殊请求包上传恶意后门文件&#xff0c;从…...

mp4文件全部转换为mp3

问题 今天突发奇想&#xff0c;想把mp4视频转换为mp3来收听&#xff0c;于是想到了ffmpeg工具 步骤 安装ffmpeg环境 要在 Windows 上配置 FFmpeg 环境&#xff0c;你可以按照以下步骤进行操作&#xff1a; 下载 FFmpeg&#xff1a; 首先&#xff0c;你需要下载 FFmpeg 的 W…...

深信服技术认证“SCSA-S”划重点:逻辑漏洞

为帮助大家更加系统化地学习网络安全知识&#xff0c;以及更高效地通过深信服安全服务认证工程师考核&#xff0c;深信服特别推出“SCSA-S认证备考秘笈”共十期内容&#xff0c;“考试重点”内容框架&#xff0c;帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…...

Linux grep命令教程:强大的文本搜索工具(附案例详解和注意事项)

Linux grep命令介绍 grep (Global Regular Expression Print)命令用来在文件中查找包含或者不包含某个字符串的行&#xff0c;它是强大的文本搜索工具&#xff0c;并可以使用正则表达式进行搜索。当你需要在文件或者多个文件中搜寻特定信息时&#xff0c;grep就显得无比重要啦…...

网络安全的威胁PPT

建议的PPT免费模板网站&#xff1a;http://www.51pptmoban.com/ppt/ 此PPT模板下载地址&#xff1a;https://file.51pptmoban.com/d/file/2023/03/20/1ae84aa8a9b666d2103f19be20249b38.zip 内容截图&#xff1a;...

CUDA驱动深度学习发展 - 技术全解与实战

全面介绍CUDA与pytorch cuda实战 关注TechLead&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&#xff0c;项目管理专业人士&…...

如何做用户分层和标签体系

“活动作了一场接一场&#xff0c;简直要累死了&#xff0c;拉进来的客户也没有多少&#xff0c;投入产出完全不成比例&#xff0c;怎么办&#xff1f;“ “有那么多注册用户&#xff0c;但是GMV怎么才这么点&#xff0c;他们怎么不买啊&#xff0c;难道都是羊毛党&#xff1f;…...

Vue+Element Ui实现el-table自定义表头下拉选择表头筛选

用vueelement ui开发管理系统时&#xff0c;使用el-table做表格&#xff0c;当表格列过多的时候&#xff0c;想要做成可选表头的&#xff0c;实现表格列的筛选显示&#xff0c;效果如下&#xff1a; 代码文件结构&#xff1a; 废话不多说&#xff0c;直接上代码&#xff1a; 第…...

使用Java连接MongoDB (6.0.12) 报错

报错&#xff1a; Exception in thread "main" com.mongodb.MongoCommandException: Command failed with error 352: Unsupported OP_QUERY command: create. 上图中“The client driver may require an upgrade”说明了“客户端驱动需要进行升级”&#xff0c;解…...

数学建模day16-预测模型

本讲首先将介绍灰色预测模型&#xff0c;然后将简要介绍神经网络在数据预测中的应用&#xff0c;在本讲的最 后&#xff0c;我将谈谈清风大佬对于数据预测的一些看法。 注&#xff1a;本文源于数学建模学习交流相关公众号观看学习视频后所作 目录 灰色系统 GM(1,1)…...

Vue3响应式系统(一)

一、副作用函数。 副作用函数指的是会产生副作用的函数。例如&#xff1a;effect函数会直接或间接影响其他函数的执行&#xff0c;这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如&#xff1a; //全局变量let val 2f…...

MStart | MStart开发与学习

MStart | MStart开发与学习 1.学习 1.MStart |开机LOG显示异常排查及调整...

GoZero微服务个人探索之路(一)Etcd:context deadline exceeded原因探究及解决

产生错误原因就是与etcd交互时候需要指定&#xff1a; 证书文件的路径 客户端证书文件的路径 客户端密钥文件的路径 &#xff08;同时这貌似是强制默认就需要指定了&#xff09; 但我们怎么知道这三个文件路径呢&#xff0c;如下方法 1. 找到etcd的配置文件&#xff0c;里…...

C语言从入门到实战——结构体与位段

结构体与位段 前言一、结构体类型的声明1.1 结构体1.1.1 结构的声明1.1.2 结构体变量的创建和初始化 1.2 结构的特殊声明1.3 结构的自引用 二、 结构体内存对齐2.1 对齐规则2.2 为什么存在内存对齐2.3 修改默认对齐数 三、结构体传参四、 结构体实现位段4.1 什么是位段4.2 位段…...

java如何修改windows计算机本地日期和时间?

本文教程&#xff0c;主要介绍&#xff0c;在java中如何修改windows计算机本地日期和时间。 目录 一、程序代码 二、运行结果 一、程序代码 package com;import java.io.IOException;/**** Roc-xb*/ public class ChangeSystemDate {public static void main(String[] args)…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

webpack面试题

面试题&#xff1a;webpack介绍和简单使用 一、webpack&#xff08;模块化打包工具&#xff09;1. webpack是把项目当作一个整体&#xff0c;通过给定的一个主文件&#xff0c;webpack将从这个主文件开始找到你项目当中的所有依赖文件&#xff0c;使用loaders来处理它们&#x…...