STM32—W25Q64

1.W25Q64简介

  • W25Oxx系列是一种低成本、小型化、使用简单的非易失性存储器
    • 易失性存储器 般就是SRAM、DRAM等
    • 非易失性存储器 般就是E2PROM、Flash等
  • 常应用于数据存储、字库存储、固件程序存储等场景
  • 存储介质:Nor Flash(闪存)
  • 时钟频率:80MHz  /  160MHz(DualSPI)双重SPI   /   320MHz(Quad SPI)四重SPI
  • 存储容量(24位地址):
    • W25040:        4Mbit / 512KByte
      W25080:        8Mbit / 1MByte
      W25Q16:       16Mbit / 2MByte
      W25Q32:       32Mbit / 4MByte
      W25064:        64Mbit / 8MByte
      W250128:      128Mbit / 16MByte
      W250256:      256Mbit / 32MByte

2的24方=16777216  /   1024  = 16384KB  /1024  =16MB   所以24位地址的最大寻址空间是16MB W25Q40到Q128,使用3字节24位的地址都是足够的,所以W25Q256分为3字节地址模式和4字节地址模式,在3字节地址模式下,只能读写前16MB的数据,后面16MB,3个字节的地址够不着,要想读写到所有存储单元,可以进入4字节地址的模式

AT24C02它的容量,一般是KB级别的

2.硬件电路

除了SPI通信引脚,还有两个引脚,一个是WP写保护,另一个是HOLD,这两个引脚,如果不需要的话,也可以拉过来,充当数据传输引脚,加上MOSI和MISO,这就可以4个数据位同时收发了,这就是四重SPI,其实这就有点并行传输的意思了,串行是根据时钟,一位一位地发送,并行是一个时钟,8位同时发送,所以这个四重SPI模式,其实就是4位并行的模式

1号引脚这个CS左边画了个斜杠,代表是低电平有效,或者这边,CS上面画了个横线,也是低电平有效,CS对应之前我们讲SPl的名称就是SS,意思是SPI的片选引脚

3号,WP(Write Protect),它的意思是写保护,配合内部的寄存器配置,可以实现硬件的写保护,写保护低电平有效,WP接低电平,保护住,不让写

最后7号,HOLD数据保持,低电平有效,就是如果你在进行正常读写时,突然产生中断,然后想用SP|通信线去操控其他器件,这时如果把CS置回高电平,那时序就终止了,但如果你又不想终止总线,又想操作其他器件,这就可以HOLD引脚置低电平,这样芯片就HOLD住了,芯片释放总线,但是芯片时序也不会终止,它会记住当前的状态,当你操作完其他器件时,可以回过来,HOLD置回高电平,然后继续HOLD之前的时序,相当于SPI总线进了一次中断,并且在中断里,还可以用SPI午别的事情,这就是HOLD功能

这个DI、DO、WP和HOLD旁边都有括号,写了1O0、IO1、1O2、IO3,这个就对应我们刚才这里说的,双重SP|和四重SPI,如果是普通的SPI模式,那括号里的都不用看,如果是双重SPI那DI和DO就变成IO0和IO1,也就是数据同时收和同时发的2个数据位,同理四重。。

3.框图

首先,右上角这一大块,描述的是存储器的规划示意图,我们这个W25Q64,容量是8MB,如果不进行划分,而只按照一整块来使用的话,那这一整块的容量就太大了,不利于管理,而且后续,我们涉及到F当sH擦除,或者写入的时候,都会有个基本单元,我们得以这个基本单元为单位进行,所以,这里,这 整块大蛋糕,8MB的存储空间,就有必要进行一些合理的划分

那常见的划分方式就是一整块存储空间,先划分为若干的块Block,其中每一块再划分为若干的扇区Sector,对于每个扇区,内部又可以分成很多页Page

那我们看下W25064是怎么划分的呢,首先,这一整个矩形空问里,是所有的存储器存储器以字节为单位,每个字节都有唯一的地址,之前说了,W25Q64的地址宽度是24位,3个字节,所以可以看到,左下角,第一个字节,它的地址是00 00 00H,H代表16进制,之后的空间,地址依次自增直到最后一个字节,地址是7FFFFFh,那最后一个字节为啥是7F开头,不是FF开头呢,因为24位地址,最大寻址范围是16MB,我们这个芯片只有8MB,只用了一半

然后在这整个空间里,我们以64KB为一个基本单元,把它划分成若干的块Block,从前往后,依次是块0、块1、块2、等等等等,直分到最后一块,那整块蛋糕是8MB,以64KB为一块进行划分,最后分得的块数,就是8MB/64KB=128块,那块序号就是块0,一直到块127,然后观察一下块内地址值的变化规律,比如块0的起始地址是00 00 00,结束地址是00 FF FF,之后,块31,起始是1F0000,结东是1FFFFF,在每一块内,它的地址变化范围就是低位的2个字节,每个块的起始是xx 0000,结東是xx FF FF

之后看一下左边,这个示意图就是我们还要再对每一块进行更细的划分,分为多个扇区Sector,这里的虚线看到没,指向了右边的各个块,也就是告诉你,每一块里面都是这个样子的,那在每个块里它的起始地址是xx 00 00,结東地址是xx FF FF,在一块里,我们再以4KB为一个单元,进行切分,块是64KB,我4KB一切,切成16份,所以在每一块里,都可以分为扇区0,一直到扇区15,每个扇区内的地址范围是减xx 0x 00到xx xF FF,这就是对每一块,再细分为16个扇区的分配方式,当然,地址划分,到扇区就结束了

但是当我们在写入数据时,还会有个更细的划分,这就是页Page,当然你也可以把它看作,在扇区里,再进行划分,都是一样,那页的大小呢,是256个字节,一个扇区是4KB,以256个字节划分,4x1024/256=16页,页的地址规律,我们也看一下,在这里,每一行就是一页,左边这里指了个箭头,写的是页地址的开始,右边这里也指了个箭头,写的是页地址的结束,在一页中,地址变化范围xx xx 00到xx xx FF,页内的地址变化,仅限于地址的最低一个字节

左下角,这是SPI控制逻辑,也就是芯片内部进行地址锁存、数据读写等操作,都可以由控制逻辑来自动完成,这个不用我们操心,控制逻辑就是整个芯片的管理员,我们有什么事,只需要告诉这个管理员就行了,然后,控制逻辑左边,就是SPl的通信引脚,有WP、HOLD、CLK、DI和DO,这些引脚,就和我们的生控芯片相连,主控芯片通过SPI协议,把指令和数据发给控制逻辑,控制逻辑就会自动去操作内部电路来完成我们想要的功能,

然后继续看,控制逻辑上面有个状态寄存器Status Register,这个状态寄存器是比较重要的,比如芯片是否处于忙状态、是否写使能、是否写保护,都可以以在这个状态寄存器里体现

然后上面,是写控制逻辑Write Control Logic和外部的WP引I脚相连,显然,这个是配合WP引l脚实现硬件写保护的,接着继续,右边这里,是个高电屈生成器High Voltage Generators,这个是配合Flash进行编程的。因为Hash是掉电不丢失的,如何实现掉电不丢失呢,比如你点亮一个LED表示1,熄灭LD表示0,但如果整个系统电都没有,那1和0就无从说起了,所以要想掉电不丢失,就要在我们的存储器里,产生些刻胃铭心的变化,比如,一个LED,我给它加很高的电压,那LED就烧坏了,我们用烧坏的LED表示1,没烧坏的LED表示0,然后再断电,烧坏的LED还是烧坏的,有电没电,它都是坏的,这个烧没烧坏的状态,不受有电还是没电的影响,所以它就是掉电不丢失的

那对于我们的非易失性存储器来说,也是一样,我们要让它产生一个即使断电也不会消失的状态,般都需要一个比较高的电压去刺激它,所以这种掉电不丢失的存储器,一般都需要一个高压源,那这里,芯片内部集成了高电压发生器,所以就不需要我们再外接高电压了,比较方便

然后在下面,这里是页地址锁存/计数器(Page Address Latch / Counter),然后下面还有个字节地址锁存数器(Byte Address Latch / Counter),这两个地址锁存和计数器,就是用来指定地址的,我们通过SPI,总共发过来3个字节的地址,因为一页是256字节,所以一页内的字节地址,就取决于最低一个字节,而高位的2个字节,就对应的是页地址,所以在这里,我们发的3个字节地址,前两个字节,会进到这个页地址锁存计数器里,最后一个字节,会进到这个字节地址锁存计数器里,然后,页地址,通过这个写保护和行解码,来选择我要操作哪一页,字节地址,通过这个列解码和256字节页缓存,来进行指定字节的读写操作,那又因为我们这个地址锁存,都是有一个计数器的,所以这个地址指针,在读写之后,可以自动加1,这样就可以实现从指定地址开始,连续读写多个字节的目的了

那最后,右边这里,有个256字节的页缓存区,它其实是一个256字节的RAM存储器,然后,我们数据读写,就是通过这个RAM缓存区来进行的,我们写入数据,会先放到缓存区里,然后在时序结束后,芯片再将缓存区的数据复制到对应的Flash里,进行永久保存
为啥要弄一个缓存区呢?我们直接往Flash里写不好吗,那这是因为,我们的SPI写人的频率是非常高的,而Flash的写入,由于需要掉电不丢失,留下刻骨铭心的印象,它就比较慢,所以,这个芯片的设计思路就是你写入的数据,我先放在页缓存区里存着,因为缓存区是RAM,所以它的速度非常快,可以跟得上SPl总线的速度,但是这里有个小问题,就是这个缓存区只有256字节,所以写入的时序有个限制条件就是写入的一个时序,连续写入的数据量,不能超过256字节,然后等你写完了,我芯片再慢慢地把数据,从缓存区转移到Flash存储器里,那我数据从缓存区转到Flash里,需要一定的时间,所以在写入时序结束后,芯片会进入一段忙的状态,在这里,它就会有一条线通往状态寄存器,给状态寄存器的BUSY位置1,表示芯片当前正在搬砖呢,很忙,那在忙的时候,芯片就不会响应新的读写时序了,这就是写入的执行流程

然后我们读取数据呢,虽然这里画的应该也会通过缓存区来读取,但是由于读取,只是看一下电路的状态就行了,它某本不花时间,所以读取的限制就很少了,速度也非常快

4.Flash操作注意事项

写入操作时:

  • 写入操作前,必须先进行写使能
  • 每个数据位只能由1改写为0,不能由0改写为1
  • 写入数据前必须先擦除,擦除后,所有数据位变为1
  • 擦除必须按最小擦除单元进行
    • Flash的擦除,有最小擦除单元的限制,你不能指定某一个字节去擦除,要擦,就得一大片一起擦,在我们这个芯片里可以选择,整个芯片擦除,也可以选择,按块擦除,或者按扇区擦除然后再小,就没有了,所以最小的擦除单元,就是一个扇区4KB,就是4096个字节
    • 那你说,我只想擦除某一个字节怎么办呢,这没办法,你只能把那个字节所在扇区的4096个字节全都掉,如果存储了数据怎么办,这也没办法,要想不丢失数据,你只能先把4096个字节都读出来,再把4096个字节的扇区擦掉,改写完读出来的数据后再把4096个字节全都写回去
    • 实际情况下,我们还有别的方法可以优化一下这个流程,比如,上电后,我先把Flash的数据读出来,放到RAM里,当有数据变动时,我再统一把数据备份到Flash里,或者,我把使用频繁的扇区,放在RAM里,当使用频率降低时,我再把整个扇区备份到FLash里,或者,如果你数据量确实非常少,只想存几个字节的参数就行了,那直接一个字节占一个扇区,不就行了嘛,尽限奢之风
  • 连续写入多字节时,最多写入一页的数据256字节,超过页尾位置的数据,会回到页首覆盖写入
  • 写入操作结束后,芯片进入忙状态,不响应新的读写操作

读取操作时:

  • 直接调用读取时序,无需使能,无需额外操作,没有页的限制,
  • 读取操作结束后不会进入忙状态,但不能在忙状态时读取

我们来看下Hash操作的注意事项,这里列出了这么多Hash写入和读取的要求,那你可能会有些疑惑,不就是个存储器吗,我直接指定地址写或者指定地址读然后它直接给我把数据存在对应的存储单元里不就行了嘛,为啥还要搞这么多的注意事项呢,其实,这是因为Flash,作为一种掉电不丢失的存储器,为了保证掉电不丢失这个特性,同时还要保证存储容量足够大、成本足够低,所以,Flash存储器会在其他地方,比如操作的便捷性等做出一些要协和让步,Hash的写入和读取并不像RAM那样简单直接,RAM是指哪打哪,想在哪写就在哪写,想写多少就写多少,并且RAM是可以覆盖写入的,但是Flash并没有这个特性,总之,Hlash的读写有很多要求,其中写入的要求是非常多的,需要我们掌握

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C语言 | 第十三章 | 二维数组 冒泡排序 字符串指针 断点调试

P 120 数组应用案例 2023/1/29 一、应用案例 案例一&#xff1a;创建一个char类型的26个元素的数组&#xff0c;分别 放置’A’-Z‘。使用for循环访问所有元素并打印出来。提示&#xff1a;字符数据运算 ‘A’1 -> ‘B’ #include<stdio.h>void main(){/*创建一个c…

Mysql中创建用户并设置任何主机连接

Mysql中创建用户并设置任何主机连接 文章目录 Mysql中创建用户并设置任何主机连接背景解决方式 背景 在linux上安装mysql,默认用户是root,但是用navicat连接不了,必须要用ssh隧道连接,现在想用任何主机只要输入账号密码之后就可以连接 解决方式 #创建一个指定用户和IP链接的用…

通过祖先序列重建辅助工程化UDP-糖基转移酶-文献精读64

Engineering the Substrate Specificity of UDP-Glycosyltransferases for Synthesizing Triterpenoid Glycosides with a Linear Trisaccharide as Aided by Ancestral Sequence Reconstruction 通过祖先序列重建辅助工程化UDP-糖基转移酶的底物特异性&#xff0c;用于合成具…

股市有人吹的“哨音”也应倾听

国庆节前&#xff0c;深圳东方港湾投资管理股份有限公司董事长但斌发微博警告说&#xff1a;“这样暴涨&#xff0c;必有暴跌&#xff0c;这次如果再被套住&#xff0c;该动员的力量都动员了解套将遥遥无期”他这样警告&#xff0c;就与新冠病毒刚在武汉爆发时的“吹哨人”起的…

重头开始嵌入式第四十六天(硬件 ARM裸机开发 ADC 中断 UART)

目录 ADC使用 1.什么是ADC&#xff1f; 一、功能 二、工作原理 三、参数指标 四、应用领域 2.如何配置s3c2440中的adc&#xff1f; 中断 1.什么是中断&#xff1f; 一、定义 二、中断的作用 三、中断的类型 四、中断处理过程 2.如何配置中断&#xff1f; UART 1…

一站式服务,产业园运营让创业更轻松!

一站式服务&#xff0c;也被称为“一条龙服务”或“全流程服务”&#xff0c;它是指企业或机构为了满足客户或用户的需求&#xff0c;整合内部资源&#xff0c;通过优化服务流程、提高服务效率&#xff0c;从而提供从咨询、受理、办理到反馈等各个环节的完整、连续、高效的服务…

汽车主机厂主数据管理中一物多码或多码一物问题的具体表现有哪些?

数据入口多导致重复编码 在汽车主机厂的主数据管理中&#xff0c;由于存在多个数据入口&#xff0c;不同部门或环节可能会独立进行数据录入。这就容易出现一物多码或多码一物的情况。例如&#xff0c;采购部门、生产部门、物流部门等可能各自采用不同的编码体系来标识同一种汽…

车辆路径规划问题(VRP)优化方案

车辆路径规划问题&#xff08;VRP&#xff09;优化方案 车辆路径规划问题&#xff08;Vehicle Routing Problem, VRP&#xff09;是物流领域中一个经典的组合优化问题&#xff0c;目标是在满足客户需求的情况下&#xff0c;找到一组车辆的最优配送路径&#xff0c;以最小化总的…

PMP11月考试中文报名10月9日开始!

经过PMI与中国国际人才交流基金会的联合研究决定&#xff0c;2024年度第四期PMI认证考试将于11月30日进行。 为了让各位考生能够充分准备&#xff0c;我们特此梳理了本次考试的具体安排及注意事项&#xff0c;请务必仔细阅读&#xff01; 报名时间安排&#xff1a; &#xf…

使用Python批量修改文件修改日期为随机的6到8月份

使用Python批量修改文件修改日期为随机的6到8月份 每当雪花飘起的时候&#xff0c;总有一股抹不去的情节&#xff0c;会想起儿时雪天的记忆&#xff0c;虽然模糊但也清晰。那时每年的冬季很冷&#xff0c;但依然喜欢飘雪的日子&#xff0c;看着满天迷蒙飘舞的雪花总有想不完的心…

microsoft edge浏览器卡死问题

win11经常遇到microsoft edge浏览器卡死的情况&#xff0c;有时候是一会没用浏览器就全部卡死&#xff0c;有时候是锁屏或者电脑休眠浏览器就不能用&#xff0c;找了很多的办法都没好使&#xff0c;用以下方法好使了&#xff1a; edge浏览器中打开 edge://settings/system 把 …

架设传奇SF时提示此服务器满员,GEE引擎点开始游戏弹出服务器满员的解决方法

昨天一个朋友在架设GEE的传奇服务端时遇到一个奇怪的问题&#xff0c;就是在服务器外网架设时&#xff0c;建好角色点开始游戏提示此服务器满员&#xff0c;这个问题一般比较少见&#xff0c;而且出现的话一般都是GEE引擎的版本。 他折腾了半天&#xff0c;一直没进游戏&#x…

apt update报错:ModuleNotFoundError: No module named ‘apt_pkg‘(可能是默认python版本被改坏了)

文章目录 错误信息分析1. 确保 apt_pkg 模块已安装2. 检查 Python 版本3. 重新配置 Python4. 修复损坏的依赖5. 检查环境变量 尝试 错误信息 (base) rootkyai:/ky/tml/ky_ai_get_server_info# apt update 获取:1 file:/var/cuda-repo-cross-aarch64-ubuntu2004-11-4-local InR…

简易入门:使用Docke 部署一个tomcat服务

简易入门&#xff1a;使用Docke 部署一个tomcat服务 # 拉取 >docker pull tomcat:9.0# 后台运行容器&#xff0c;端口映射为8080. -p 宿主机端口:容器端口 >docker run -d --name tomcat-c-01 -p 8080:8080 tomcat:9.0# 查看容器id >docker ps CONTAINER ID IMAG…

Go语言对接微信支付与退款全流程指南

在互联网技术日益发展的今天&#xff0c;线上支付已成为不可或缺的一部分。作为一门简洁高效的编程语言&#xff0c;Go&#xff08;又称Golang&#xff09;凭借其强大的并发处理能力和高效性能&#xff0c;在后端开发领域越来越受到开发者的青睐。本文将详细介绍如何使用Go语言…

【Java SE基础回顾】看这篇就够了!

JavaSE复习 参考视频&#xff1a;【狂神说Java】JavaSE阶段回顾总结 简单的就不讲了&#xff0c;比如什么break和continue区别&#xff0c;甚至一些什么什么继承封装多态的概念等等。 主要写一些Java特有的&#xff0c;重点的基础知识。主要还是例子和代码更多&#xff0c;更有…

对象存储之阿里云OSS最详细的实现

Hello&#xff0c;大家好&#xff0c;我是Feri&#xff0c;一枚十多年的程序员&#xff0c;同时也是一名在读研究生&#xff0c;关注我&#xff0c;且看一个平凡的程序员如何在自我成长&#xff0c;只为各位小伙伴提供编程相关干货知识&#xff0c;希望在自我蜕变的路上&#x…

【JS】环形链表怎么找入口?

思路 判断是否有环&#xff1a;定义快慢指针&#xff0c;慢指针&#xff08;slow&#xff09;走一步&#xff0c;快指针&#xff08;fast&#xff09;走两步。 无环&#xff1a;快指针最终会到达链表的末尾&#xff08;即fast.next为null&#xff09;,永远不可能相遇有环&#…

C++ 二叉搜索树转换为双向链表

描述 输入一棵二叉搜索树&#xff0c;将该二叉搜索树转换成一个排序的双向链表: 代码 #include <iostream> #include <string> #include <optional>struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x): val(x), left(…

陈零九全新单曲《也曾想走进你的心底》 揭露爱而不得的情感遗憾

图片提供&#xff1a;种子音乐 “创作男神”陈零九于10月9日推出充满深情的全新创作单曲《也曾想走进你的心底》&#xff0c;这首歌再次延续他招牌的“九式情歌”风格&#xff0c;展现其创作魅力。歌曲以一段“爱而不得”的感情故事为主线&#xff0c;深入探讨人们在爱情中的复…