在嵌入式系统开发中,STM32 微控制器凭借其高性能、低功耗等优势得到了广泛应用。了解 STM32 的启动过程对于开发者来说至关重要,它不仅有助于理解硬件与软件的交互机制,还能为后续的开发和调试工作提供坚实的基础。下面我们将详细介绍 STM32 的启动过程、启动模式、串口程序原理以及从汇编代码角度分析启动过程。
- 上电复位:当 STM32 单片机上电后,硬件会自动对堆栈指针 (SP) 和程序计数器 (PC) 进行设置。堆栈指针通常会被初始化为一个预设值,这个预设值为后续程序运行时的堆栈操作提供了基础。而程序计数器则指向复位向量表的起始地址,一般为 0x08000004。复位向量表是 STM32 启动的关键,它包含了一系列中断服务程序的入口地址,程序计数器指向这里,意味着后续程序将从这个地址开始执行相关的初始化操作。
- 初始化系统时钟:系统复位后,硬件会自动对齐到 0x08000144 地址,然后执行 SystemInit 函数来初始化系统时钟。系统时钟是 STM32 运行的基础,它为各个外设和模块提供了稳定的时钟信号。合适的系统时钟配置能够确保 STM32 在不同的应用场景下高效、稳定地运行。例如,在一些对实时性要求较高的应用中,需要配置较高的系统时钟频率;而在低功耗应用中,则可以适当降低系统时钟频率。
- 加载.data 和.bss 段:程序会将已初始化的数据段 (.data) 和未初始化的数据段 (.bss) 从 Flash 加载到 SRAM 中,并进行初始化。.data 段包含了已经初始化的全局变量和静态变量,而.bss 段则包含了未初始化的全局变量和静态变量。将这些数据段加载到 SRAM 中,是为了方便程序在运行过程中对这些变量进行快速访问和修改。
- 跳转到 main 函数:完成上述步骤后,程序会跳转到 main 函数,开始执行用户的应用程序。main 函数是用户程序的入口点,开发者可以在其中编写自己的业务逻辑代码,实现各种功能。
STM32 支持三种启动模式,每种模式都有其特定的应用场景。
- 主闪存存储器启动:从 STM32 内置的 Flash 启动,地址范围为 0x08000000 到 0x0807FFFF。这是常见的启动模式,通常通过 JTAG 或 SWD 程序。在这种模式下,主 Flash 地址 0x08000000 会被映射到 0x00000000,代码启动后就相当于从 0x08000000 开始执行。主闪存存储器作为芯片内置的 Flash,是 STM32 正常的工作模式,适合存储和运行终的应用程序。
- 系统存储器启动:从内置 ROM 启动,地址范围为 0x1FFFF000 到 0x1FFF F7FF。这种模式通常用于通过串口程序。芯片出厂时,在这个区域预置了一段 Bootloader,也就是我们常说的 ISP 程序。这个区域的内容在芯片出厂后无法修改或擦除,是一个 ROM 区。启动的程序功能由厂家设置,主要用于通过串口将程序到系统的 Flash 中。
- 片上 SRAM 启动:从内置 SRAM 启动,地址范围为 0x20000000 到 0x3FFFFFFF。这种模式适用于调试,因为 SRAM 没有存储能力,但读写速度快。将 SRAM 地址 0x20000000 映射到 0x00000000,代码启动后就相当于从 0x20000000 开始。在调试过程中,如果只修改了代码中的一小部分,使用这种模式可以避免重新擦除整个 Flash,节省调试时间。
用户可以通过设置 BOOT1 和 BOOT0 引脚的状态,来选择在复位后的启动模式。STM32 三种启动模式对应的存储介质均是芯片内置的,如下图所示:

从系统存储器启动时,这种模式启动的程序功能是由厂家设置的。系统存储器是芯片内部一块特定的区域,STM32 在出厂时,由 ST 在这个区域内部预置了一段 BootLoader,也就是我们常说的 ISP 程序,这是一块 ROM,出厂后无法修改。
一般来说,选用这种启动模式是为了从串口程序。因为在厂家提供的 BootLoader 中,提供了串口程序的固件,可以通过这个 BootLoader 将程序到系统的 Flash 中。具体的步骤如下:
- 将 BOOT0 设置为 1,BOOT1 设置为 0,然后按下复位键,这样才能从系统存储器启动 BootLoader。
- 在 BootLoader 的帮助下,通过串口程序到 Flash 中。
- 程序完成后,需要将 BOOT0 设置为 GND,手动复位,这样,STM32 才可以从 Flash 中启动。
STM32 的启动文件与编译器有关,不同编译器的启动文件不同。虽然启动文件 (汇编) 代码各有不同,但它们的原理类似,都属于汇编程序。下面以基于 MDK - ARM 的启动文件为例,分析其中的要点内容。
在基于 MDK 的启动文件开始,有一段汇编代码是分配堆栈大小的。这里我们重点关注堆栈数值大小,因为堆栈的大小会影响程序运行时的栈空间使用。还有一段 AREA (区域),表示分配一段堆栈数据段。可以使用 STM32CubeMX 对上面的数值大小进行配置,也可以在 IAR 中通过工程配置堆栈大小。



程序上电之后,会跳到 Reset_Handler 这个位置。知道代码是从 Reset_Handler 开始执行后,再来看 Reset_Handler 汇编代码。在启动的时候,会执行 SystemInit 这个函数,执行完该函数后,初始化了系统时钟,之后跳转到 main 函数执行。


通过深入理解 STM32 的启动过程、启动模式、串口程序原理以及从汇编代码角度分析启动过程,开发者可以更好地进行开发和调试工作,确保系统能够稳定运行。在实际开发中,根据不同的应用场景选择合适的启动模式和配置参数,能够提高开发效率和系统的性能。例如,在产品开发的调试阶段,可以多使用片上 SRAM 启动模式进行快速调试;而在产品正式发布时,则使用主闪存存储器启动模式来存储和运行终的应用程序。