ARM Cortex-M内存映射深度解析:直接读写寄存器与硬件寄存器控制MCU的寄存器映射方式编码程序指南

ARM Cortex-M 的系统映射空间

​ 在 STM32 等 ARM Cortex-M 系列 MCU 中,内存地址空间按照 存储功能 进行了严格划分,包括 Flash(程序存储)、RAM(数据存储)、外设寄存器(GPIO、UART、SPI 等)以及系统控制寄存器(中断、调试相关)。下面详细解析各个地址段的作用和特点。

1.1 内存地址映射总览

​ 在 ARM Cortex-M 处理器(如 STM32 系列 MCU)中地址空间通常采用 32 位地址总线,因此可寻址 4GB(0x00000000 ~ 0xFFFFFFFF),但在嵌入式系统中,MCU 的可用内存远小于 4GB,并且地址空间被划分为多个功能区。

地址范围 存储内容 描述
0x000000000x000003FF 向量表(Vector Table) 存放复位向量(起始栈指针)、异常入口地址
0x080000000x0800FFFF Flash(代码存储) 存储 程序代码(.text)只读数据(.rodata)
0x1FFFF0000x1FFFF7FF 系统 Boot ROM 预留给 MCU BootLoader(ISP、IAP 相关)
0x200000000x20004FFF RAM(可变数据存储) SRAM(RAM,存储 .data.bss、堆、栈)
0x400000000x500607FF 外设寄存器 片上 GPIO、UART、SPI、I2C、TIM、ADC 等外设的控制寄存器
0xE00000000xE00FFFFF System 控制寄存器 NVIC(中断控制)、SysTick(系统定时器)、调试接口

1.20x000000000x000003FF:向量表 (Vector Table)

​ MCU 复位后,系统从 0x00000000 地址处读取向量表,该表包含了复位后跳转到 main() 的入口地址。

作用:

  • 存储异常和中断向量表,即异常/中断入口地址
  • 第一项存放的是栈指针初值(SP),用于 CPU 复位时初始化堆栈。
  • 其余项是中断服务程序(ISR)地址,例如:
  • 复位向量(Reset Vector)
  • 硬件故障处理(HardFault、NMI)
  • 外设中断(UART、GPIO、TIM 等)
  • 向量表示例

    0x00000000: 0x20004FFF   ; 初始栈指针地址(RAM 顶部)
    0x00000004: 0x08000239   ; 复位处理函数(Reset_Handler)
    0x00000008: 0x08000321   ; NMI_Handler
    0x0000000C: 0x08000345   ; HardFault_Handler
    

    该表通存储于 Flash(0x08000000)

    1.3 0x080000000x0800FFFF:Flash(程序存储)

    作用

  • 存放 MCU 固件(程序代码),包括:
  • .text(代码段)
  • .rodata(只读数据)
  • 代码段的存储区域,运行时 CPU 直接从 Flash 取指令,不会加载到 RAM。
  • 特点

  • Flash 只能按扇区擦除,不能按字节修改(通常 1 次擦除需要 20ms 左右)。
  • RAM 访问速度远快于 Flash,因此 关键代码可拷贝到 RAM 执行
  • 1.4 0x1FFFF0000x1FFFF7FF:系统 Boot ROM

    作用

  • STM32 MCU 内置 Bootloader(引导程序),支持:
  • ISP(In-System Programming):通过 UART/SWD 进行固件烧录。
  • IAP(In-Application Programming):运行时更新 Flash 代码。
  • 特点

  • Bootloader 可以让 MCU 在 Flash 损坏的情况下仍然可以进行固件更新
  • 通过 BOOT0 / BOOT1 硬件引脚可以选择启动 Flash 还是 Bootloader
  • 1.5 0x200000000x20004FFF:RAM(数据存储)

    作用

  • 存储 MCU 运行时的变量和数据,包括:
  • .data 段:已初始化的全局变量(上电后从 Flash 复制到 RAM)
  • .bss 段:未初始化的全局变量(上电后初始化为 0)
  • 堆(Heap):malloc() 动态分配的内存
  • 栈(Stack**)**:局部变量、函数调用信息
  • 结构

    +------------------+ 0x20005000 (RAM 结束)
    |       Heap      |  动态分配(malloc)
    +------------------+
    |       Stack     |  栈(局部变量、返回地址)
    +------------------+
    |      .bss       |  未初始化数据(RAM)
    +------------------+
    |      .data      |  已初始化全局变量(RAM)
    +------------------+ 0x20000000 (RAM 起始)
    

    注意

  • 栈向下增长,堆向上增长,如果二者相遇会导致崩溃(Stack Overflow)。
  • 优化方法:
  • 尽量使用 const 让数据存入 Flash,减少 RAM 占用。
  • 避免使用 malloc(),防止内存碎片化。
  • 1.6 0x400000000x500607FF:外设寄存器

    作用

  • 用于 MCU 片上外设的控制,如:
  • GPIO(0x40010800):控制 I/O 口输入/输出。
  • UART(0x40013800):串口收发数据。
  • SPI(0x40013000):SPI 传输数据。
  • ADC(0x40012400):模拟信号转换。
  • 代码示例

    #define GPIOC_ODR  (*((volatile uint32_t*) 0x4001100C))
    GPIOC_ODR |= (1 << 13); // 置位 PC13(LED 亮)
    

    特点

  • 访问外设寄存器时 必须使用 volatile 修饰,否则编译器可能优化导致错误。
  • 1.7 0xE00000000xE00FFFFF:System 控制寄存器

    作用

  • 控制 中断、调试、系统时钟,主要包括:
  • NVIC(Nested Vectored Interrupt Controller,中断控制器)
  • SysTick(系统定时器)
  • SCB(System Control Block,系统控制块)
  • 代码示例

    #define NVIC_ISER0 (*((volatile uint32_t*) 0xE000E100))
    NVIC_ISER0 |= (1 << 6); // 使能外部中断 6
    

    特点

  • NVIC 允许中断嵌套,可以配置优先级。
  • SysTick 是 Cortex-M 内置的 24-bit 计时器,用于系统心跳计时
  • 作者:电科周杰伦

    物联沃分享整理
    物联沃-IOTWORD物联网 » ARM Cortex-M内存映射深度解析:直接读写寄存器与硬件寄存器控制MCU的寄存器映射方式编码程序指南

    发表回复