STM32开发 -- 复位类型判断

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
}

猜你喜欢

转载自blog.csdn.net/qq_29350001/article/details/87179586