文章目录
1 什么是寄存器
在STM32微控制器中,寄存器(Register)是用于存储和操作数据的硬件组件。寄存器是CPU和其他外设之间进行数据交换的关键部分。每个寄存器通常是一个固定大小的存储单元(如8位、16位或32位),用于存储特定类型的数据或控制信息。
2 存储器的映射
在STM32 系统架构中,被控单元FLASH,RAM,FSMC 和 AHB 到 APB 的桥(即片上外设),这些部件共同排列在一个4GB的地址空间内。
存储器本身不具有地址信息,它的地址是由芯片厂商或用户分配,给存储器分配地址的过程就称为存储器映射,如果给存储器再分配一个地址就叫存储器重映射。存储器映射图如下:
2.1 为什么是4GB的地址空间
- 32位架构:STM32是32位处理器,使用32位的地址总线
- 地址总线的位数:32位的地址总线可以产生 2^32 个不同的地址。
- 地址范围:这表示地址范围为从
0x0000 0000
到0xFFFF FFFF
,每个地址对应一个字节的内存。因此, 2^32 字节等于4GB。
2.2 地址空间的使用
理论上可寻址4GB,但并非所有地址都用于访问物理内存。一部分地址空间可能被保留给系统和硬件用途,例如I/O端口和内核空间。实际可用内存可用于用户程序的内存空间通常会少于4GB。在这 4GB 的地址空间中,ARM 已经粗线条的平均分成了8个块,每块512MB,每个块也都规定了用途,具体分类见表格存储器功能分类。每个块的大小都有512MB,显然这是非常大的,芯片厂商在每个块的范围内设计各具特色的外设时并不一定都用得完,都是只用了其中的一部分而已。

2.3 存储器区域功能划分
在这 4GB 的地址空间中,ARM 已经粗线条的平均分成了8个块,每块512MB,每个块也都规定了用途,具体分类见表格存储器功能分类。每个块的大小都有512MB。
序号 | 用途 | 地址范围 |
Block 0 | SRAM | 0x00000000~0x1FFFFFFF (512MB) |
Block 1 | SRAM | 0x20000000~0x3FFFFFFF (512MB) |
Block 2 | 片上外设 | 0x40000000~0x5FFFFFFF (512MB) |
Block 3 | FMC的bank1~bank2 | 0x60000000~0x7FFFFFFF (512MB) |
Block 4 | FMC的bank3~bank4 | 0x80000000~0x9FFFFFFF (512MB) |
Block 5 | FMC | 0xA0000000~0xCFFFFFFF (512MB) |
Block 6 | FMC | 0xD0000000~0xDFFFFFFF (512MB) |
Block 7 | Cortex-M4内部外设 | 0xE0000000~0xFFFFFFFF (512MB) |
在这8个 Block 里面,有3个块非常重要,Block0 用来设计成内部FLASH;Block1 用来设计成内部 RAM;Block2 用来设计成片上的外设。
2.3.1 存储器 Block0 内部区域功能划分
Block0 主要用于设计片内的 FLASH,F429 系列片内部 FLASH 最大是 2MB,我们使用的STM32F429IGT6的 FLASH 就是 1MB。要在芯片内部集成更大的 FLASH 或者 SRAM 都意味着芯片成本的增加,往往片内集成的 FLASH 都不会太大,ST 能在追求性价比的同时做到 1MB 以上,实乃良心之举。

2.3.2 存储器 Block1 内部区域功能划分
Block1 用于设计片内的 SRAM。F429 内部 SRAM 的大小为 256KB,其中 64KB 的 CCM RAM 位于 clock0,剩下的 192KB 位于 Block1,分 SRAM1 112KB,SRAM2 16KB,SRAM3 64KB。
块 | 用途说明 | 地址范围 |
Block 1 | 预留 | 0x20030000~0x3FFFFFFF |
SRAM3 64KB | 0x20020000~0x2002FFFF | |
SRAM2 16KB | 0x2001C000~0x2001FFFF | |
SRAM1 112KB | 0x20000000~0x2001FFFF |
2.3.3 存储器 Block2 内部区域功能划分
Block2 用于设计片内的外设,根据外设的总线速度不同,Block 被分成了 APB 和 AHB 两部分,其中 APB 又被分为 APB1 和 APB2,AHB 分为 AHB1 和 AHB2。还有一个 AHB3 包含了 Block3/4/5/6,这四个 Block 用于扩展外部存储器,如 SDRAM,NORFLASH 和 NANDFLASH 等。
块 | 用途说明 | 地址范围 |
Block 2 | APB1总线外设 | 0x40000000~0x40007FFF |
预留 | 0x40008000~0x4000FFFF | |
APB2总线外设 | 0x40010000~0x40016BFF | |
预留 | 0x40016C00~0x4001FFFF | |
AHB1总线外设 | 0x40020000~0x4007FFFF | |
预留 | 0x40080000~0x4FFFFFFF | |
AHB2总线外设 | 0x50000000~0x50060BFF | |
预留 | 0x5006C000~0x5FFFFFFF |
2.4 寄存器映射
在存储器的Block2区域,有一些片上外设,每个外设的功能对应一个特定的内存单元。每个单元占用4个字节(32位),这些单元可以用来控制外设的工作。
为了访问这些内存单元,我们需要知道它们的起始地址,然后可以通过C语言中的指针来操作这些地址。然而,如果我们每次都需要记住这些复杂的地址,既麻烦又容易出错。
为了解决这个问题,我们可以给每个功能单元起一个容易记住的名字,这个名字就是我们所说的“寄存器”。这个过程把已经分配好地址的特定功能内存单元命名为寄存器,就叫做“寄存器映射”。
举个例子:在一个大型社区中,整个社区就像是一个微控制器,里面有许多栋不同的楼(外设),每栋楼提供不同的功能,例如住宅楼、商店和办公室。每一栋楼里的住户(寄存器)都有自己的门牌号(地址),比如301、302等,这些门牌号就是寄存器的名字。社区的管理办公室相当于CPU,每当需要某个服务时,管理办公室(CPU)就会根据住户的门牌号去找特定的住户,指挥他们去完成任务。每户人家所占用的空间(4个字节)就像是这户人家的房间、厨房和其他生活空间的总和,提供特定的功能。通过这种设计,微控制器能够高效、灵活地控制和管理各种外设。
2.5 STM32 的外设地址映射
片上外设区分为四条总线,根据外设速度的不同,不同总线挂载着不同的外设,APB 挂载低速外设,AHB 挂载高速外设。相应总线的最低地址为总线的基地址,总线基地址也是挂载在该总线上的首个外设的地址。其中 APB1 总线的地址最低,片上外设从这里开始,也叫外设基地址。
2.5.1 总线基地址
表格总线基地址 中的“相对外设基地址偏移”即该总线地址与“片上外设”基地址 0x4000 0000的差值。
总线名称 | 总线基地址 | 相对外设基地址的偏移 |
APB1 | 0x40000000 | 0x0 |
APB2 | 0x40010000 | 0x00010000 |
AHB1 | 0x40020000 | 0x00020000 |
AHB2 | 0x50000000 | 0x10000000 |
AHB3 | 0x60000000 | 已不属于片上外设 |
2.5.2 外设基地址
总线上挂载着各种外设,这些外设也有自己的地址范围,特定外设的首个地址称为“XX 外设基地址”,也叫 XX 外设的边界地址。
这里面我们以 GPIO 这个外设来讲解外设的基地址:
外设名称 | 外设基地址 | 相对AHB1总线的地址偏移 |
GPIOA | 0x40020000 | 0x0 |
GPIOB | 0x40020400 | 0x00000400 |
GPIOC | 0x40020800 | 0x00000800 |
GPIOD | 0x40020C00 | 0x00000C00 |
GPIOE | 0x40021000 | 0x00001000 |
GPIOF | 0x40021400 | 0x00001400 |
GPIOG | 0x40021800 | 0x00001800 |
GPIOH | 0x40021C00 | 0x00001C00 |
2.5.3 外设寄存器
在 XX 外设的地址范围内,分布着的就是该外设的寄存器。
以 GPIO 外设为例,GPIO 是通用输入输出端口。GPIO 有很多个寄存器,每一个都有特定的功能。每个寄存器为 32bit,占四个字节,在该外设的基地址上按照顺序排列,寄存器的位置都以相对该外设基地址的偏移地址来描述。这里我们以GPIOH 端口为例:
寄存器名称 | 寄存器地址 | 相对GPIOH基址的偏移 |
GPIOH MODER | 0x40021C00 | 0x00 |
GPIOH OTYPER | 0x40021C04 | 0x04 |
GPIOH OSPEEDR | 0x40021C08 | 0x08 |
GPIOH PUPDR | 0x40021C0C | 0x0C |
GPIOH IDR | 0x40021C10 | 0x10 |
GPIOH ODR | 0x40021C14 | 0x14 |
GPIOH BSRR | 0x40021C18 | 0x18 |
GPIOH LCKR | 0x40021C1C | 0x1C |
GPIOH AFRL | 0x40021C20 | 0x20 |
GPIOH AFRH | 0x40021C24 | 0x24 |