一、STM32系统框架
- 1.1、Cortex M内核 & 芯片
- 1.2、F1系统架构
- 1.3、F4系统架构
- 1.4、F7系统架构
- 1.5、H7系统架构
二、STM32的寻址范围?
三、存储器映射
- 存储器功能划分(F1为例)
- STM32F1存储器映射图
四、寄存器映射
- 寄存器基础知识
- STM32寄存器分类
- 寄存器映射(F1为例)
- 寄存器描述解读
- 寄存器映射举例
- 寄存器地址计算
- GPIOA_ODR寄存器地址计算过程:
- 使用结构体,可以很方便的完成对寄存器的映射:
- stm32f103xe.h主要组成部分
五、总结
一、STM32系统框架
1.1、Cortex M内核 & 芯片
1.2、F1系统架构
ARM Cortex-M3 内核的总线结构以及相关概念。以下是对其中一些术语的简要解释:
总线矩阵(Bus Matrix):
总线矩阵是用于连接主动单元(主要是处理器内核)和被动单元(外设)的关键组件。它负责协调和管理数据和指令的传输,确保有效地连接不同的单元。在 ARM Cortex-M3 内核中,总线矩阵是连接 DCode 总线和 System 总线的关键组成部分。
主动单元:
- Cortex-M3 内核:
Cortex-M3 内核是主动单元的核心。它通过 DCode 总线直接连接到 Flash 存储器,以便高效地获取指令。同时,连接到 System 总线以与外设进行通信。
被动单元:
-
AHB 到 APB 桥:
AHB 到 APB 桥是被动单元的一部分,它连接着所有的 APB 外设。这个桥是主动单元和被动单元之间的桥梁,允许数据在高性能总线(AHB)和外围总线(APB)之间传输。 -
外设:
外设是连接到被动单元的各种设备,如传感器、通信模块等。它们通过 APB 连接到主动单元,与 Cortex-M3 内核进行通信。
时钟频率:
各个单元的工作时钟频率是至关重要的。在 ARM Cortex-M3 内核中:
- AHB 时钟频率: 最大为 72MHz。
- APB1 时钟频率: 最大为 36MHz。
- APB2 时钟频率: 最大为 72MHz。
这些频率指定了各个总线的最大工作速度,影响着整个系统的性能。
这样,通过总线矩阵的管理,主动单元和被动单元之间实现了高效的数据和指令传输,形成了 ARM Cortex-M3 内核的总线架构。
-
Cortex-M3 内核:
ARM Cortex-M3 是 ARM 公司推出的低功耗、高性能的 32 位 RISC 处理器内核。它通常用于嵌入式系统,具有较小的体积和功耗。 -
DCode 总线(D-Bus):
DCode 总线是用于连接 Cortex-M3 内核和 Flash 存储器的总线,用于传输数据。 -
System 总线(S-Bus):
System 总线用于连接 Cortex-M3 内核与外设和其他系统组件之间的通信。它负责处理系统中的数据和指令传输。 -
ICode 总线:
ICode 总线直接连接 Flash 存储器接口,用于指令传输。它不需要经过总线矩阵,以提高指令读取的效率。 -
DMA(直接内存访问):
DMA 是一种数据传输机制,允许外设和内存之间的直接数据传输,而无需 CPU 的干预。这有助于提高系统性能。 -
AHB(高级高性能总线):
AHB 是 Cortex-M3 内核连接到系统中高性能设备的总线。它是一种高级别总线,用于连接高性能的模块。 -
APB(高级外围总线):
APB 是 Cortex-M3 内核连接到外设的总线。它是一种低功耗、低速率的总线,适用于连接外围设备。 -
总线时钟频率:
描述了各个总线的最大时钟频率。AHB 的最大时钟频率为 72MHz,APB1 的最大时钟频率为 36MHz,APB2 的最大时钟频率为 72MHz。这些频率是系统中各个总线的最大工作频率。
总体而言,这些概念构成了 ARM Cortex-M3 内核及其周边组件的总线架构,提供了灵活而高效的数据和指令传输机制。
参考:STM32F10xxx参考手册_V10(中文版).pdf 2.1小节
路径:战舰 V4\资料\8,STM32参考资料\2,芯片资料\STM32F10xxx参考手册_V10(中文版).pdf
战舰 V4\资料\7,硬件资料\STM32F103ZET6(中文版).pdf
STM32F103xC、STM32F103xD和STM32F103xE增强型模块框图
- 工作温度:-40°C至+85°C(尾缀为6,见表71),或-40°C至+105°C(尾缀为7,见表71),结温分别达105°C或125°C。
- AF:可作为外设功能脚的I/O端口
1.3、F4系统架构
F4 系统架构:
F4 系列的系统架构包括主控总线和被控总线,这些总线连接了各种核心和外设,为处理器提供了高效的数据和指令传输通道。
主控总线:
-
Cortex M4 内核 I 总线:
连接 Cortex-M4 内核的指令总线,负责指令的读取。 -
Cortex M4 内核 D 总线:
连接 Cortex-M4 内核的数据总线,负责数据的读写。 -
Cortex M4 内核 S 总线:
连接 Cortex-M4 内核的系统总线,用于核心和外设之间的通信。 -
DMA1 存储器总线:
连接 DMA1 控制器和存储器,用于实现 DMA 操作。 -
DMA2 存储器总线:
连接 DMA2 控制器和存储器,支持存储器访问的 DMA 操作。 -
DMA2 外设总线:
连接 DMA2 控制器和外设,用于外设之间的数据传输。 -
以太网 DMA 总线:
专门用于连接以太网控制器的 DMA 总线。 -
USB OTG HS DMA 总线:
专用于连接 USB OTG 控制器的 DMA 总线。
被控总线:
-
内部 FLASH Icode 总线:
用于连接内部 Flash 存储器的指令总线。 -
内部 FLASH Dcode 总线:
用于连接内部 Flash 存储器的数据总线。 -
主要内部 SRAM1(112KB):
连接主要的内部 SRAM 区域,用于存储数据。 -
辅助内部 SRAM2(16KB):
连接辅助的内部 SRAM 区域,提供额外的存储空间。 -
辅助内部 SRAM3(64KB):
适用于某些型号(如 F42xxx 和 F43xxx),提供额外的内部 SRAM。 -
AHB1 外设(包括 AHB-APB 总线桥和 APB 外设):
连接 AHB1 外设总线,包括连接到 AHB-APB 总线桥的外设和直接连接到 AHB1 的外设。 -
AHB2 外设:
连接 AHB2 外设总线,用于连接直接连接到 AHB2 的外设。
CCM RAM:
CCM RAM 是 Core-Coupled Memory RAM,专用于存储数据,具有快速的访问速度,但不支持 DMA 操作。
总线时钟频率:F407/F429
- AHB1/2 时钟频率: 最大为 168/180MHz。
- APB1 时钟频率: 最大为 42/45MHz。
- APB2 时钟频率: 最大为 84/90MHz。
这些频率限制了各个总线和外设的工作速度,影响着系统的性能。总体而言,F4 系列的系统架构提供了高度灵活性和性能,适用于不同应用场景的需求。
摘自:STM32F4xx参考手册_V4(中文版).pdf 2.1小节
路径:F429、F767\资料 A盘\8,STM32参考资料\STM32F4xx中文参考手册.pdf
1.4、F7系统架构
摘自:STM32F7xx参考手册_V2(中文版).pdf 2.1小节
F7 系统架构:
F7 系列的系统架构包括主系统架构和多重 AHB 总线矩阵,为 Cortex-M7 处理器提供高效的数据和指令传输通道。
主系统架构:
-
AXI 转 AHB 总线桥:
- 连接到内嵌 Flash 的 AXI 转 64 位 AHB 总线桥。
- 连接到 AHB 总线矩阵的 3 个 AXI 转 32 位 AHB 总线桥。
-
AHB 总线矩阵:
- 包含 12 个总线主控制器和 8 个总线从控制器。
- 连接各种核心、外设以及多重 AHB 总线矩阵。
-
多重 AHB 总线矩阵:
- 12 个总线主控制器和 8 个总线从控制器。
- 包括 3 个 32 位 AHB 总线、连接到内嵌 Flash 的 64 位 AHB 总线、AHBP 总线、以及各种 DMA 控制器和外设。
总线主控制器:
-
3x32 位 AHB 总线:
- 连接到不同外设和 DMA 控制器的独立 32 位 AHB 总线。
-
连接到内嵌 Flash 的 64 位 AHB 总线:
- 用于高效连接到内部 Flash 存储器。
-
AHBP 总线:
- 与 AHBP 接口相关的总线,可能用于特定的 DMA 操作。
-
DMA1 存储器总线:
- 连接 DMA1 控制器和存储器,支持存储器访问的 DMA 操作。
-
DMA2 存储器总线:
- 连接 DMA2 控制器和存储器,用于 DMA 操作。
-
DMA2 外设总线:
- 连接 DMA2 控制器和外设,用于外设之间的数据传输。
-
以太网 DMA 总线:
- 专用于连接以太网控制器的 DMA 总线。
-
USB OTG HS DMA 总线:
- 专用于连接 USB OTG 控制器的 DMA 总线。
-
LCD 控制器 DMA 总线:
- 连接到 LCD 控制器的 DMA 总线。
-
DMA2D 存储器总线:
- 连接 DMA2D 控制器和存储器,支持高级 2D 图形加速。
总线从控制器:
-
AHB 总线上的内嵌 Flash:
- 用于连接到 Cortex-M7 处理器的内嵌 Flash 存储器。
-
Cortex M7 AHBS 从接口:
- 仅用于 DTCM RAM 的 DMA 数据传输。
-
主 SRAM1(240KB):
- 连接到主要的内部 SRAM 区域,用于存储数据。
-
辅助 SRAM2(16KB):
- 连接到辅助的内部 SRAM 区域,提供额外的存储空间。
-
AHB1 外设(包括 AHB-APB 总线桥和 APB 外设):
- 连接到 AHB1 外设总线,包括连接到 AHB-APB 总线桥的外设和直接连接到 AHB1 的外设。
-
AHB2 外设:
- 连接到 AHB2 外设总线,用于连接直接连接到 AHB2 的外设。
-
FMC(外部存储器接口):
- 连接到外部存储器接口,支持连接外部存储设备。
-
Quad SPI(四通道串行外围设备接口):
- 连接到 Quad SPI 外设总线,支持四通道 SPI 通信。
DTCM RAM 和 ITCM RAM:
-
DTCM RAM:
- 可以存放数据,也可以存放指令。
- 用于存储数据,支持 DMA 操作。
-
ITCM RAM:
- 用于存储指令,支持 CPU 时钟速度访问,无等待周期。
总线时钟频率:
- AHB1/2 时钟频率: 最大为 216MHz。
- APB1 时钟频率: 最大为 54MHz。
- APB2 时钟频率: 最大为 108MHz。
F7 系列的系统架构提供了强大的数据通路和丰富的外设支持,适用于高性能应用。
1.5、H7系统架构
摘自:STM32H7xx参考手册_V3(中文版).pdf 2.1小节
H7 系统架构:
H7 系列的系统架构包括主系统架构、AXI 总线矩阵、两个 AHB 总线矩阵(D2 域和 D3 域)、总线桥以及域间总线。
主系统架构:
-
AXI 总线矩阵:
- 提供高性能的 AXI 总线连接,用于连接主要外设和总线主控制器。
-
AHB 总线矩阵(D2 域和 D3 域):
- 包括两个独立的 AHB 总线矩阵,分别是 D2 域和 D3 域,用于连接不同的外设和 DMA 控制器。
-
总线桥:
- 提供连接 AXI 总线和 AHB 总线之间的桥梁,用于实现不同总线之间的数据传输。
-
域间总线:
- 提供不同域之间的通信桥梁,用于在不同域之间传输数据。
总线主设备:
-
AHB 总线主设备:
- 用于连接到 AHB 总线的主设备,包括连接到 D2 和 D3 域的外设和 DMA 控制器。
-
AXI 总线主设备:
- 用于连接到 AXI 总线的主设备,包括连接到主 AXI 总线矩阵的外设和 DMA 控制器。
总线从设备:
-
AHB 总线从设备:
- 连接到 AHB 总线的从设备,包括连接到 D2 和 D3 域的外设和 DMA 控制器。
-
AXI 总线从设备:
- 连接到 AXI 总线的从设备,包括连接到主 AXI 总线矩阵的外设和 DMA 控制器。
ITCM 和 DTCM:
-
ITCM(指令 Tightly-Coupled Memory):
- 用于存放程序指令,支持 CPU 以时钟速度访问。
-
DTCM(数据 Tightly-Coupled Memory):
- 用于存放数据,支持 DMA 操作。
总线时钟频率:
- AHB1/2/3/4 时钟频率: 最大为 240MHz。
- APB1/2/3/4 时钟频率: 最大为 120MHz。
H7 系列的系统架构提供了高性能的总线结构,支持多领域的并行数据传输,适用于处理复杂且高性能要求的应用。
总线主设备与总线从设备互连
在嵌入式系统中,总线主设备与总线从设备的互连是通过总线协议来实现的。主要的总线协议包括 AHB(Advanced High-performance Bus)、APB(Advanced Peripheral Bus)、AXI(Advanced eXtensible Interface)等。以下是它们的简要说明:
-
AHB(Advanced High-performance Bus):
- 总线特性: 提供高性能的总线传输,支持并行传输。
- 主设备: AHB 总线上的总线主控制器和主设备。
- 从设备: 连接到 AHB 总线的外设和 DMA 控制器。
-
APB(Advanced Peripheral Bus):
- 总线特性: 用于连接外设,相对于 AHB 总线速度较低。
- 主设备: AHB-APB 桥接控制器和 AHB 主设备。
- 从设备: 连接到 APB 总线的外设。
-
AXI(Advanced eXtensible Interface):
- 总线特性: 高度灵活且支持多通道、高性能的总线协议。
- 主设备: AXI 总线上的总线主控制器和主设备。
- 从设备: 连接到 AXI 总线的外设和 DMA 控制器。
总线主设备和总线从设备通过相应的总线协议进行通信。连接过程中,总线主控制器负责发起总线事务,选择通信的从设备,并将数据传输到或从从设备读取。通信的具体协议规定了数据传输的格式、时序和控制信号。
在总线互连中,总线主设备通过总线协议的特定信号(例如,地址线、数据线、控制线等)与总线从设备进行数据传输。这种互连方式是基于硬件设计的总线架构,确保系统中的各个部件可以有效地协同工作。
二、STM32的寻址范围?
STM32的寻址范围是从0x00000000到0xFFFFFFFF,即32位寻址范围,对应4GB的内存空间。这个范围包括了Flash存储器、SRAM(静态随机存储器)、外设寄存器等。在这个范围内,不同的地址区域用于存放程序代码、数据、系统寄存器等。
以下是一些常见的STM32地址范围:
- Flash 存储器: 存放程序代码,通常从0x08000000开始。
- SRAM(静态随机存储器): 存放变量和堆栈等数据,其起始地址通常为0x20000000。
- 外设寄存器: 包括与外设通信的寄存器,地址范围根据不同的外设而变化。
- System Control Block(系统控制块): 包含一些系统级别的控制寄存器,位于地址0xE000E000区域。
这个寻址范围是非常大的,但实际上,不同的STM32型号可能只使用其中的一部分,具体的使用范围和映射关系需要查看芯片的数据手册。
在通常的32位单片机中,地址线的数量通常是32根,而每根地址线上有两种状态(高电平或低电平),因此总共有2^32个不同的地址。
-
32位的单片机有32根地址线: 即使每根地址线有两种状态(0或1,低电平或高电平),总地址数量为2^32。
-
单片机内存地址访问的存储单元按字节编址: 这是正确的,每个地址代表一个字节。即,每个地址可以存储8位二进制数据(一个字节)。
-
地址线根数和地址编号:
- 当有1根地址线时,有2个地址编号(0和1)。
- 当有2根地址线时,有4个地址编号(00、01、10、11)。
- 当有3根地址线时,有8个地址编号(000、001、010、011、100、101、110、111)。
- 对于n根地址线,有2^n个地址编号。
这种二进制的地址编码方式允许单片机访问非常大的内存范围,但实际上,芯片的内存容量通常受限于其硬件设计和制造技术。
三、存储器映射
存储器映射(Memory Mapping)是指将计算机中的存储器(包括RAM、ROM、寄存器等)的地址空间分配给不同的硬件或软件组件,使其能够被访问和操作。存储器映射创建了一个虚拟的地址空间,通过该空间,处理器和其他外设可以有效地进行通信。
以下是存储器映射的一些关键概念:
-
地址空间: 存储器映射创建了一个地址空间,其中包含了所有可寻址的存储单元。这个地址空间可以被划分成若干区域,每个区域对应一个设备或组件。
-
地址映射: 地址映射将逻辑地址(程序中使用的地址)映射到物理地址(实际的硬件地址)。这样,程序可以使用逻辑地址来访问存储器,而底层硬件负责将逻辑地址映射到实际的存储器位置。
-
内存映射 I/O: 存储器映射技术允许将某些设备的寄存器或控制器映射到内存地址空间,以便通过读写内存的方式来访问这些设备。这被称为内存映射 I/O。
-
外设寄存器映射: 外设(如串口、定时器、GPIO等)通常有相关的寄存器,这些寄存器被映射到存储器地址空间中的特定地址。通过写入或读取这些地址,可以配置和控制外设的行为。
-
物理地址 vs. 逻辑地址: 物理地址是硬件实际使用的地址,而逻辑地址是程序员在编写软件时使用的地址。存储器映射提供了一个桥梁,使得逻辑地址能够被正确映射到物理地址上。
存储器映射的灵活性使得计算机系统可以更方便地管理和访问各种硬件和外设,提高了系统的可扩展性和可编程性。
存储器映射是指将实际的存储器分配到特定的地址范围,从而方便处理器访问和控制。
对于星忆XM8A51216芯片,有19根地址线(A0到A18)和16根数据线(D0到D15)。地址线的数量决定了总的地址空间大小,16根数据线表示每个地址单元可以传输16位数据。
根据地址范围和映射描述,我们可以分析如下:
-
映射1:0 - 512K
- 地址范围:0x00000 - 0x7FFFF
- 数据线:D0-D15
- 这是标准的0-512K的映射,从地址0开始。
-
映射2:1 – 512K + 1
- 地址范围:0x00001 - 0x80000
- 数据线:D0-D15
- 这是将映射1中的地址整体向上偏移1。
-
映射3:100K – 612K
- 地址范围:0x19000 - 0x96FFF
- 数据线:D0-D15
- 这是将映射1中的地址整体向上偏移100K。
-
映射4:512K – 1024K
- 地址范围:0x80000 - 0xFFFFF
- 数据线:D0-D15
- 这是将映射1中的地址整体向上偏移512K,达到了512K到1024K的范围。
这些映射可以根据系统需求和硬件设计来调整,但需要确保不同映射之间没有重叠。
存储器功能划分(F1为例)
对于STM32F1系列,ST将4GB的地址空间划分为8个块,每个块有不同的功能和地址范围。以下是各存储块的功能和地址范围(以STM32F1为例):
-
Block 0: Code(FLASH)
- 功能: 存储主程序代码(Flash存储器)
- 地址范围: 0x0000 0000 ~ 0x1FFF FFFF(512MB)
-
Block 1: SRAM
- 功能: 随机存储器,用于存储变量和堆栈
- 地址范围: 0x2000 0000 ~ 0x3FFF FFFF(512MB)
-
Block 2: 片上外设
- 功能: 存储一些与片上外设相关的寄存器和数据
- 地址范围: 0x4000 0000 ~ 0x5FFF FFFF(512MB)
-
Block 3: FSMC Bank1&2
- 功能: 存储FSMC(外部存储控制器) Bank1和Bank2的外部设备映射区域
- 地址范围: 0x6000 0000 ~ 0x7FFF FFFF(512MB)
-
Block 4: FSMC Bank3&4
- 功能: 存储FSMC Bank3和Bank4的外部设备映射区域
- 地址范围: 0x8000 0000 ~ 0x9FFF FFFF(512MB)
-
Block 5: FSMC寄存器
- 功能: 存储FSMC控制寄存器等
- 地址范围: 0xA000 0000 ~ 0xBFFF FFFF(512MB)
-
Block 6: 没用到
- 功能: 该区域没有被使用
-
Block 7: Cortex M3内部外设
- 功能: 存储Cortex M3内核的内部外设寄存器
- 地址范围: 0xE000 0000 ~ 0xFFFF FFFF(512MB)
这样的划分使得不同的存储块用于不同的目的,有效地利用了整个32位地址空间。
对于 Block 0(FLASH),这里具体的功能划分如下:
-
FLASH或系统存储器别名区
- 功能: FLASH存储器或系统存储器的别名区域
- 地址范围: 0x0000 0000 ~ 0x0007 FFFF(512KB)
-
保留
- 地址范围: 0x0008 0000 ~ 0x07FF FFFF
-
用户FLASH,用于存储用户代码
- 功能: 用于存储用户程序代码
- 地址范围: 0x0800 0000 ~ 0x0807 FFFF(512KB)
-
保留
- 地址范围: 0x0808 0000 ~ 0x1FFF EFFF
-
系统存储器,存储出厂Bootloader
- 功能: 存储出厂Bootloader等系统相关信息
- 地址范围: 0x1FFF F000 ~ 0X1FFF F7FF(2KB)
-
选项字节,配置读保护等
- 功能: 存储选项字节,用于配置读保护等选项
- 地址范围: 0X1FFF F800 ~ 0X1FFF F80F(16B)
-
保留
- 地址范围: 0X1FFF F810 ~ 0X1FFF FFFF
这样的划分充分利用了 Flash 存储器的不同区域,包括用户代码区、系统存储器区、选项字节等,以满足不同的需求和配置。
对于 Block 1(SRAM),功能划分如下:
-
SRAM
- 功能: 静态随机存储器,用于存储变量、数据等
- 地址范围: 0X2000 0000 ~ 0x2000 FFFF(64KB)
-
保留
- 地址范围: 0X2001 0000 ~ 0x3FFF FFFF
这样的划分使得 Block 1 主要用于存储数据,例如变量、缓冲区等,提供了一定的存储空间供程序运行使用。
对于 Block 2(外设),功能划分如下:
-
APB1总线外设
- 功能: 连接到 APB1 总线的外设
- 地址范围: 0X4000 0000 ~ 0x4000 77FF
-
保留
- 地址范围: 0X4000 7800 ~ 0x4000 FFFF
-
APB2总线外设
- 功能: 连接到 APB2 总线的外设
- 地址范围: 0X4001 0000 ~ 0x4000 3FFF
-
保留
- 地址范围: 0X4001 4000 ~ 0x4001 7FFF
-
AHB总线外设
- 功能: 连接到 AHB 总线的外设
- 地址范围: 0X4001 8000 ~ 0x4002 33FF
-
保留
- 地址范围: 0X4002 3400 ~ 0x5FFF FFFF
这样的划分使得 Block 2 主要用于存储外设寄存器的地址,可以通过这些地址访问外设的寄存器来进行配置和控制。
STM32F1存储器映射图
参考资料:STM32F103ZET6.pdf(英文版数据手册)
数据手册:4 Memory mapping \ Figure 9. Memory map
路径:战舰 V4\资料\7,硬件资料\STM32F103ZET6.pdf
四、寄存器映射
参考资料:STM32F10xxx参考手册_V10(中文版).pdf
路径:战舰 V4\资料\8,STM32参考资料\STM32F10xxx参考手册_V10(中文版).pdf
寄存器映射是指将每个寄存器分配一个唯一的地址,以便在程序中通过这个地址来访问寄存器。在嵌入式系统中,寄存器通常用于配置和控制外设、存储状态信息等。通过寄存器映射,程序可以通过读写特定的内存地址来实现对寄存器的访问。
在微控制器或微处理器的设计中,不同的寄存器用于不同的目的,例如配置、控制、状态检测等。这些寄存器的地址被定义为特定的数值,程序可以通过这些地址与寄存器进行交互。对于每个寄存器,通常都会有相应的位域,用于表示不同的配置选项、状态标志等信息。
以下是一个简化的例子,展示了寄存器映射的一部分:
地址: 寄存器
0x40000000: 控制寄存器
0x40000004: 数据寄存器
0x40000008: 状态寄存器
0x4000000C: 配置寄存器
...
通过访问这些地址,程序可以读取或写入相应的寄存器,从而实现对硬件的配置和控制。在编程时,开发者通常会使用硬件手册或数据表来查找寄存器的地址和相关的位域信息。
寄存器基础知识
STM32寄存器分类
STM32寄存器主要可以分为两大类:内核寄存器和外设寄存器。
内核寄存器:
-
内核相关寄存器: 包括 R0~R15 寄存器,xPSR 寄存器,以及一些特殊功能寄存器。这些寄存器用于处理器的基本操作和状态管理。
-
中断控制寄存器: 包括 NVIC(Nested Vectored Interrupt Controller)和 SCB(System Control Block)相关寄存器。在 NVIC 中,有一系列寄存器用于控制中断的使能、优先级等,如 ISER(Interrupt Set Enable Register)、ICER(Interrupt Clear Enable Register)、ISPR(Interrupt Set Pending Register)等。SCB 包含一些系统级别的控制寄存器,如 VTOR(Vector Table Offset Register)、AIRCR(Application Interrupt and Reset Control Register)等。
-
SysTick 寄存器: 包括 CTRL(Control Register)、LOAD(Reload Value Register)、VAL(Current Value Register)和 CALIB(Calibration Value Register)四个寄存器。SysTick 是一个用于实现系统时钟节拍的定时器。
-
内存保护寄存器: 这些寄存器用于配置存储器的保护机制,但在一些 STM32 系列中可能并不包含。
-
调试系统寄存器: 包括 ETM(Embedded Trace Macrocell)、ITM(Instrumentation Trace Macrocell)、DWT(Data Watchpoint and Trace)等相关寄存器。这些寄存器用于支持调试和跟踪功能。
外设寄存器:
外设寄存器包括 STM32 上各种外设的配置和控制寄存器。这些外设寄存器用于配置和控制与 MCU 相连接的外围设备,如 GPIO、UART、I2C、SPI、TIM(定时器)、DMA、ADC、DAC、RTC(实时时钟)、I/WWDG(看门狗)、PWR(电源管理)、CAN(控制器局域网)、USB(通用串行总线)等。每个外设通常都有一组寄存器用于控制其行为、配置参数等。
寄存器映射(F1为例)
在 STM32 系列中,每个寄存器都有其特定的地址,该地址通常采用寄存器映射的方式进行命名。给定一个例子,如寄存器地址 0x4001080C
和寄存器名字 GPIOA_ODR
:
- 寄存器地址:
0x4001080C
- 寄存器名字:
GPIOA_ODR
这表示该寄存器的物理地址是 0x4001080C
。在 STM32 系列中,寄存器名字通常包含外设名和功能描述,以便更好地理解和识别该寄存器的用途。在这个例子中,GPIOA_ODR
可能是 GPIO(通用输入/输出)模块中的一个输出数据寄存器(Output Data Register),用于控制 GPIOA 端口上的输出状态。
通常,具体的寄存器映射和寄存器名字的含义可以在 STM32 的参考手册或数据手册中找到,这些手册由芯片制造商提供,详细描述了芯片的内部结构、外设功能和寄存器的使用方法。
寄存器描述解读
参考资料:STM32F10xxx参考手册_V10(中文版).pdf
当阅读芯片手册或数据手册时,寄存器描述通常包含以下几个重要部分:
-
寄存器名字: 这是寄存器的标识符,用于表示特定功能或外设的某个寄存器。
-
偏移量及复位值: 描述了该寄存器在整个寄存器映射中的偏移地址,通常给出了复位时寄存器的默认值。
-
寄存器位表: 列出了该寄存器的所有位,每个位对应一个特定的功能或配置选项。表格中可能包括位的名称、位的偏移量、位宽度等信息。
-
位功能描述: 对每个位进行详细的描述,解释了该位的作用、影响以及如何配置或使用。这是理解寄存器功能的关键部分。
让我们以具体的例子解读一个寄存器描述:
GPIOA_ODR (GPIOA output data register)
Offset: 0x14 Reset value: 0x0000 0000Bits | 31:16 | 15:0 ||-------|-------|
ODR | 0 | PortA ||-------|-------|
在这个例子中:
-
寄存器名字:
GPIOA_ODR
表示 GPIOA 端口的输出数据寄存器。 -
偏移量及复位值: 该寄存器的偏移量为
0x14
,复位时的默认值为0x0000 0000
。 -
寄存器位表: 该寄存器只有一个位,即
ODR
,位宽度为 16 位。该位控制 GPIOA 端口的输出。 -
位功能描述: 该位的描述可能是 “PortA”,说明这个位用于控制 GPIOA 端口的输出状态。
这是一个简化的例子,实际的寄存器描述可能更加复杂,包含更多的位和功能描述。理解这些寄存器描述对于正确配置和使用芯片的外设非常重要。
寄存器映射举例
在嵌入式开发中,直接操作寄存器地址是常见的做法。通过定义寄存器的地址,并使用指针访问这个地址,可以直接对寄存器进行读写操作。这种方式通常用于对寄存器位进行精确控制,例如配置 GPIO 的输入输出状态。
下面是一个简单的示例,演示如何通过直接操作寄存器地址或使用宏定义的方式控制 GPIOA 的输出状态:
// 直接操作寄存器地址
*(unsigned int *)(0x4001080C) = 0xFFFF; // 设置 GPIOA_ODR 寄存器的值为 0xFFFF// 使用宏定义
#define GPIOA_ODR (*(volatile unsigned int *)(0x4001080C)) // 定义 GPIOA_ODR 的宏
GPIOA_ODR = 0xFFFF; // 设置 GPIOA_ODR 寄存器的值为 0xFFFF
在这个例子中,0x4001080C
是 GPIOA_ODR 寄存器的地址,volatile
关键字用于告诉编译器该变量是易变的,可能会被外部因素更改,因此编译器不会进行一些优化,确保每次都从内存中读取值。
使用宏定义的方式有助于提高代码的可读性和维护性。通过定义宏,可以将寄存器的地址封装在宏中,给这个地址起一个易于理解的名字,方便在代码中使用。这也是嵌入式开发中常见的一种编程风格。
寄存器地址计算
寄存器地址计算的思路是将寄存器的地址拆分为三个部分,这样的设计有助于更灵活地应对不同的外设、总线等。具体而言,计算公式如下:
寄存器地址 = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET \text{寄存器地址} = \text{BUS\_BASE\_ADDR} + \text{PERIPH\_OFFSET} + \text{REG\_OFFSET} 寄存器地址=BUS_BASE_ADDR+PERIPH_OFFSET+REG_OFFSET
其中:
- BUS_BASE_ADDR:总线基地址,代表总线的起始地址。
- PERIPH_OFFSET:外设基于总线基地址的偏移量,表示特定外设相对于总线的位置。
- REG_OFFSET:寄存器相对外设基地址的偏移量,表示特定寄存器相对于外设的位置。
这种寄存器地址计算的方法允许我们通过更改这三个部分的数值,轻松地适应不同的硬件配置和外设分布。在嵌入式系统中,通常由芯片厂商提供相应的寄存器映射表和基地址信息,开发人员可以据此进行地址计算和寄存器操作。
参考资料:STM32F10xxx参考手册_V10(中文版).pdf 2.3小节
GPIOA_ODR寄存器地址计算过程:
你的计算是正确的,下面将每一步详细讲解:
-
获取外设挂在哪个总线上面?查系统结构图得知 GPIOA 外设挂在 APB2 总线上。
-
获取总线基地址,APB2 总线基地址为 0 X 40010000 0X4001 0000 0X40010000。
-
获取外设地址偏移量,GPIOA 相对于 APB2 总线的偏移量是 0 X 800 0X800 0X800。
-
获取寄存器地址偏移量,ODR 相对于 GPIOA 外设的基地址的偏移量是 0 X 0 C 0X0C 0X0C。
现在,可以使用寄存器地址计算公式计算 GPIOA_ODR 的地址:
GPIOA_ODR = BUS_BASE_ADDR + PERIPH_OFFSET + REG_OFFSET \text{GPIOA\_ODR} = \text{BUS\_BASE\_ADDR} + \text{PERIPH\_OFFSET} + \text{REG\_OFFSET} GPIOA_ODR=BUS_BASE_ADDR+PERIPH_OFFSET+REG_OFFSET
将具体数值代入:
GPIOA_ODR = 0 X 40010000 + 0 X 800 + 0 X 0 C = 0 X 4001080 C \text{GPIOA\_ODR} = 0X4001 0000 + 0X800 + 0X0C = 0X4001 080C GPIOA_ODR=0X40010000+0X800+0X0C=0X4001080C
因此,GPIOA_ODR 寄存器的地址是 0 X 4001080 C 0X4001 080C 0X4001080C。
0 X 40013804 0X40013804 0X40013804
使用结构体,可以很方便的完成对寄存器的映射:
使用结构体进行寄存器映射,可以更方便地访问和操作寄存器,提高代码的可读性和可维护性。定义一个结构体 GPIO_TypeDef
包含了 GPIO 相关寄存器的成员,然后使用结构体指针来访问寄存器,是一种常见的做法。
在上述例子中:
typedef struct
{__IO uint32_t CRL;__IO uint32_t CRH;__IO uint32_t IDR;__IO uint32_t ODR;__IO uint32_t BSRR;__IO uint32_t BRR;__IO uint32_t LCKR;
} GPIO_TypeDef;#define GPIOA_BASE 0X4001 0800
#define GPIOA ((GPIO_TypeDef *)GPIOA_BASE)// 访问 GPIOA 的 ODR 寄存器
GPIOA->ODR = 0XFFFF;
这样的代码更加清晰和易于维护。通过使用结构体,你可以直观地理解每个寄存器的作用,也方便了对硬件的配置和操作。
stm32f103xe.h主要组成部分
stm32f103xe.h
路径:战舰 V4\资料\4,程序源码\2,标准例程-HAL库版本\实验1 跑马灯实验\stm32f103xe.h
跳转到此处