嵌入式入门必备:单片机存储结构详解,主存 / 外部内存 / 地址空间全解析

在之前的课程中,我们已经编写了一些运行在树莓派 Pico 开发板上的 MicroPython 程序,并且使用 PyCharm 的 MicroPython 插件将编写好的代码上传到开发板(即烧录程序),代码上传后,MicroPython 虚拟机会将其编译为字节码,虚拟机的解释器也会逐行解释字节码并将其转换为低级指令,与 MCU 的硬件资源进行交互。

那么问题来了,这些代码具体存储在 MCU 的哪个地方?它们又是如何被执行的呢?我们需要了解程序与 MCU 之间的关系,这里我们首先讲解程序的存储相关知识点。

单片机的存储结构概述

单片机中用于存储程序代码和运行数据的存储空间被称为内存,从是否与 CPU 直接相连的角度,单片机的内存可以分为以下两种:

  • 主内存(Main​ Memory) 是 CPU 可以快速、直接访问的内存,它主要用于存储当前正在执行的程序代码和数据,典型的主内存包括 ROM(只读存储器)和 RAM(随机存取存储器);无论是 ROM 还是 RAM,它们的主要作用都是存储程序和数据,ROM 通常存储固定的程序代码,RAM 则用于存储运行时的数据和可变程序
  • 外部内存(External Memory) 通常指的是不直接与 CPU 相连的存储设备,例如通过 USB、串口或并行接口访问的数据存储器,它们主要用于保存尚未执行的程序代码或数据,在需要时,外部内存中的数据需要先加载到主内存中,然后 CPU 才能执行

1.主内存的分类和特点

主内存可以分为以下几个部分:

  • 程序存储器(ROM​​​:存储固化的程序指令,单片机上电后从此处读取并执行程序,单片机多采用 Flash 存储器,它具备可擦写性,允许反复更新程序等特性,常见容量从几 KB 到数百 KB,部分高端单片机甚至达到几 MB
  • 数据存储器(RAM​​​:存储程序运行时的临时数据和变量,单片机中往往使用静态 SRAM 来保存全局变量、局部变量和中间数据,SRAM 读写速度快但在断电后数据会丢失,常见的 MCU RAM 容量从几百字节到几百 KB
  • 特殊功能寄存器(SFR)​:存储控制单片机运行的状态信息,尤其是与外设和内核相关的配置,包括程序计数器(PC)、堆栈指针(SP)和外设控制寄存器
  • ​通用寄存器​组(​​GPR)​:这些寄存器用于存储临时数据和运算结果,是 CPU 与内存交互的桥梁

1.1 ROM 只读存储器介绍

ROM(Read-Only Memory,只读存储器)是一种非易失性存储器,它在计算机和嵌入式系统中起着重要的作用。ROM 的特点是数据在存储器制造时或首次编程时被写入,此后通常只能读取,不能轻易修改。ROM 的主要功能是保存系统启动时所需的固件或程序,保证设备在断电后仍然保留重要数据。

ROM 最常见的用途是存储设备启动时所需的固件程序,例如计算机的 BIOS 或嵌入式设备的启动程序,固件是在设备运行之前执行的一组指令,用来初始化硬件并加载操作系统或其他软件;在嵌入式系统中,ROM 常被用来存储操作系统或控制代码。

最原始的 ROM 是 Mask ROM,数据在芯片制造过程中通过物理掩模直接写入,出厂后无法修改,因此一旦程序有变动,整个芯片都需要重新制造;后面又出现了一种允许用户在设备出厂后通过专用设备进行一次性编程的 ROM—PROM 可编程只读存储器,由于只能编程一次,因此一旦写入错误或者需要更新内容,只能更换芯片,PROM 通常用于开发过程中测试和小批量生产的应用中。

目前,我们在嵌入式开发中常用的可擦除并重新编程的 ROM 分为两种:

  • EEPROM(电​​可擦除可编程只读存储器)​:它允许用户选择性地擦除和修改存储单元中的数据,而无需擦除整个芯片,适合那些需要保存但偶尔更新的配置数据。

1.PNG
EEPROM 存储单元阵列结构图,我们可以使用 Select_x 行选择线和 Word_x 字选择线选择不同的存储单元,每个存储单元对应一个晶体管,存储 1 位数据,存储单元通过在浮栅(Floating Gate)上存储电子来保持数据的状态,通过控制字节操作线输入不同电压可以进行不同操作,如一个字节的写入、擦除和读取

EEPROM 支持按字节擦除或按页擦除(通常每页包含多个字节,具体大小取决于 EEPROM 的设计),用户可以擦除单个字节或一整页的数据,写入操作常是按字节进行,即每次可以写入 1 字节的数据,写入操作通常比读取速度慢,且对 EEPROM 有一定的寿命影响(典型的 EEPROM 可以承受约 10 万到 100 万次擦写循环),并且每次写入操作都需要一定的时间(通常为毫秒级),写操作完成后芯片会进入一个写延迟状态,无法进行新的操作
  • Flash Memory(闪存)​:闪存是一种基于 EEPROM 技术的 ROM 类型,能够快速擦除并重新编程大块数据,具备高密度存储和快速擦除、写入的能力,能够在运行时动态修改数据,它既可以作为存储设备(如 SSD 和 U 盘),也可以作为嵌入式设备中的程序存储器。

    2.PNG
    Flash Memory 的核心存储单元是浮栅晶体管(Floating Gate Transistor),其工作原理与 EEPROM 类似

    Flash 存储器通常以“块”(Block)或“扇区”(Sector)为单位进行擦除,块或扇区的大小通常是几 KB 到几 MB 不等,Flash 存储器必须在写入之前执行擦除操作,Flash 通常以“页”(Page)为单位进行写入操作,页的大小可以是几百字节到几 KB 不等(写入通常也称为“编程”),Flash 存储器有一定的擦写寿命限制(典型寿命为 1 万到 10 万次),擦除一个块需要几毫秒到几十毫秒,而写入操作通常也需要数百微秒到几毫秒,Flash 按照存储架构可以分为以下两种:
    

3.PNG
NAND Flash 中的存储单元以串联的方式连接,多个存储单元共用相同的位线(Bit Line);NOR Flash 中没有单独的位线选择电路,而是每个存储单元直接连接到位线和源线,这使得每个单元的访问更加直接

  • NOR Flash​:采用线性寻址架构,存储单元以字节为单位,类似于传统的 RAM,存储单元的每个字节都有独立的地址,它支持直接、随机读取,读取时可以像读取 RAM 一样逐字节访问数据,由于其线性寻址结构,可以直接执行代码(XIP,Execute In Place),因此常用于固件、程序代码存储等需要高读取性能的场景。NOR Flash 读取速度较快,而写入擦除操作较慢,由于其架构设计,存储密度较低,通常适用于小容量存储(几 MB 到几十 MB),而且其单元面积较大,制造成本较高
  • NAND Flash​:采用矩阵寻址架构,数据按页为单位组织,存储单元以页和块的形式排列,读取和写入操作通常以页为单位,擦除操作以块为单位,不能像 NOR 那样随机读取字节数据,而是顺序访问,数据以较大的块进行操作。NAND Flash 在顺序读取和大块数据操作时读取和写入速度非常快,而在随机读取速度较慢,其存储密度更高,适合大容量存储(几 GB 到几 TB),通常用于固态硬盘(SSD)、USB 驱动器等大容量存储设备

EEPROM 中的分页和 Flash 中的扇区,虽然都涉及到存储介质的分段管理,但它们还是有一些区别:

  • ​写入方式:​EEPROM 的分页支持逐字节写入,通常可以在不擦除的情况下更新单个字节,而 Flash 的扇区只能以扇区为单位进行写入,写入前必须先擦除整个扇区
  • ​存储结构:​EEPROM 通常由多个连续的页组成,每页可以存储固定数量的数据(如 64 字节),Flash 中扇区的大小可能较大(如 4KB、16KB 等),每个扇区通常包含多个页

1.2 RAM 随机存取存储器介绍

随机存取存储器(RAM, Random Access Memory) 是计算机和其他设备中的一种重要存储介质,它允许数据以任意顺序进行读取和写入,其主要功能是为处理器提供快速访问的数据存储,支持计算机程序的运行以及操作系统的任务调度,但它是一种易失性存储器,一旦设备断电,RAM 中的数据就会消失。

4.png
RAM 结构简易示意图,其中,读/写控制信号决定 RAM 进行的是读操作还是写操作,地址解码器根据外部输入的地址信号,控制字线 (Wordline) 和位线 (Bitline)选择具体的存储单元或行,数据输入和输出控制电路负责在写入和读取过程中将数据输入到 RAM 或从 RAM 中输出,存储单元是一个个锁存器,可以保持存储的数据直到被刷新或者写入新数据

根据工作原理不同,RAM 可以分为两种类型:

  • DRAM(动态随机存取存储器)​:DRAM 的每个存储单元由一个电容和一个晶体管组成,电容用于存储电荷,电容充满电表示“1”,电容放电表示“0”,而晶体管作为开关,控制电容的充电和放电;DRAM 的存储单元排列成二维矩阵,电容和晶体管排列在行(wordline)和列(bitline)中,在通过行线和列线选择存储单元后,我们可以通过晶体管向电容中注入电荷(写入“1”)或放电(写入“0”)实现写入数据操作,而在读取数据时同样是通过晶体管读取电容中电荷的状态,需要注意的是读取时,电容的电荷会被消耗,因此读取后需要立即进行刷新操作。
    5.png
    DRAM 结构简易示意图,DRAM 通过电容存储数据,并依靠访问晶体管进行数据的读写操作。它的结构由多个层级组成,包括 Rank、Bank、MAT 等,每个层级都通过局部和全局的位线和字线连接;数据读取时,行解码器激活特定行,感应放大器放大电容中的电荷差异以确定存储的二进制值。
    这里,由于电容会随着时间泄漏电荷,必须定期刷新电容中的电荷,以防止数据丢失,这就是 DRAM 被称为“动态”的原因,我们通常每隔几毫秒就需要刷新一次,每个刷新周期会读取存储单元中的数据并重新写入,以保持数据的完整性。
    
  • SRAM(静态随机存取存储器)​:SRAM 的每个存储单元由六个晶体管组成,包括两个用于保持数据(1 或 0)交叉耦合的反相器,和用于控制数据的读写的两个访问晶体管,多个存储单元排列成二维矩阵,与 DRAM 不同,负责数据存储的交叉耦合反相器之间形成稳定的反馈,无需刷新操作。

6.png
每个反相器由一对晶体管组成,共有 4 个晶体管用于存储数据,当要写入数据时,字线被拉高,两个访问晶体管打开,数据通过位线(Bit Line, BL 和 Bit Line Bar, BLB)写入反相器;在读取操作时,字线被拉高,打开访问晶体管,位线将与存储单元连接,根据反相器输出的状态,位线上的电压变化会反映存储的二进制值,感应放大器会检测位线上的电压变化并解码出存储的值。

由于没有刷新操作,SRAM 的读写速度比 DRAM 快得多,适合对速度要求高的场合;但是由于每个存储单元由 6 个晶体管组成,SRAM 的存储密度比 DRAM 低很多,每位存储数据的成本高于 DRAM。

2.外部内存的分类和特点

常用的外部内存包括外部 RMA、外部 ROM、外部 EEPROM 和存储卡,如下所示:

7.png

不同的外部内存各有特点和应用场景:
8.png

3.地址空间和总线结构

地址空间是 MCU 可以直接访问的所有内存的范围。每个内存位置都有唯一的地址,通常以十六进制表示。例如,树莓派 Pico 板载的 RP2040 MCU 是一个 32 位微控制器,因此它的地址空间是 32 位宽的,能够表示 2 的 32 次幂个地址,也就是 4,294,967,296 字节(约 4GB)的空间,范围从 0x000000000xFFFFFFFF

这里,4GB 的地址空间被划分为多个功能区域,包括 ROM、SRAM、外设、XIP(Execute In Place)等,这些区域中的地址映射到不同的存储和外设,便于开发人员直接操作硬件资源。如下图所示:

9.png

主要包括以下几个部分:

  • Boot ROM (只读存储器)​:在系统上电或复位时,RP2040 会首先从 Boot ROM 中执行启动代码,负责初始化硬件并引导用户代码运行
  • XIP (就地执行寄存器)​:XIP 区域映射外部 QSPI Flash 存储器,用于存储用户代码和数据,XIP 技术允许 RP2040 直接从 Flash 读取和执行代码,而不需要将代码复制到 RAM 中,RP2040 通过 QSPI 总线与外部 Flash 进行通信
  • SRAM (静态随机存取存储器)​:用于存储程序运行时的临时数据、堆栈等
  • APB Peripherals (低速外设)总线​:用于连接一些低速设备,例如 GPIO 控制、定时器、ADC 等,APB 外设通常用于较低带宽的外设,且访问方式与 AHB 外设类似,直接通过访问地址寄存器来控制硬件
  • AHB-Lite Peripherals (高速外设)总线​:包含高速外设的寄存器映射,如 DMA 控制器、USB 控制器和 PIO(可编程输入输出)等,这些外设处理较高吞吐量的数据传输
  • IOPORT (输入/输出端口寄存器)​:该区域包含 SIO(单周期输入/输出)寄存器,允许对 GPIO 引脚和其他简单外设进行快速控制和操作
  • Cortex-M0+ 内部寄存器​:该区域包含 ARM Cortex-M0+ 核心的内部寄存器,包括中断控制器、系统定时器(SysTick)、调试接口等,这些寄存器控制着微控制器的核心功能,如中断处理、系统时间管理等

这里,APB 和 AHB-Lite 总线是用于连接 CPU、内存和外设(如 UART、SPI、I2C 等)的通信通道,用于传递数据、地址和控制信号,通过总线,CPU 可以访问总线上的地址,控制这些外设并读取其状态。

10.png

posted @ 2026-09-03 16:37  FreakStudio  阅读(21)  评论(0)    收藏  举报