版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29350001/article/details/87179586
复位类型的情况有多种,会导致MCU重启。
因此我们有必要确认一下是何种复位导致的。
一、复位类型
想要查看复位类型可以看一下RCC_GetFlagStatus函数说明
/ **
* @brief检查是否设置了指定的RCC标志。
* @param RCC_FLAG:指定要检查的标志。
*
*对于@b STM32_Connectivity_line_devices,此参数可以是其中之一
*以下值:
* @arg RCC_FLAG_HSIRDY:HSI振荡器时钟就绪
* @arg RCC_FLAG_HSERDY:准备好HSE振荡器时钟
* @arg RCC_FLAG_PLLRDY:PLL时钟就绪
* @arg RCC_FLAG_PLL2RDY:PLL2时钟就绪
* @arg RCC_FLAG_PLL3RDY:PLL3时钟就绪
* @arg RCC_FLAG_LSERDY:LSE振荡器时钟就绪
* @arg RCC_FLAG_LSIRDY:LSI振荡器时钟就绪
* @arg RCC_FLAG_PINRST:引脚复位
* @arg RCC_FLAG_PORRST:POR / PDR重置
* @arg RCC_FLAG_SFTRST:软件重置
* @arg RCC_FLAG_IWDGRST:独立看门狗复位
* @arg RCC_FLAG_WWDGRST:窗口看门狗复位
* @arg RCC_FLAG_LPWRRST:低功耗复位
*
*对于@b other_STM32_devices,此参数可以是以下值之一:
* @arg RCC_FLAG_HSIRDY:HSI振荡器时钟就绪
* @arg RCC_FLAG_HSERDY:准备好HSE振荡器时钟
* @arg RCC_FLAG_PLLRDY:PLL时钟就绪
* @arg RCC_FLAG_LSERDY:LSE振荡器时钟就绪
* @arg RCC_FLAG_LSIRDY:LSI振荡器时钟就绪
* @arg RCC_FLAG_PINRST:引脚复位
* @arg RCC_FLAG_PORRST:POR / PDR重置
* @arg RCC_FLAG_SFTRST:软件重置
* @arg RCC_FLAG_IWDGRST:独立看门狗复位
* @arg RCC_FLAG_WWDGRST:窗口看门狗复位
* @arg RCC_FLAG_LPWRRST:低功耗复位
*
* @retval RCC_FLAG的新状态(SET或RESET)。
* /
二、记录系统重启的方式
printf("\r\nThe RCC_CSR=0x%x\r\n",RCC->CSR);
printf("\r\nThe RCC_FLAG_LPWRRST=0x%x\r\n", RCC_GetFlagStatus(RCC_FLAG_LPWRRST));
printf("\r\nThe RCC_FLAG_PINRST=0x%x\r\n" , RCC_GetFlagStatus(RCC_FLAG_PINRST));
printf("\r\nThe RCC_FLAG_IWDGRST=0x%x\r\n", RCC_GetFlagStatus(RCC_FLAG_IWDGRST));
printf("\r\nThe RCC_FLAG_SFTRST=0x%x\r\n" , RCC_GetFlagStatus(RCC_FLAG_SFTRST));
printf("\r\nThe RCC_FLAG_PORRST=0x%x\r\n" , RCC_GetFlagStatus(RCC_FLAG_PORRST));
RCC_ClearFlag();//清除掉复位源Flag;
无复位打印:
The RCC_CSR=0xc000003
The RCC_FLAG_LPWRRST=0x0
The RCC_FLAG_PINRST=0x1
The RCC_FLAG_IWDGRST=0x0
The RCC_FLAG_SFTRST=0x0
The RCC_FLAG_PORRST=0x1
RCC_ClearFlag
看门狗复位打印:
The RCC_CSR=0x20000003
The RCC_FLAG_LPWRRST=0x0
The RCC_FLAG_PINRST=0x0
The RCC_FLAG_IWDGRST=0x1
The RCC_FLAG_SFTRST=0x0
The RCC_FLAG_PORRST=0x0
RCC_ClearFlag
三、基于库的STM32软件复位(库V3.5)
参看:基于库的STM32软件复位
在官方软件库的 core_cm3.h 文件里直接提供了系统复位的函数 :
/**
* @brief启动系统重置请求。
*
*启动系统重置请求以重置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 */
}
但是Cortex-M3权威指南中提到一个要注意的问题:
从SYSRESETREQ 被置为有效,到复位发生器执行复位命令, 往往会有一个延时。在此延时期间,处理器仍然可以响应中断请求。但我们的本意往往是要 让此次执行到此为止,不要再做任何其它事情了。所以,最好在发出复位请求前,先把 FAULTMASK 置位。所以最好在复位前将FAULTMASK 置位。
在官方软件库的 core_cm3.h 文件里同样也提供了这个函数:
118/5000
/**
* @brief设置Fault Mask值
*
* @param faultMask faultMask值
*
*设置故障屏蔽寄存器
*/
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & 1);
}
最后,通过调用整合的SoftReset函数即可进行软件复位了:
/**
* @brief通过软件重置mcu
*
* @param无
*
* @note使用3.5版本的固件库。
*/
void SoftReset(void)
{
__set_FAULTMASK(1); // 关闭所有中断
NVIC_SystemReset(); // 复位
}
我的复位:
void BSP_CPU_Reset(void)
{
/* system soft reset */
NVIC_SystemReset(); // 函数在core_m3.c中
//*((u32 *)0xE000ED0C) = 0x05fa0004;
while(1);
}