单片机启动流程详细介绍
文章目录
- **一、复位阶段:触发启动的起点**
- 1. 复位触发方式
- 2. 复位后的硬件状态
- **二、向量表跳转:从复位向量到启动代码**
- 1. 向量表的作用
- 2. 跳转至Bootloader
- **三、Bootloader执行:硬件与环境初始化**
- 1. 堆栈初始化
- 2. 时钟系统初始化
- 3. 存储器初始化(若有外部存储)
- 4. 数据段与BSS段初始化(C语言程序必备)
- 5. 外设初始化(可选)
- 6. 启动模式判断(关键分支)
- **四、跳转至用户程序:执行main函数**
- **不同架构的差异举例**
- **总结**
单片机的启动流程是指从芯片上电复位到执行用户程序(如main
函数)的完整过程,其核心是通过硬件复位触发初始化,再由启动代码(Bootloader)完成底层配置,最终过渡到用户应用。不同架构的单片机(如ARM Cortex-M、8051、PIC等)流程略有差异,但核心逻辑一致。以下是详细拆解:
一、复位阶段:触发启动的起点
单片机的启动始于复位信号,这是启动流程的“开关”。复位的目的是将芯片内部状态恢复到初始值,确保程序从固定起点执行。
1. 复位触发方式
复位信号可由多种场景触发,不同触发源对应不同的启动需求:
- 上电复位(POR):芯片刚接通电源时,电源电压达到阈值后自动产生复位信号,确保电源稳定后再启动。
- 手动复位:通过外部复位引脚(如STM32的
NRST
、8051的RST
)施加低电平(或高电平,依芯片而定)强制复位。 - ** watchdog 复位**:若程序跑飞未及时喂狗, watchdog 定时器溢出触发复位,用于故障恢复。
- 软件复位:通过特定指令(如ARM的
SVC
、8051的RESET
指令)主动触发复位。
2. 复位后的硬件状态
复位信号结束后,单片机内部硬件会进入默认状态:
- 程序计数器(PC):指向复位向量地址(芯片出厂预设的固定地址,如STM32的0x08000000),这是CPU执行第一条指令的位置。
- 寄存器初始化:关键寄存器(如堆栈指针SP、状态寄存器CPSR等)恢复默认值(如SP可能初始化为0x00000000,需后续代码重新配置)。
- 外设禁用:所有外设(GPIO、UART、定时器等)默认处于禁用状态,需后续代码初始化。
二、向量表跳转:从复位向量到启动代码
复位向量地址存储的并非直接执行的代码,而是跳转指令(或中断服务程序入口),其作用是引导CPU进入启动代码(Bootloader)。
1. 向量表的作用
向量表是一段存储“异常/中断入口地址”的内存区域(通常位于Flash起始地址),包含复位、NMI、硬 fault 等异常的处理入口。例如:
- 复位向量:向量表的第一个条目,存储启动代码的入口地址。
- 其他向量:如中断向量(UART接收中断、定时器溢出中断等),供后续程序运行时使用。
以ARM Cortex-M3为例,向量表结构如下:
地址偏移 | 内容 | 说明 |
---|---|---|
0x00 | 初始堆栈指针(SP) | 复位后SP的初始值 |
0x04 | 复位向量(PC初始值) | 指向Bootloader入口地址 |
0x08 | NMI向量 | 不可屏蔽中断服务程序入口 |
… | … | … |
2. 跳转至Bootloader
复位向量中存储的指令通常是一条无条件跳转指令(如ARM的B
指令),将CPU引导至Bootloader(启动加载程序)。Bootloader是芯片厂商或用户预先烧录的底层代码,负责启动前的核心配置。
三、Bootloader执行:硬件与环境初始化
Bootloader是启动流程的核心,负责完成从硬件到软件的过渡,主要包括以下步骤:
1. 堆栈初始化
堆栈是程序运行的基础(用于函数调用、局部变量存储、中断现场保护),Bootloader首先会重新配置堆栈指针(SP):
- 通常将SP指向内部RAM的顶部(如STM32的RAM起始地址+大小,假设RAM为0x20000000~0x2000FFFF,则SP可能设为0x20010000)。
- 若使用外部RAM,需先初始化外部存储器接口(如FSMC),再将SP指向外部RAM。
2. 时钟系统初始化
单片机的CPU、外设需依赖稳定的时钟源才能工作,Bootloader会优先配置时钟系统:
- 选择时钟源:从内部高速时钟(HSI)、外部高速时钟(HSE)、PLL锁相环等中选择(如STM32默认用HSI,Bootloader可能切换为HSE+PLL以提高频率)。
- 配置分频系数:设置CPU主频(如STM32通过PLL将HSE(8MHz)倍频至72MHz)、外设时钟(如APB1分频为36MHz供UART使用)。
例如,8051单片机的时钟初始化:默认使用内部RC振荡器(约12MHz),Bootloader可通过配置特殊功能寄存器(如CKCON
)切换为外部晶振。
3. 存储器初始化(若有外部存储)
若系统使用外部存储(如外部Flash、SRAM),Bootloader需初始化存储器接口:
- 配置时序参数(如地址建立时间、数据保持时间),确保CPU能正确读写外部存储(如STM32的FSMC接口初始化用于驱动外部NOR Flash)。
- 检测外部存储是否存在,若异常可能触发报错(如点亮错误指示灯)。
4. 数据段与BSS段初始化(C语言程序必备)
C语言程序中的全局变量和静态变量需在启动时初始化,Bootloader会处理两个关键数据段:
- data段(已初始化变量):存储在Flash中(只读),需复制到RAM中(可读写)。例如,
int a = 10;
中a
的初始值10
在Flash,Bootloader会将其复制到RAM的a
地址。 - bss段(未初始化变量):默认值为0,Bootloader会将该段对应的RAM区域清零。例如,
int b;
中b
的初始值由Bootloader设为0。
这一步确保程序运行时变量有正确的初始值,避免随机值导致错误。
5. 外设初始化(可选)
部分Bootloader会初始化基础外设用于启动指示或交互:
- 初始化LED:点亮LED表示启动中。
- 初始化串口:用于输出启动日志(如“Bootloader start”)或接收用户指令(如升级程序)。
6. 启动模式判断(关键分支)
Bootloader会根据预设条件(如引脚电平、按键状态)判断启动模式,决定下一步执行逻辑:
- 正常启动:若满足默认条件(如启动引脚为高电平),则跳转到用户程序入口(通常是
main
函数)。 - 升级模式:若检测到特殊条件(如启动引脚为低电平,或串口收到升级指令),则进入程序升级流程(如通过UART接收新程序并烧录到Flash)。
例如,STM32可通过BOOT0
和BOOT1
引脚配置启动模式:
BOOT0=0
:从主Flash启动(用户程序)。BOOT0=1
且BOOT1=0
:从系统存储器启动(厂商Bootloader,用于通过串口烧录程序)。
四、跳转至用户程序:执行main函数
若Bootloader判断为正常启动,会最终跳转到用户程序的入口地址。对于C语言程序,这个入口是**main
函数**,但跳转前需满足两个条件:
- 用户程序已正确烧录到指定地址(如STM32的主Flash)。
- 跳转地址需符合CPU要求(如ARM要求跳转地址的最低位为1,表示Thumb模式)。
跳转后,CPU开始执行main
函数中的用户代码,完成具体功能(如传感器采集、电机控制等)。
不同架构的差异举例
-
ARM Cortex-M(如STM32):
- 向量表前4字节为初始SP,后4字节为复位向量(指向Bootloader)。
- Bootloader由厂商提供(如系统存储器中的Bootloader)或用户自定义,支持多种启动模式。
-
8051单片机:
- 复位后PC=0000H,直接从0000H执行第一条指令(通常是跳转至用户程序)。
- 无内置Bootloader,需用户代码自行处理初始化(如堆栈设置、时钟配置)。
-
PIC单片机:
- 复位向量固定为0000H,通常存放跳转指令至用户代码。
- 需通过配置位(Configuration Bits)设置启动相关参数(如振荡器类型、看门狗使能)。
总结
单片机启动流程可概括为:
复位触发→向量表跳转→Bootloader初始化(堆栈、时钟、存储、数据段)→启动模式判断→跳转到用户程序(main)。
理解这一流程有助于调试启动故障(如程序跑飞、变量初始化错误),并根据需求定制启动逻辑(如自定义升级模式)。