通用外设-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就够用了,但是当我们使用图片或其他大量数据时…...
Spring MVC MVC介绍和入门案例
1.SpringMVC概述 1.1.MVC介绍 MVC是一种设计模式,将软件按照模型、视图、控制器来划分: M:Model,模型层,指工程中的JavaBean,作用是处理数据 JavaBean分为两类: 一类称为数据承载Bean…...
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…...
行为型设计模式——模板方法模式
学习难度:⭐ ,比较常用 模板方法模式 在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知࿰…...
曲面上偏移命令的查找
今天学习老王的SW绘图时,遇到一个命令找不到,查询了一会终于找到了这个命令,防止自己忘记,特此记录一下,这个命令就是“曲面上偏移”,网上好多的教程都是错误的,实际上这个命令没有在曲面里面&a…...
世邦spon IP网络对讲广播系统任意文件上传漏洞
产品介绍 世邦通信IP网络对讲广播系统采用领先的IPAudio™技术,将音频信号以数据包形式在局域网和广域网上进行传送,是一套纯数字传输系统。 漏洞描述 spon IP网络对讲广播系统存在任意文件上传漏洞,攻击者可以通过构造特殊请求包上传恶意后门文件,从…...
mp4文件全部转换为mp3
问题 今天突发奇想,想把mp4视频转换为mp3来收听,于是想到了ffmpeg工具 步骤 安装ffmpeg环境 要在 Windows 上配置 FFmpeg 环境,你可以按照以下步骤进行操作: 下载 FFmpeg: 首先,你需要下载 FFmpeg 的 W…...
深信服技术认证“SCSA-S”划重点:逻辑漏洞
为帮助大家更加系统化地学习网络安全知识,以及更高效地通过深信服安全服务认证工程师考核,深信服特别推出“SCSA-S认证备考秘笈”共十期内容,“考试重点”内容框架,帮助大家快速get重点知识~ 划重点来啦 *点击图片放大展示 深信服…...
Linux grep命令教程:强大的文本搜索工具(附案例详解和注意事项)
Linux grep命令介绍 grep (Global Regular Expression Print)命令用来在文件中查找包含或者不包含某个字符串的行,它是强大的文本搜索工具,并可以使用正则表达式进行搜索。当你需要在文件或者多个文件中搜寻特定信息时,grep就显得无比重要啦…...
网络安全的威胁PPT
建议的PPT免费模板网站:http://www.51pptmoban.com/ppt/ 此PPT模板下载地址:https://file.51pptmoban.com/d/file/2023/03/20/1ae84aa8a9b666d2103f19be20249b38.zip 内容截图:...
CUDA驱动深度学习发展 - 技术全解与实战
全面介绍CUDA与pytorch cuda实战 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,项目管理专业人士&…...
如何做用户分层和标签体系
“活动作了一场接一场,简直要累死了,拉进来的客户也没有多少,投入产出完全不成比例,怎么办?“ “有那么多注册用户,但是GMV怎么才这么点,他们怎么不买啊,难道都是羊毛党?…...
Vue+Element Ui实现el-table自定义表头下拉选择表头筛选
用vueelement ui开发管理系统时,使用el-table做表格,当表格列过多的时候,想要做成可选表头的,实现表格列的筛选显示,效果如下: 代码文件结构: 废话不多说,直接上代码: 第…...
使用Java连接MongoDB (6.0.12) 报错
报错: Exception in thread "main" com.mongodb.MongoCommandException: Command failed with error 352: Unsupported OP_QUERY command: create. 上图中“The client driver may require an upgrade”说明了“客户端驱动需要进行升级”,解…...
数学建模day16-预测模型
本讲首先将介绍灰色预测模型,然后将简要介绍神经网络在数据预测中的应用,在本讲的最 后,我将谈谈清风大佬对于数据预测的一些看法。 注:本文源于数学建模学习交流相关公众号观看学习视频后所作 目录 灰色系统 GM(1,1)…...
Vue3响应式系统(一)
一、副作用函数。 副作用函数指的是会产生副作用的函数。例如:effect函数会直接或间接影响其他函数的执行,这时我们便说effect函数产生了副作用。 function effect(){document.body.innerText hello vue3 } 再例如: //全局变量let val 2f…...
MStart | MStart开发与学习
MStart | MStart开发与学习 1.学习 1.MStart |开机LOG显示异常排查及调整...
GoZero微服务个人探索之路(一)Etcd:context deadline exceeded原因探究及解决
产生错误原因就是与etcd交互时候需要指定: 证书文件的路径 客户端证书文件的路径 客户端密钥文件的路径 (同时这貌似是强制默认就需要指定了) 但我们怎么知道这三个文件路径呢,如下方法 1. 找到etcd的配置文件,里…...
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计算机本地日期和时间?
本文教程,主要介绍,在java中如何修改windows计算机本地日期和时间。 目录 一、程序代码 二、运行结果 一、程序代码 package com;import java.io.IOException;/**** Roc-xb*/ public class ChangeSystemDate {public static void main(String[] args)…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
