STM32F1 存储器映射:笔记版

 

1. 先记住一句话

STM32 把 Flash、SRAM、外设寄存器都统一编上地址,CPU 访问它们就像访问内存一样。

所以 STM32 里常说:

外设寄存器也是“内存地址”

例如 GPIO、USART、TIM、RCC 这些外设,本质上都有固定地址。

 

一、STM32 的寻址范围

STM32F1 使用 32 位地址总线。

所以最大寻址空间是:

2^32 = 4GB

地址范围:

0x0000 0000 ~ 0xFFFF FFFF

也就是说,STM32 把整个 4GB 空间划分成不同区域。

 

二、STM32F1 常见存储器映射总表

地址范围

区域作用0x0000 0000 开始

启动映射区上电后 CPU 首先访问的区域0x0800 0000 开始

Flash存放程序代码0x2000 0000 开始

SRAM存放运行时变量、栈、堆0x4000 0000 开始

外设寄存器区GPIO、USART、TIM、RCC 等0x6000 0000 开始

外部存储器区外接 SRAM、NOR Flash 等0xE000 0000 开始

Cortex-M3 内核外设区NVIC、SysTick、SCB 等

三、几个最重要的地址

1. Flash 程序存储区

Flash 起始地址:0x0800 0000

作用:

存放我们下载进去的程序

比如你在 Keil 里点 Download,程序一般就烧录到这里。

STM32F103ZET6 常见 Flash 大小:

512KB

所以大概范围是:

0x0800 0000 ~ 0x0807 FFFF

重点记忆:

程序代码存在 Flash,Flash 从 0x08000000 开始。

 

2. SRAM 数据存储区

SRAM 起始地址:0x2000 0000

作用:

存放变量、数组、栈、堆

例如:

int a = 10;

int arr[100];

这些程序运行时的数据,一般就在 SRAM 里。

STM32F103ZET6 常见 SRAM 大小:

64KB

大概范围:

0x2000 0000 ~ 0x2000 FFFF

重点记忆:

变量运行时主要在 SRAM,SRAM 从 0x20000000 开始。

 

3. 外设寄存器区

外设寄存器区起始地址:0x4000 0000

GPIO、定时器、串口、RCC 等都在这里。

例如:

外设

常见基地址TIM2

0x4000 0000TIM3

0x4000 0400USART1

0x4001 3800GPIOA

0x4001 0800GPIOB

0x4001 0C00GPIOC

0x4001 1000RCC

0x4002 1000重点记忆:

外设寄存器从 0x40000000 开始。

 

四、为什么说“外设寄存器也是地址”?

比如 GPIOA 的基地址是:

GPIOA_BASE = 0x40010800

GPIOA 里面有很多寄存器,例如:

寄存器

作用CRL

配置低 8 个引脚CRH

配置高 8 个引脚IDR

输入数据寄存器ODR

输出数据寄存器BSRR

置位/复位寄存器这些寄存器本质上就是一些固定地址。

例如:

GPIOA_BASE = 0x40010800

GPIOA_CRL  = GPIOA_BASE + 0x00

GPIOA_CRH  = GPIOA_BASE + 0x04

GPIOA_IDR  = GPIOA_BASE + 0x08

GPIOA_ODR  = GPIOA_BASE + 0x0C

GPIOA_BSRR = GPIOA_BASE + 0x10

所以:

外设基地址 + 寄存器偏移地址 = 具体寄存器地址

这就是后面要学的 寄存器映射。

 

五、存储器映射和寄存器映射的关系

存储器映射

关注的是整个 STM32 地址空间怎么分配。

例如:

Flash 在哪里?

SRAM 在哪里?

外设在哪里?

寄存器映射

关注的是某一个外设内部,每个寄存器具体在哪里。

例如:

GPIOA 的 CRL 在哪里?

GPIOA 的 ODR 在哪里?

RCC 的 APB2ENR 在哪里?

简单理解:

存储器映射:大地图

寄存器映射:某个外设内部的小地图

 

六、启动地址映射

STM32 上电复位后,CPU 会从:

0x0000 0000

开始取指令。

但是我们程序实际存放在:

0x0800 0000

所以 STM32 会根据 BOOT 引脚,把不同区域映射到 0x00000000。

常见启动方式:

BOOT 配置

启动区域作用从 Flash 启动

0x08000000 映射到 0x00000000正常运行用户程序从系统存储器启动

System Memory串口下载程序等从 SRAM 启动

0x20000000调试或特殊用途平时我们下载程序运行,基本都是:

从 Flash 启动

也就是:

0x00000000 实际对应 0x08000000

 

七、程序入口和中断向量表

STM32 程序最前面有一个东西叫:

中断向量表

它通常放在 Flash 起始位置:

0x0800 0000

上电后 CPU 会先读两个重要内容:

地址

内容0x08000000

栈顶地址 MSP0x08000004

复位入口 Reset_Handler所以启动流程可以简单理解为:

上电

读取 0x08000000,设置栈顶

读取 0x08000004,找到复位函数

进入 Reset_Handler

进入 main 函数

 

八、代码里为什么能直接操作外设?

比如库函数里经常看到:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

它背后本质是操作 RCC 的某个寄存器。

RCC 的基地址:

0x40021000

通过修改 RCC 里的时钟控制寄存器,就能打开 GPIOA 的时钟。

所以我们写:

GPIO_SetBits(GPIOA, GPIO_Pin_0);

本质上也是修改 GPIOA 相关寄存器。

底层逻辑是:

CPU 写某个地址

这个地址对应 GPIOA 的寄存器

GPIOA 引脚电平发生变化

 

九、常见地址速记

这个表很重要,建议记住:

内容

地址Flash 起始地址

0x08000000SRAM 起始地址

0x20000000外设起始地址

0x40000000GPIOA 基地址

0x40010800GPIOB 基地址

0x40010C00RCC 基地址

0x40021000USART1 基地址

0x40013800TIM2 基地址

0x40000000TIM3 基地址

0x40000400Cortex-M3 内核外设

0xE0000000

十、学习时重点掌握什么?

这一节不用死背所有地址,重点掌握这几个:

1. STM32 是 32 位寻址,地址范围 4GB

2. Flash 从 0x08000000 开始

3. SRAM 从 0x20000000 开始

4. 外设寄存器从 0x40000000 开始

5. GPIO、USART、TIM、RCC 都是通过地址访问的

6. 外设基地址 + 寄存器偏移 = 具体寄存器地址

7. 启动时 0x00000000 会映射到不同启动区域

 

十一、最简单理解

可以把 STM32 想成一栋大楼:

0x08000000:程序办公室,放代码

0x20000000:临时仓库,放变量

0x40000000:设备控制室,控制 GPIO、串口、定时器

0xE0000000:内核管理室,控制 NVIC、SysTick

CPU 想干什么,就去对应地址读写数据。

例如:

想点亮 LED

找到 GPIO 地址

修改 GPIO 输出寄存器

引脚输出高/低电平

LED 亮/灭

 

十二、一句话总结

存储器映射就是:STM32 把 Flash、SRAM、外设寄存器、内核外设等资源统一放到 4GB 地址空间中,CPU 通过访问不同地址来读取数据、运行程序和控制外设。

 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐