关于STM32软件复位代码编写 (转)

本文介绍STM32的两种软件复位方法:使用官方软件库和编写自定义汇编代码。强调了在触发系统复位前设置FAULTMASK的重要性,并提供MDK和IAR环境下的通用复位代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于STM32来说软件复位有两种方式:
 
1)采用官方自带的软件库
 
  在官方软件库的stm32f10x_nvic.c 文件里 直接提供了 系统复位的函数
 
/*******************************************************************************
* Function Name  : NVIC_GenerateSystemReset
* Description    : Generates a system reset.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_GenerateSystemReset(void)
{
  SCB->AIRCR = AIRCR_VECTKEY_MASK | (u32)0x04;
}
 
但是不是直接调用这个函数就OK了?
 
在Cortex-M3权威指南中有这么一句话
 
这里有一个要注意的问题:从SYSRESETREQ 被置为有效,到复位发生器执行复位命令,
往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。但我们的本意往往是要
让此次执行到此为止,不要再做任何其它事情了。所以,最好在发出复位请求前,先把
FAULTMASK 置位。
 
所以最好在将FAULTMASK 置位才万无一失。
 
同样官方stm32f10x_nvic.c 文件里也直接提供了该函数
 
/*******************************************************************************
* Function Name  : NVIC_SETFAULTMASK
* Description    : Enables the FAULTMASK priority: Raises the execution priority to -1.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_SETFAULTMASK(void)
{
  __SETFAULTMASK();
}
 
所以要系统复位 只要 调用这两个函数就OK了
NVIC_SETFAULTMASK();
GenerateSystemReset();
 
2)自己编写相应汇编代码
 
其实道理是一样的,我当初是没有看到官方的函数所以自己编的,实际你看官方函数里面其实就是调用的cortexm3_macro.s同样的代码 呵呵。
 
我的代码:
 
/*******************************************************************************
* Function Name  : SystemReset
* Description    : Configures the port pin connected to the push button. GPIO_D_4
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
__asm void SystemReset(void)
{
 MOV R0, #1           //; 
 MSR FAULTMASK, R0    //; 清除FAULTMASK 禁止一切中断产生
 LDR R0, =0xE000ED0C  //;
 LDR R1, =0x05FA0004  //;
 STR R1, [R0]         //; 系统软件复位   
 
deadloop
    B deadloop        //; 死循环使程序运行不到下面的代码
}
 
然后用的时候在C程序里直接调用该函数就行了。
 
SystemReset();
在MDK环境下,包含汇编的代码嵌入到C代码中时,编写、调用与C函数一样
在misc.c中定义了上面的函数;
在misc.h中声明了函数:void SystemReset(void);
在main.c中调用函数:SystemReset();
补充:
MDK和IAR通用的软件复位代码:
#if defined ( __CC_ARM   ) /*------------------RealView Compiler -----------------*/
__asm void GenerateSystemReset(void)
{
 MOV R0, #1           //; 
 MSR FAULTMASK, R0    //; FAULTMASK 禁止一切中断产生
 LDR R0, =0xE000ED0C  //;
 LDR R1, =0x05FA0004  //; 
 STR R1, [R0]         //;   
 
deadloop
    B deadloop        //; 
}
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
//#pragma diag_suppress=Pe940
void GenerateSystemReset(void)
{
  __ASM("MOV R0, #1");
  __ASM("MSR FAULTMASK, R0");
  SCB->AIRCR = 0x05FA0004;
  for(;;);
}
上面的代码,程序在FLASH中跑时可以复位,在RAM中调试不成功,原因可能是板子上的boot比较松,导致RAM启动选择有问题

 

由上面可以看出,IAR下嵌入汇编不是简单的asm("...");,如asm("LDR R0, =0xE000ED0C  ");就会报错

<think>嗯,用户现在想了解STM32软件复位函数的实现方法或使用示例。根据他们提供的引用资料,我需要先整理一下已有的信息。 首先,用户引用了几个关于STM32软件复位的文档。其中提到,在新的STM32外设库中,原来的nvic函数被misc取代,但misc没有直接提供软件复位的功能,所以需要自己编写代码。另外,引用[2]里提到了官方库中的NVIC_GenerateSystemReset函数,但需要配合其他步骤使用。还有引用[4]中的软件定时器代码,可能相关但暂时不用考虑。 用户之前的问题是关于伺服电机驱动芯片的选择,现在STM32软件复位,可能是在开发过程中遇到了需要复位系统的需求,比如在调试或处理异常时。他们可能需要具体的代码示例和步骤,来正确实现软件复位。 接下来,我需要确认用户使用的库版本,因为不同库的函数可能不同。根据引用[1],用户提到新的外设库使用misc代替了nvic,但misc里没有软件复位函数,所以需要自己写。而引用[2]中的代码使用了NVIC_GenerateSystemReset,但指出直接调用可能不够,需要参考Cortex-M3权威指南的说明。 可能的解决方案包括直接调用库函数、使用内核寄存器或者通过看门狗复位。需要比较这些方法的优缺点,并给出示例代码。 还要注意用户可能遇到的常见问题,比如复位不完全、外设未复位等,需要提醒在复位前关闭中断和保存必要的数据。此外,不同系列或库版本可能有差异,需要确认适用的型号和库版本。 最后,生成相关问题,帮助用户进一步了解复位后的处理、不同复位方式的区别以及异常处理中的复位应用。</think>#### STM32软件复位函数实现方法详解 --- ### 一、核心实现原理 STM32软件复位通过修改**应用中断和复位控制寄存器(AIRCR)**实现,需满足: 1. 写入密钥`0x05FA`到AIRCR[31:16] 2. 设置SYSRESETREQ位(AIRCR[2]) $$ \text{AIRCR} = (0x05FA \ll 16) | (1 \ll 2) $$ --- ### 二、标准库实现方法(基于STM32F10x) #### 方法1:直接调用库函数(适用标准外设库) ```c #include "stm32f10x.h" void SoftReset(void) { NVIC_SystemReset(); // 直接调用CMSIS函数 } ``` #### 方法2:寄存器级实现(适用HAL库/无库环境) ```c #define AIRCR_VECTKEY_MASK ((uint32_t)0x05FA0000) void SoftwareReset(void) { // 关闭全局中断 __disable_irq(); // 写入复位命令 SCB->AIRCR = AIRCR_VECTKEY_MASK | (uint32_t)(0x04); // 等待复位生效 for(;;); } ``` --- ### 三、关键实现步骤 1. **中断处理** 复位前需关闭所有中断: ```c __disable_irq(); // 关闭全局中断 __DSB(); // 数据同步屏障 ``` 2. **外设状态处理** 建议复位前执行硬件清理: ```c RCC_DeInit(); // 复位时钟配置 SysTick->CTRL = 0; // 关闭SysTick定时器 ``` 3. **看门狗联合复位**(增强可靠性) ```c IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetReload(0x0FFF); IWDG_ReloadCounter(); ``` --- ### 四、HAL库专用实现(STM32CubeMX生成工程) ```c void HAL_NVIC_SystemReset(void) { __DSB(); // 确保所有内存访问完成 SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk); __DSB(); // 保证指令执行顺序 for(;;) { /* 等待复位 */ } } ``` --- ### 五、常见问题解决方案 | 问题现象 | 解决方法 | |-----------------------|--------------------------------------------------------------------------| | 复位后外设未初始化 | 在`SystemInit()`中增加`RCC_DeInit()`调用 | | 部分寄存器未复位 | 手动复位外设:`RCC_APB1PeriphResetCmd(RCC_APB1Periph_ALL, ENABLE)` | | 复位延迟过长 | 检查看门狗配置,确保`IWDG`/`WWDG`已关闭 | | 复位后程序卡死 | 验证中断向量表偏移量设置`SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET` | --- ### 六、不同库版本对照表 | 库类型 | 函数原型 | 头文件依赖 | |--------------|-----------------------------------|---------------------| | CMSIS | `void NVIC_SystemReset(void)` | core_cm3.h | | Standard Lib | `NVIC_GenerateSystemReset()` | misc.h | | HAL | `HAL_NVIC_SystemReset()` | stm32f1xx_hal_cortex.h | | LL | `LL_mDelay(5); LL_APB1_GRP1_ForceReset()` | stm32f1xx_ll_system.h | --- ### 七、代码验证方法 1. 在复位前写入标记值: ```c __HAL_RTC_BKP_WriteValue(RTC, BKP_DR1, 0x5A5A); ``` 2. 启动时检测标记: ```c if(__HAL_RTC_BKP_ReadValue(RTC, BKP_DR1) == 0x5A5A) { // 软件复位成功 __HAL_RTC_BKP_WriteValue(RTC, BKP_DR1, 0x0000); } ``` --- ### 八、安全注意事项 1. 在调用复位函数前必须保存关键数据到备份寄存器或Flash 2. 避免在中断服务程序中执行复位操作 3. 工业设备建议配合硬件看门狗使用 --- --相关问题-- 1. STM32软件复位后如何保持RTC/BKP寄存器数据? 2. 系统复位与电源复位在寄存器清除范围上有何区别? 3. 如何通过SWD调试器检测软件复位事件? [^1]: STM32F10x软件复位方法技术文档 [^2]: Cortex-M3权威指南第8.4章系统控制块
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值