STM32如果需要复位可使用库函数NVIC_SystemReset(); 一般的做IAP才进行软件复位,代码放在IAP完成之后。
附上库函数:
/* ################################## Reset function ############################################ */
/**
* @brief Initiate a system reset request.
*
* Initiate a system reset request to reset the MCU
*/
static __INLINE void NVIC_SystemReset(void)
{
SCB-AIRCR = ((0x5FA SCB_AIRCR_VECTKEY_Pos) |
(SCB-AIRCR SCB_AIRCR_PRIGROUP_Msk) |
SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */
__DSB(); /* Ensure completion of memory access */
while(1); /* wait until reset */
}
/*@}*/ /* end of group CMSIS_CM3_Core_FunctionInterface */
一样的,C语言都是从main()函数开始执行的,所有的单片机都是这样的,AVR,freescale,STM8,STM32...
如果不清楚该怎么写,ST官网上都是程序库例程的,你下载下来研究一下就明白了,里面有keil,iar,gcc这几个开发环境各有一套例程
直接使用复位命令:
NVIC_SystemReset();//系统复位
即可,和上电复位一个效果
因为STM32设计的Flash起始地址是在0x0800 0000位置开始的。全部代码都只能在从这里开始存储。详见STM32 referenc manual手册第54页。
那既然从这里才能存储代码,就必须在MDK里设置Flash地址为0x0800 0000,下面是MDK设置页面,这个应该都看到过:
这样就还有一个问题,理论上,CM3中规定上电后CPU是从0地址开始执行,但是这里中断向量表却被烧写在0x0800 0000地址里,这是因为STM32的Flash是从0x0800 0000开始才有。但SMT32也不能破坏ARM定下的“规矩”,所以它做了一个启动映射的过程,就是和芯片上总能见到的BOOT0和BOOT1有关了,当选择从主Flash启动模式后,芯片一上电,Flash的0x0800 0000地址被映射到0地址处,不影响CM3内核的读取,所以这时的CM3既可以在0地址处访问中断向量表,也可以在0x0800 0000地址处访问中断向量表,而代码还是在0x0800 0000地址处存储的。这就是最难理解的地方,其实,这是基本上所有ARM芯片采用的启动映射方法。ARM7,ARM9没有内部Flash的通常都是这样做的。这个过程出自STM32 referenc manual手册,里面是有说明的:
还要注意,这个中断向量表是可以在程序中再次被映射的。控制它的就是CM3已经规定的NVIC寄存器SCB-VTOR。在STM32库中给出的启动代码里,startup_stm32f10x_hd.s文件里,第146行,是上电后读取中断向量表中的复位中断位置,并执行复位中断处理代码,代码如下:
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __main
IMPORT SystemInit
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
注意复位后第一个被执行的是SystemInit代码,这个代码在库目录下的system_stm32f10x.c文件里,它初始化了时钟,NVIC等一系列操作,这里摘要与中断向量有关的代码:
void SystemInit (void)
{
......
#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
}
可以看出中断向量重映射是一个选择性编译,通常宏定义VECT_TAB_SRAM都没有被定义,所以这里执行结束后,SCB-VTOR就是FLASH_BASE了,值为0x0800 0000。以后CM3再取中断向量里,就会根据SCB-VTOR的设置,从这里取向量执行了。中断向量自此终于转正。
注意这时连__main函数都还没进,看起来中断向量的重映射位置还是够早的。
可能的两个原因:
你目前的开发工具(IAR或keil)对低版本的工程不兼容导致,尤其是使用低版本软件打开高版本工程,很容易出现这个问题(PS:前几天我使用IAR就遇到这问题,在设置上下功夫没有任何作用),解决方法:使用你现在的开发工具新建工程,重新添加源代码(这个过程不熟悉的话请自行百度)
你的程序烧写最终的起始地址不对,STM32内部flash是从0x08000000这个地址开始执行的,若你的代码起始地址不是这个,就很容易出现问题。(起始这条可能不适用你的情况,这种情况的结果是仿真可以进入主函数的,但独立运行就不行了)。
本文标签:stm32软件复位main函数