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

单片机内部结构基础知识 FLASH相关解读

一、总线简单说明

地址总线、控制总线、数据总线

什么是8位8051框架结构的微控制器?
数据总线宽度为8位,即CPU一次处理或传输的数据量为8位(1字节)
同时还有一个16位的地址总线,这个地方也刚好对应了为什么能看到内存地址是0000H-03FFH这种字眼。这里就是跟直接寻址内容等强相关,就是说CPU的能力是16位,这个地方就跟内存空间息息相关,因为我们如果想内存大,就不得不扩大我们的内存,而扩大我们的内存就意味着增加了CPU的地址总线访问能力,目前常见的如48位→256TB内存支持。所以嵌入式一般的地址总线并不是很大。
此外需要说明的是不管是0000H(16位)还是FFFFFFFFH(32位)他能存储的数据就是一个字节,之所以这么长,目的只是为了提升存储空间。

这个怎么计算呐?
例如0000H-FFFFH,为什么表示64KB,一个地址可以存储一共表示65536个字节,字节称为Byte(1个字节包含8位,bit)。
65536B = 64KB
那数据总线表示的是可以同时取多少个字节(一个地址存储一个字节,如果是16位数据总线,那么就可以同时取出2个字节,也就是需要同时读出两个地址里面存储的数据,不然怎么实现读出16位数据。这个地方和地址总线大小无关,但是如何执行这些操作肯定是有关系的,那就是后话。)。常用的处理器32位,64位,显卡可能是128位。
如果具有40位数据总线,那么本身是32位处理器,那么相当于是一次能读取4个字节的数据才能最大限度发挥该性能,那么相当于是需要找到四个地址(并不是同时读取这四个地址,毕竟如果同时读取就需要160位,不符合逻辑。这个里面应该是流水线结构。)。

二、单片机内部内存空间理解

◆ 最大 64KB 的 FLASH 程序存储器(APROM 区)。

◆ 最大 1KB 的非易失性数据存储器(Data FLASH)。

◆ 最大 256B 的通用内部数据存储器(RAM)。

◆ 最大 4KB 的通用外部数据存储器(XRAM)。

◆ 特殊功能寄存器 SFR。

◆ 外部特殊功能寄存器 XSFR。

2.1 程序储存器 FLASH

以51单片机为例:
程序存储器 FLASH 用来存放源程序和表格数据,且以程序计数器 PC 作地址指针。PC 为 16 位程序计数器,因此可以寻址
到的地址空间为 64KB,此芯片有 64K bytes 程序存储空间。具体空间是:0000H-FFFFH

芯片复位后,CPU 从 0000H 开始执行。每个中断在程序存储器中都分配有固定的地址,中断使 CPU 跳到该地址开始执行
服务程序。例如外部中断 1,被分配地址为 0013H,如果使用外部中断 1,它的服务程序必须从 0013H 位置开始。如果没有用到该中断,其服务地址作为普通程序存储地址使用。

Flash存储器在正常存储状态下断电不会丢失数据​(非易失性特性),但在写入或擦除操作过程中突然断电可能导致数据损坏或丢失

引入一个问题:
那地址0013H存储的程序是中断服务程序吗

1. ​0013H的本质是中断向量入口(非完整服务程序)​

  • 固定入口地址​:在8051单片机中,外部中断1(INT1)的中断向量被硬件固定分配在0013H地址
    这是CPU响应中断时自动跳转的目标地址
  • 空间限制​:0013H至001BH之间仅有8字节空间(0013H~001AH),不足以存放完整的中断服务程序(ISR) 若强行在此写入长代码,会覆盖后续中断入口(如定时器1中断入口001BH)

2. ​0013H通常存储跳转指令(AJMP/LJMP)​

  • 跳转设计​:因此芯片原厂需在0013H处放置无条件跳转指令​(如AJMPLJMP),将程序流导向实际的中断服务程序地址

    ORG 0013H     ; 外部中断1入口
    AJMP INT1_ISR ; 跳转到实际ISR
    
  • 实际ISR位置​:中断服务程序通常存放在程序存储器的其他空闲区域​(如0100H之后),避免占用中断向量区。

3. ​未使用中断时,0013H可作为普通程序空间

  • 灵活性设计​:若系统未启用外部中断1,0013H地址可自由存储其他程序代码或数据​(如初始化代码、常量表)
  • 注意事项​:若后续启用该中断,必须确保0013H处已覆盖为正确的跳转指令,否则CPU可能执行无效代码导致崩溃。

4. ​中断响应的完整流程

  • 触发中断​:INT1引脚有效 → CPU检测中断标志 → ​自动加载0013H到PC
  • 执行跳转​:CPU从0013H读取跳转指令 → ​跳转至实际ISR地址​ → 执行中断处理逻辑。
  • 返回主程序​:ISR结尾执行RETI指令 → 恢复断点地址,继续主程序。

简单理解一下:
这个地方也就解决了,我之前的一个疑问,就是为什么执行完中断以后,还能回到原来的地方,里面的数据等不会改变,因为CPU执行程序,都是和内存进行交互,一切基于地址,此时在执行其他地址上面的程序,那原本的就不执行了,然后再使用一个跳转执行,恢复到断点地址,继续执行程序。这个里面涉及到保护现场等知识,先不进一步理解。

关于Flash引入另外一个问题
Flash是非易失性数据区域,那么我们在写入EEPROM的时候,是否能写入Flash?
EEPROM(电可擦除可编程只读存储器)不会直接写入Flash存储器

一、EEPROM与Flash的物理隔离性

  1. 独立的存储单元结构

    • EEPROM​:通过浮栅晶体管实现按字节擦写,每个存储单元可独立修改电荷状态,无需整块擦除

    • Flash​:采用更简化的晶体管结构,​必须按扇区(Block)擦除​(如4KB~128KB),擦除后整块区域变为全1(0xFF)才能写入新数据

    • 物理隔离​:在芯片设计中,EEPROM和Flash通常是独立的物理模块,通过不同总线地址访问(如EEPROM映射到数据存储区,Flash映射到程序存储区

  2. 不同的控制器逻辑

    • EEPROM控制器支持直接覆盖写入​(如写入0x55到地址0x20,旧数据自动擦除)

    • Flash控制器需先发送擦除命令,再执行写入操作,无法跳过擦除步骤。

二、EEPROM的写入机制

  1. 直接电荷注入
    EEPROM通过隧道效应(Fowler-Nordheim Tunneling)​​ 直接修改目标字节的浮栅电荷:

    • 写入0:向浮栅注入电子,提高阈值电压。
    • 写入1:抽出电子,降低阈值电压
      无需整块擦除​:此过程仅影响目标单元,相邻数据保持不变。
  2. 内部电荷泵支持
    即使外部电压为3.3V/5V,EEPROM内置电荷泵可生成高压(12V20V),实现单字节操作


三、Flash的写入限制

  1. ​==只能写0,不能直接写1​==
    Flash的存储单元特性决定:
    • 写操作​:仅能将1变为0(通过热电子注入)。
    • 擦除操作​:通过强电场释放浮栅电荷,将整块数据恢复为全10xFF
      若未擦除直接写入,原有0无法变为1,导致数据错误
  2. 擦除粒度大
    擦除最小单位为扇区(如STM32的Flash扇区为1KB~128KB),即使只修改1字节,也需重写整个扇区。
特性EEPROMFlash
最小擦除单位字节(Byte)扇区(Block,4KB~128KB)
写入机制直接覆盖旧数据必须先擦除整块再写入
写入速度较慢(ms/字节)较快(擦除后批量写入)
寿命10⁶次擦写10⁴~10⁵次擦写
典型应用参数配置(如校准值)程序代码、大容量数据存储

EEPROM映射到数据存储区,Flash映射到程序存储区

EEPROM的写入操作仅作用于自身物理单元,不会影响Flash存储区。两者在硬件层面完全独立,不存在交叉写入的可能性。若需在Flash中存储数据,必须通过专用Flash控制器执行擦除和写入流程。

2.2 非易失性数据存储器 Data FLASH

非易失性数据存储器 Data FLASH 可用于存放常量数据、校准数据、防护安全相关信息等重要数据。存储在该区域的数据具有在芯片断电或者突然性、意外性断电时,数据不会丢失的特性。

Data FLASH 存储器的读、写、擦除操作通过 FLASH 控制接口实现。

为什么需要Data Flash?​

1. 解决Code Flash的局限性
  • 擦写寿命瓶颈​:Code Flash擦写次数有限(约1万次),频繁写入会缩短寿命。Data Flash通过优化存储单元结构(如NAND型)和磨损均衡算法,支持更高擦写次数(10万次+)。
  • 写入效率优化​:Code Flash需整块擦除才能写入,操作耗时(如STM32擦除1KB需40ms)。Data Flash支持页写入(如512B),减少无效擦除。
2. 满足数据存储的特定需求
  • 动态数据管理​:系统运行中产生的参数(如温度校准值)、事件日志需频繁更新,Data Flash提供专用空间避免干扰代码区。
  • 高密度低成本存储​:Data Flash采用NAND结构,单元密度高(如QLC每单元4bit),成本仅为NOR Flash的1/10,适合大数据存储(如音频、图像)。
3. 系统安全性与可靠性
  • 隔离代码与数据​:Code Flash写错误可能导致程序崩溃。Data Flash独立操作,通过ECC校验和坏块管理提升数据完整性。
  • 掉电保护机制​:Data Flash设计支持紧急数据保存(如电容缓冲+CRC校验),在断电前完成关键数据存储。
4. 扩展性与灵活性
  • 接口简化​:SPI/I²C接口的Data Flash减少引脚占用(仅4~6线),适合空间受限的便携设备(如智能手表)。
  • 标准化封装​:eMMC、SD卡等Data Flash模块可热插拔,便于存储扩展(如工业相机更换存储卡)。
5.典型应用场景
  • Code Flash​:
    ✅ 单片机启动代码(STM32的0x0800_0000
    ✅ 实时操作系统内核(如FreeRTOS)
  • Data Flash​:
    ✅ 用户配置保存(如Wi-Fi密码)
    ✅ 黑匣子日志(汽车ECU事件记录)
    ✅ 固件升级缓存(OTA下载包临时存储)
6.​使用注意事项
  1. 避免混用区域​:
    Code Flash写错误会导致程序崩溃,Data Flash需严格通过控制器访问(如STM32的HAL_FLASH_Program())。
  2. 磨损均衡必需​:
    高频写入时需动态分配物理地址(如日志结构写入),延长Data Flash寿命。
  3. 掉电保护设计​:
    搭配硬件PVD检测(电压阈值触发中断)和软件原子操作,确保数据完整性

在嵌入式系统中,程序运行时的临时数据通常不会直接存储在Flash中,而是存储在RAM(随机存取存储器)中。Flash主要用于存储程序代码和需要长期保存的非易失性数据(如配置参数),而RAM负责存储运行时的变量、堆栈和动态内存数据。

Flash存储器的物理结构中,“页”和“扇区”是不同层级的操作单元

包含层级
​==页(Page)​​ 是Flash的最小写入单位,通常为256字节​(如W25Q系列)。==

扇区(Sector)​​ 是Flash的最小擦除单位,通常为4KB​(即16页 × 256字节)。

块(Block)​​ 是更高层级单位,通常包含多个扇区(如16扇区=64KB)。

以中微CMS80F761X为例

FLASH 存储器包含程序存储器(APROM)与非易失数据存储器(Data FLASH)。程序存储器空间最大为 64KB,分为 128个扇区,每个扇区包含 512B。数据存储器空间最大为 1KB,分为 2 个扇区,每个扇区包含 512B。
==页(Page)​​ 是Flash的最小写入单位,通常为256B
扇区(Sector)​​ 是Flash的最小擦除单位,通常为512B

Flash 存储器擦除操作仅支持扇区擦除,不支持字节擦除。在修改某个地址的数据之前,建议先将其他数据保存后,再擦除当前扇区,最后进行数据写入操作。

第一部分:连续写入等待Flash操作完成for(i = 0 ;i< 256 ;i++)		//连续256 bytes的写等待Flash执行完成{			FLASH_Write(FLASH_CODE,0xEFFF, 0xFF); //写地址使用最后的地址(任意地址都可以,建议用使用较少的地址)}
  • 强制等待Flash内部操作

    • Flash写入后需等待内部电荷泵操作完成(通常需数µs至ms级时间)。循环256次写入0xFF到固定地址(如0xEFFF),实质是通过重复写入触发Flash控制器状态检测,确保每次写入后Flash完成内部操作 。
    • 为何选择0xFF
      0xFF是擦除后的默认值(全1状态),写入0xFF不会改变原有数据​(Flash只能将1→0,不能0→1),因此是安全的“空操作” 。
  • 地址选择的逻辑

    • 使用固定地址(如0xEFFF)是为了避免跨页风险。Flash写入受页限制(通常256字节/页),若写入跨越页边界会导致数据回绕错误。末尾地址通常未被程序占用,适合测试 。
  • 替代状态寄存器查询

    • 部分低端MCU无状态寄存器,需通过写入操作间接同步。但此方法效率低​(256次写入耗时≈256ms),且加速Flash磨损​(寿命约10⁴次)
第二部分:数据写入与验证for(addr = 0x1000 ;addr< 0x1010 ;addr++){			FLASH_Write(FLASH_CODE,addr, Dtemp++);			temp = FLASH_Read(FLASH_CODE,addr);		}
  • 递增数据写入(Dtemp++)​

    • 在地址0x10000x100F(共16字节)写入连续递增的字节数据(如0x01, 0x02…)

    • 关键前提​:目标区域必须已擦除(全为0xFF),否则写入会失败(如尝试将0x00改为0x01

  • 即时读取验证

    • 每次写入后立即读取相同地址数据,比对tempDtemp是否一致,用于检测写入是否正确Flash物理损坏
  • 地址范围选择

    • 0x1000通常是用户数据区起始地址(避开代码区),长度16字节适合小数据测试(如配置参数)

在写入数据的时候,
Flash允许单次写入的数据量小于页大小(256字节),但写入地址必须在同一页内不跨页边界

  • 写入前​:目标区域必须为全10xFF),否则无法正确写入(未擦除区域写入非0xFF数据会导致数据错误)

  • 写入后​:若需修改已写入的数据(如将0x00改为0x01),必须先擦除整个扇区

一般情况要从其实地址开始写入

但是写入的少的时候,不一定非要是起始地址,只需要再规定的地址写就行了。

数据截断规则
编译器或硬件会自动丢弃高 8 位,保留低 8 位:

擦除函数


void FLASH_Erase(uint8_t FLASHModule, uint16_t Addr)
{MADRL = Addr;MADRH = Addr>>8;if(1==EA)			{EA=0;		MCTRL  = FLASH_ERASE | FLASHModule;	//操作FLASH期间不允许被打断_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();	while(MCTRL & 0x01);EA=1;}else{MCTRL  = FLASH_ERASE | FLASHModule;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();			while(MCTRL & 0x01);}
}

其中MCTRL就是操作,看数据手册,关于寄存器的描述,一定要看关于数据手册的描述,不然就会走到误区,容易走弯路。如
![[Pasted image 20250606163812.png]]

在硬件层面,会自动执行相关操作,
这个函数的Addr,说白了就是为了定位扇区,然后进行擦除。
不然怎么进行扇区擦除。硬件自动的执行一些操作。这就又设计到芯片原厂的操作了。至于为什么,那就暂时就理解到这里。

文章源码获取方式:
如果您对本文的源码感兴趣,欢迎在评论区留下您的邮箱地址。我会在空闲时间整理相关代码,并通过邮件发送给您。由于个人时间有限,发送可能会有一定延迟,请您耐心等待。同时,建议您在评论时注明具体的需求或问题,以便我更好地为您提供针对性的帮助。

【版权声明】
本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议。这意味着您可以自由地共享(复制、分发)和改编(修改、转换)本文内容,但必须遵守以下条件:
署名:您必须注明原作者(即本文博主)的姓名,并提供指向原文的链接。
相同方式共享:如果您基于本文创作了新的内容,必须使用相同的 CC 4.0 BY-SA 协议进行发布。
示例:
如果您在博客或文章中引用了本文的内容,请在显著位置标注类似以下声明:
本文部分内容参考自 [博主名称] 的原创文章,原文链接:[文章链接],遵循 CC 4.0 BY-SA 版权协议。
感谢您的理解与支持!如果您有任何疑问或需要进一步协助,请随时在评论区留言。*

http://www.xdnf.cn/news/902899.html

相关文章:

  • 数据集-目标检测系列- 口红嘴唇 数据集 lips >> DataBall
  • windows10搭建nfs服务器
  • Linux中 SONAME 的作用
  • mysql-MySQL体系结构和存储引擎
  • 《UE5_C++多人TPS完整教程》学习笔记37 ——《P38 变量复制(Variable Replication)》
  • Xsens-AAA工作室品质,为动画师准备
  • 中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点
  • Bootstrap 5 文件结构与 API 使用指南
  • 从EDR到XDR:终端安全防御体系演进实践指南
  • 汽车免拆诊断案例 | 2010款捷豹XFL车制动警告灯、DSC警告灯异常点亮
  • curl获取ip定位信息 --- system(一)
  • Git版本控制工具详解
  • 电脑定时关机工具推荐
  • scss(sass)中 的使用说明
  • 装载机防撞系统:智能守护,筑牢作业现场人员安全防线
  • 智绅科技 —— 智慧养老 + 数字健康,构筑银发时代安全防护网
  • JVM虚拟机:内存结构、垃圾回收、性能优化
  • 用设计模式重新思考(类FSM)验证:从混乱到优雅
  • 无人机定位系统技术设计与难点突破!
  • 项目管理的五个阶段有哪些核心功能?项目管理过程需要注意什么?
  • LlamaFactory × 多模态RAG × Chat-BI:万字长文探寻RAG进化轨迹,打造卓越专业AI助手
  • 20250606-C#知识:泛型与非泛型容器的基本操作
  • gitlab CI/CD本地部署配置
  • maven微服务${revision}依赖打包无法识别
  • 【数据结构】B树
  • linux操作系统笔记1
  • 鸿蒙开发 获取当前页面的路径和名字
  • 深入理解指针(二)
  • 文件上传漏洞深度解析:检测与绕过技术矩阵
  • 深入理解 transforms.Normalize():PyTorch 图像预处理中的关键一步