> 文章列表 > 【STM32】基础知识 第七课 存储器映射 寄存器映射

【STM32】基础知识 第七课 存储器映射 寄存器映射

【STM32】基础知识 第七课 存储器映射  寄存器映射

【STM32】基础知识 第七课 存储器映射 & 寄存器映射

  • STM32 寻址范围
  • 存储器映射
  • 存储器功能划分 (F1 为例)
    • Block 0
    • Block 1
    • Block 2
    • 寄存器映射
  • 寄存器映射 (F1 为例)
  • 寄存器映射举例
  • 寄存器地址计算
    • GPIO 外设基地址及偏移量
    • 寄存器地址及偏移量
    • 寄存器地址计算过程
  • 使用结构体映射寄存器
  • STM32F103xe.h 主要组成部分

STM32 寻址范围

32 位的单片机可以友 32 根地址线 (每根地址线有两种转态: 导通或不导通). 单片机内存地址访问的存储单元是按字节编址的 (而不是 bit)

地址线根数 地址编号 (二进制) 地址编号数 (即内存大小)
1 0, 1 2
2 00, 01 4
3 000, 001, 010, 011, 100, 101, 110, 111 8
n 2 n 2^n 2n

STM32 寻址大小: 2 32 = 4 G 2^{32} = 4G 232=4G (字节)
STM 寻址范围: 0x0000 0000~0xFFFF FFFF

STM32 存储器映射

存储器映射

存储器指可以存储数据的设备, 本身没有地址信息, 对存储器分配地址的过程称为存储器映射.

存储器功能划分 (F1 为例)

ST 将 4GB (2^32) 地址空间分成 8 个块.

存储块 功能 地址范围
Block 0 Code (Flash) 0x0000 0000 ~ 0x1FFF FFFF (512 MB)
Block 1 SRAM 0x2000 0000 ~ 0x3FFF FFFF (512 MB)
Block 2 片上外设 0x4000 0000 ~ 0x5FFF FFFF (512 MB)
Block 3 FSMC Bank1&2 0x6000 0000 ~ 0x7FFF FFFF (512 MB)
Block 4 FSMC Bank3&4 0x8000 0000 ~ 0x9FFF FFFF
Block 5 FSMC 寄存器 0xA000 0000 ~ 0xBFFF FFFF
Block 6 0xC000 0000 ~ 0xDFFF FFFF (512 MB)
Block 7 Cortex M3 内部外设 0xE000 0000 ~ 0xFFF FFFF (512 MB)

Block 0

Block0 (FLASH) 功能划分:

存储块 功能 地址范围
Block 0 FLASH 或系统存储器别名区 0x0000 0000 ~ 0x0007 FFFF (512 KB)
Block 0 保留 0x0008 0000 ~ 0x07FF FFFF
Block 0 用户 FLASH, 用于存储用户代码 0x0800 0000 ~ 0x0807 FFFF (512 KB)
Block 0 保留 0x0808 0000 ~ 0x1FFF EFFF
Block 0 系统存储器, 存储出厂 Bootloader 0x1FFF F000 ~ 0x1FFF F7FF (2 KB)
Block 0 选项字节, 配置读保护等 0X1FFF F800 ~ 0x1FFF F80F (16 B)
Block 0 保留 0x1FFF F810 ~ 0x1FFF FFFF

Block 1

Block1 (SRAM) 功能划分:

存储块 功能 地址范围
Block 1 SRAM 0x2000 0000 ~ 0x2000 FFFF (64 KB)
保留 0x2001 0000 ~ 0x3FFF FFFF

Block 2

存储块 功能 地址范围
Block 2 APB1 总线外设 0x4000 0000 ~ 0x4000 77FF
Block 2 保留 0x4000 7800 ~ 0x4000 FFFF
Block 2 APB2 总线外设 0x4001 0000 ~ 0x4000 3FFF
Block 2 保留 0x4001 4000 ~ 0x4001 7FFFF
Block 2 AHB 总线外设 0x4001 8000 ~ 0x4002 33FF
Block 2 保留 0x4002 3400 ~ 0x5FFF FFFF

STM32 寄存器映射

寄存器映射

寄存器 (Register) 是单片机内部一种特殊的内存, 可以实现对单片机各个功能的控制.

简单来说: 寄存器就是单片机内部的控制机构.

STM32 寄存器分类:

大类 小类 说明
内核寄存器 内核相关寄存器 包含 R0~R15, xPSR, 特殊功能寄存器等
内核寄存器 中断控制寄存器 包含 NVIC 和 SCB 相关寄存器, NVIC 有: ISER, ICER, ISPR, IP 等. SCB 有: VTOR, AIRCR, SCR 等
内核寄存器 SysTick 寄存器 包含 CTRL, LOAD, VAL 和 CALIB 四个寄存器
内核寄存器 内存保护寄存器 可选功能, STM32F103 没有
内核寄存器 调试系统寄存器 ETM, ITM, DWT, IPIU 等相关寄存器
外设寄存器 包含 GPIO, UART, IIC, SPI, TIM, DMA, ADC, DAC, RTC, I/WWDG, PWR, CAN, USB 等各种外设寄存器

寄存器映射 (F1 为例)

寄存器是特殊的存储器, 给寄存器地址命名的过程, 就叫寄存器映射.

寄存器地址 映射 寄存器名字
0x4001080C 给寄存器地址命名 GPIOA_ODR

寄存器映射举例

直接操作寄存器地址:

*(volatile unsigned int*)(0x4001 080C) = 0xFFFF;

定义一个名字后再操作:

#define GPIOA_ODR *(volatile unsigned int*)(0x4001080C)GPIOA_ODR = 0XFFFF;
  • 使用volatile 关键词对寄存器地址进行修饰, 告诉编译器, 该地址运行过程中随时可能变化, 编译时不要优化该地址
  • GPFDAT 宏定义代表了某寄存器中的值

寄存器地址计算

为了方便编写代码及使用, 我们将寄存器地址分为三个部分:

  1. 总线基地址 (BUS_BASE_ADDR)
  2. 外设基于总线基地址的偏移量 (PERIPH_OFFSET)
  3. 寄存器相对外设基地址的偏移量 ( REG_OFFSET)

寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET

总线基地址:

总线 基地址 偏移量
APB 1 0x4000 0000 0
APB 2 0x4001 0000 0x1 0000
AHB 0x4001 8000 0x1 8000

APB1 总线的基地址, 也叫外设基地址 (PERIPH_BASE).

此表的偏移量: 是相对外设基地址 (PERIPH_BASE) 来说的.

GPIO 外设基地址及偏移量

所属总线 外设 基地址 偏移量
APB 2 0x4001 0000 GPIOA 0x4001 0800 0x800
APB 2 0x4001 0000 GPIOB 0x4001 0C00 0xC00
APB 2 0x4001 0000 GPIOC ox4001 1000
0x1000
APB 2 0x4001 0000 GPIOD ox4001 1400
0x1000
APB 2 0x4001 0000 GPIOE ox4001 1800
0x1000
APB 2 0x4001 0000 GPIOF ox4001 1C00
0x1000
APB 2 0x4001 0000 GPIOG ox4001 2000
0x2000

此表的偏移量: 是相对 APB2 外设基地址 (APB2PERIPH_BASE) 来说的.

寄存器地址及偏移量

所属外设 寄存器 地址 偏移量
GPIOA 0x4001 0800 GPIOA_CRL 0x4001 0800 0x00
GPIOA 0x4001 0800 GPIOA_CRH 0x4001 0804 0x04
GPIOA 0x4001 0800 GPIOA_IDR 0x4001 0808 0x08
GPIOA 0x4001 0800 GPIOA_ODR 0x4001 080C 0x0C
GPIOA 0x4001 0800 GPIOA_BSRR 0x4001 0810 0x10
GPIOA 0x4001 0800 GPIOA_BRR 0x4001 0814 0x14
GPIOA 0x4001 0800 GPIOA_LCKR 0x4001 0818 0x18

寄存器地址计算过程

  1. 获取总线基地址, APB2 总线基地址: 0x4001 0000
  2. 获取外设地址偏移量, GPIOA 相对 APB2 总线偏移量是: 0x800
  3. 获取寄存器地址偏移量, ODR 相对 GPIOA 外设地址的偏移量是 0x0C

寄存器地址 = BUS_BASE_ADDR+ PERIPH_OFFSET+ REG_OFFSET

GPIOA_ODR = 0x4001 0000+0x800+0x0C=0x4001 080C

使用结构体映射寄存器

定义结构体:

typedef struct{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSSR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
}GPIO_TypeDEF;  // 声明变量

例子:

GPIOA_BASE: 0x4001 0800
# define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
&GPIOA->CRL: 0x4001 0800
&GPIOA->CRH: 0x4001 0804
&GPIOA->IDR: 0x4001 0808
&GPIOA->ODR: 0x4001 080C// 实际应用
GPIOA->ODR = 0xFFFF;

STM32F103xe.h 主要组成部分

文件 主要组成部分 说明
stm32f103xe.h 中断编号定义 定义 IRQn_Type 枚举类型, 包含 STM32F103 内部所有中断编号 (中断号), 方便后续编写代码
stm32f103xe.h 外设寄存器结构体类型定义 以外设为单位, 使用结构体类型定义每个外设所有寄存器, 方便寄存器映射
stm32f103xe.h 寄存器映射 1. 定义总线地址和外设基地址
2. 使用外设结构体类型定义将外设基地址强制转换成结构体指针, 完成寄存器映射
stm32f103xe.h 寄存器位定义 定义外设寄存器每个功能位的位置及掩码
stm32f103xe.h 外设判定 判断某个外设是否合法 (即是否存在改外设)

出处: 笔记摘自正点原子