3.3 SystemInit详解
2026/4/26大约 4 分钟启动流程SystemInit时钟STM32
3.3 SystemInit详解
📚 本节导读
学习时长: 约 30 分钟
难度级别: ⭐⭐☆☆☆(基础级)
前置知识: 3.2 启动文件解析
🎯 学习目标
- 掌握 SystemInit() 的实际作用
一、函数概述
1.1 概念定义
SystemInit() 是 STM32 芯片的系统级初始化函数,由 ST 官方 HAL 库提供。它位于芯片启动流程的最早期,在 C 运行时环境初始化之前执行,负责为后续系统运行准备最基础的硬件环境。
1.2 函数位置
SystemInit() 函数位于:projects/stm32f103zet6-atk-elite/board/CubeMX_Config/Src/system_stm32f1xx.c二、功能说明
2.1 核心功能说明
SystemInit() 的设计原则是"最小化初始化",仅执行启动必需的操作:
| 功能模块 | 说明 | 必要性 |
|---|---|---|
| 时钟复位 | 将 RCC 相关寄存器恢复到复位状态,确保从已知安全的状态开始 | ✅ 必须 |
| HSI 时钟启用 | 开启内部高速振荡器,提供临时系统时钟 | ✅ 必须 |
| 向量表配置 | 设置 VTOR 寄存器,告诉 CPU 中断向量表的位置 | ✅ 必须 |
| 外部 SRAM 初始化 | 仅在需要时执行,用于扩展内存 | ⚪ 可选 |
2.2 函数实际作用
根据项目实际代码,SystemInit() 主要做 三件事:
- 复位 RCC 时钟配置
- 外部 SRAM 初始化(可选)
- 配置向量表偏移
三、代码解析
3.1 完整代码(第 157-210 行)
void SystemInit (void)
{
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
/* Set HSION bit */
RCC->CR |= 0x00000001U;
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)
RCC->CFGR &= 0xF8FF0000U;
#else
RCC->CFGR &= 0xF0FF0000U;
#endif /* STM32F105xC */
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= 0xFEF6FFFFU;
/* Reset HSEBYP bit */
RCC->CR &= 0xFFFBFFFFU;
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
RCC->CFGR &= 0xFF80FFFFU;
#if defined(STM32F105xC) || defined(STM32F107xC)
/* Reset PLL2ON and PLL3ON bits */
RCC->CR &= 0xEBFFFFFFU;
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x00FF0000U;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000U;
#elif defined(STM32F100xB) || defined(STM32F100xE)
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000U;
/* Reset CFGR2 register */
RCC->CFGR2 = 0x00000000U;
#else
/* Disable all interrupts and clear pending bits */
RCC->CIR = 0x009F0000U;
#endif /* STM32F105xC */
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif
}3.2 分步详细解释
第一步:复位 RCC 时钟配置
/* Set HSION bit */
RCC->CR |= 0x00000001U;- 解释: 设置 HSION bit
- 含义: 开启内部高速时钟(HSI),这是 STM32 的默认时钟源,频率为 8MHz
- 作用: 确保系统有一个稳定的时钟源运行
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#if !defined(STM32F105xC) && !defined(STM32F107xC)
RCC->CFGR &= 0xF8FF0000U;
#else
RCC->CFGR &= 0xF0FF0000U;
#endif- 解释: 复位时钟配置寄存器(CFGR)
- 作用: 清除系统时钟选择、AHB/APB 预分频、ADC 预分频、时钟输出等位
/* Reset HSEON, CSSON and PLLON bits */
RCC->CR &= 0xFEF6FFFFU;- 解释: 复位控制寄存器(CR)
- 作用: 关闭外部高速时钟(HSE)、时钟安全系统(CSS)、PLL
第二步:外部 SRAM 初始化(可选)
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif- 解释: 条件编译外部 SRAM 初始化
- 含义: 只有需要把数据段放在外部 SRAM 时才执行
- 本项目: 不启用,不会执行这里
第三步:配置向量表偏移
/* 配置向量表偏移 */
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
#endif- 解释: 配置向量表偏移寄存器(VTOR)
- 本项目配置:
VECT_TAB_SRAM未定义,向量表放在 Flash 中 - 作用: 告诉 CPU 中断向量表在哪里
四、关键点说明
| 功能 | 说明 |
|---|---|
| 时钟复位 | 将所有时钟相关寄存器恢复到复位状态 |
| 启用 HSI | 内部 8MHz 时钟作为临时系统时钟 |
| 向量表配置 | VTOR = 0x08000000(Flash 起始) |
| 不配置 PLL | SystemInit() 不配置系统主时钟到 72MHz |
| 不初始化外设 | HAL、GPIO、UART 等都不在这初始化 |
注意: SystemInit() 只做最基础的复位和配置,复杂的时钟配置和外设初始化在后续步骤完成。
💡 本节总结
重点回顾
- SystemInit() 的定位:芯片级基础初始化函数,在 C 运行时环境之前执行
- SystemInit() 的核心功能:
- 时钟复位
- 启用 HSI 内部时钟
- 配置向量表到 0x08000000
- 设计原则:最小化初始化,仅做启动必需操作
下一步
接下来请学习:3.4 $Sub$$main钩子详解