一、启动概述

STM32F103从上电到运行用户程序经历了一个精确的启动序列,主要包括硬件复位、启动模式选择、堆栈指针初始化、跳转到复位处理程序等步骤。

二、启动模式选择

1. 三种启动模式

STM32F103通过BOOT0和BOOT1引脚的电平状态决定启动模式:

  • 主闪存启动 (BOOT1=X, BOOT0=0)

    • 从0x08000000地址启动
    • 这是最常用的模式,运行用户程序
  • 系统存储器启动 (BOOT1=0, BOOT0=1)

    • 从0x1FFFF000地址启动
    • 运行ST出厂固化的Bootloader
    • 用于通过串口等接口下载程序
  • 内置SRAM启动 (BOOT1=1, BOOT0=1)

    • 从0x20000000地址启动
    • 用于调试或运行RAM中的代码

2. 地址映射机制

根据启动模式,0x00000000地址会被映射到不同的物理地址:

  • 主闪存模式:0x00000000映射到0x08000000
  • 系统存储器模式:0x00000000映射到0x1FFFF000
  • SRAM模式:0x00000000映射到0x20000000

三、详细启动流程

1. 上电复位阶段

上电 → POR/PDR复位 → 等待时钟稳定 → 读取BOOT引脚
  • 电源监控:POR(Power On Reset)和PDR(Power Down Reset)监控电源电压
  • 复位延时:确保电源稳定,典型值约为几毫秒
  • HSI启动:默认使用8MHz内部高速时钟(HSI)作为系统时钟

2. 向量表读取

芯片首先从启动地址读取两个重要的32位数据:

地址0x00000000: 初始堆栈指针值(MSP)
地址0x00000004: 复位向量(Reset_Handler地址)

3. 硬件初始化

// CPU自动执行的操作:
1. SP = 读取地址0x00000000的值  // 设置主堆栈指针
2. PC = 读取地址0x00000004的值  // 跳转到Reset_Handler

4. Reset_Handler执行

这是第一个执行的用户代码,通常完成:

Reset_Handler:
    // 1. 设置向量表偏移寄存器(如果需要)
    SCB->VTOR = FLASH_BASE;
    
    // 2. 初始化数据段(.data)
    // 从Flash复制初始化数据到RAM
    
    // 3. 清零BSS段
    // 将未初始化的全局变量清零
    
    // 4. 调用SystemInit()
    // 配置时钟系统、PLL等
    
    // 5. 调用C库初始化(如果使用)
    __libc_init_array();
    
    // 6. 跳转到main函数
    main();

5. SystemInit系统初始化

SystemInit()函数主要完成:

  • 时钟配置

    • 使能HSE(外部高速时钟)
    • 配置PLL倍频
    • 设置AHB、APB1、APB2分频器
    • 切换系统时钟源到PLL
  • Flash访问配置

    • 设置Flash预取缓冲
    • 配置Flash等待周期
  • 中断向量表配置

    • 设置向量表偏移地址

四、启动时序示例

时间线:
0ms:   上电,POR复位激活
1-2ms: 电压稳定,读取BOOT引脚
2ms:   从0x08000000读取MSP值
2.1ms: 从0x08000004读取Reset_Handler地址  
2.2ms: 跳转执行Reset_Handler
3ms:   执行SystemInit,配置时钟
5ms:   时钟切换完成,进入main函数

五、重要寄存器

1. RCC寄存器

  • RCC_CR: 时钟控制寄存器
  • RCC_CFGR: 时钟配置寄存器
  • RCC_CSR: 控制/状态寄存器(包含复位标志)

2. SCB寄存器

  • SCB_VTOR: 向量表偏移寄存器
  • SCB_AIRCR: 应用中断和复位控制寄存器

六、启动代码示例

典型的启动文件结构(startup_stm32f103.s):

.section .isr_vector
.word _estack          /* 栈顶地址 */
.word Reset_Handler    /* 复位处理函数 */
.word NMI_Handler      /* NMI处理函数 */
.word HardFault_Handler /* 硬件错误处理 */
/* ... 其他中断向量 ... */

Reset_Handler:
    /* 复制.data段 */
    ldr r0, =_sdata
    ldr r1, =_edata
    ldr r2, =_sidata
    /* ... 复制代码 ... */
    
    /* 清零.bss段 */
    ldr r0, =_sbss
    ldr r1, =_ebss
    /* ... 清零代码 ... */
    
    /* 调用系统初始化 */
    bl SystemInit
    
    /* 调用main函数 */
    bl main

七、注意事项

  1. 启动时间优化

    • 减少全局变量初始化
    • 优化时钟配置流程
    • 合理设置Flash等待周期
  2. 调试技巧

    • 通过RCC_CSR寄存器判断复位原因
    • 使用GPIO翻转监测启动时间
    • 检查向量表配置是否正确
  3. 常见问题

    • 晶振不起振导致启动失败
    • Flash等待周期设置不当
    • 堆栈溢出导致启动异常

这个启动过程确保了STM32F103能够可靠地从复位状态过渡到运行用户应用程序,整个过程通常在几毫秒内完成。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐