为了更好地理解为什么STM32需要按硬件复位才会跑程序,我们需要先了解CPU的启动机制。在复位时,CPU从固定地址0x00000000开始执行代码,这个地址称为向量表基址(VTOR),在向量表中存储着中断向量表和复位向量表。复位向量表中包含着复位时应执行的第一条指令的地址,在STM32中,这个地址是0x08000000。
当我们给STM32芯片上电时,芯片内部的电源管理单元(PMU)会先进行初始化,之后会向复位引脚发布一个复位信号,让CPU进入复位模式。在复位模式下,CPU会初始寄存器的默认值,如将SP(堆栈指针)设为0x00000000等。在这个模式下,CPU不会去执行Flash中的代码,而是等待重新启动。
那么为什么不是在上电时CPU自动执行Flash中的代码呢?这是为了保证系统稳定,防止上电时设备处于未知状态,执行非预期代码导致系统崩溃。
我们可以通过软件复位来重置CPU,这可以通过设定NVIC_SystemReset()函数实现。软件复位可以在运行期间任意执行,但不会影响芯片内部电源管理单元(PMU)或者引脚,可能会导致设备处于不稳定状态,需要重新上电进行复位。
相比之下,硬件复位是通过对芯片复位引脚施加一个高电平的脉冲来实现的。这个脉冲来自于外部复位电路或者复位按键。通过硬件复位,我们可以同时重置CPU和芯片内部电源管理单元(PMU)的状态,确保系统的稳定性。
当我们按下复位按键时,CPU会进入复位模式,之后会根据VTOR中的地址跳转到复位向量表中执行第一条指令。在STM32中,这个指令为“LDR R0, =0x08000000”,其目的是将地址0x08000000的内容装载到R0寄存器中,然后通过“BX R0”指令跳转到Flash的地址0x08000000处开始执行程序。
而当我们在运行中通过软件复位来重置CPU时,CPU会执行复位向量表中的地址,这个地址指向了一个专门的复位函数,用于重置寄存器,初始化缓存和时钟等。之后CPU会跳转到固定地址0x20000000开始执行代码。