STM32如何获得最后的重置状态

时间:2015-12-10 08:09:09

标签: c arm embedded reset stm32

我正在使用STM32F427而且我想得到最后一次重置的原因。有RCC时钟控制&状态寄存器RCC_CSR有许多复位标志,但我无法获得任何有意义的值。

通过读取该寄存器的值,我只得到0x03,这意味着LSI就绪并且LSI为ON,但是如果我尝试上电,软件复位,低电压等,则没有设置有关复位的标志。我找到了代码片段获得如下所示的重置标志,但所有标志仍为0。

if (RCC_GetFlagStatus(RCC_FLAG_SFTRST)) ...

您对如何获得更好的结果有什么建议吗?在读取这些重置标志之前是否需要一些配置?

谢谢

3 个答案:

答案 0 :(得分:4)

在初始化任何其他外设之前,请在启动后尽快读取RCC_CSR。首先初始化系统时钟是安全的(如果使用ST的库,则在SystemInit()中完成。)

答案 1 :(得分:3)

if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST))...

会告诉您软件是否重置。

然后别忘了

RCC_ClearFlag();

答案 2 :(得分:2)

@floppes建议:

  

在初始化任何其他外设之前,应在启动后尽快读取RCC_CSR。首先初始化系统时钟是安全的(如果使用ST的库,则在SystemInit()中完成)。

现在,要确定确切的重置原因,以下是一项完整的功能可以为您提供帮助。

请注意,所有复位标志都可以在微控制器的“复位和时钟控制器”(RCC)头文件中找到。

例如:“ STM32Cube_FW_F2_V1.7.0 / Drivers / STM32F2xx_HAL_Driver / Inc / stm32f2xx_hal_rcc.h”。

这里是__HAL_RCC_GET_FLAG()宏及其输入的示例说明,这些宏是从“ stm32f2xx_hal_rcc.h”复制并粘贴的。所有 以下功能中使用的重置标志从此列表中获得:

  

/ ** @brief检查是否设置了RCC标志。
    * @param FLAG 指定要检查的标志。
    *此参数可以是下列值之一:
    * @arg RCC_FLAG_HSIRDY:HSI振荡器时钟准备就绪。
    * @arg RCC_FLAG_HSERDY:HSE振荡器时钟准备就绪。
    * @arg RCC_FLAG_PLLRDY:主PLL时钟就绪。
    * @arg RCC_FLAG_PLLI2SRDY:PLLI2S时钟就绪。
    * @arg RCC_FLAG_LSERDY:LSE振荡器时钟准备就绪。
    * @arg RCC_FLAG_LSIRDY:LSI振荡器时钟准备就绪。
    * @arg RCC_FLAG_BORRST:POR / PDR或BOR重置。
    * @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 标志的新状态(真或假)。
    * /
  #define RCC_FLAG_MASK ((uint8_t)0x1FU)
  #define __HAL_RCC_GET_FLAG(__FLAG__) (((((((__FLAG__) >> 5U) == 1U)? RCC->CR :((((__FLAG__) >> 5U) == 2U) ? RCC->BDCR :((((__FLAG__) >> 5U) == 3U)? RCC->CSR :RCC->CIR))) & ((uint32_t)1U << ((__FLAG__) & RCC_FLAG_MASK)))!= 0U)? 1U : 0U)

get_system_reset_cause的功能:

const char * get_system_reset_cause(void)
{
    const char * reset_cause = "TBD";

    if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST))
    {
        reset_cause = "LOW_POWER_RESET";
    }
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_WWDGRST))
    {
        reset_cause = "WINDOW_WATCHDOG_RESET";
    }
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))
    {
        reset_cause = "INDEPENDENT_WATCHDOG_RESET";
    }
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))
    {
        reset_cause = "SOFTWARE_RESET"; // This reset is induced by calling the ARM CMSIS `NVIC_SystemReset()` function!
    }
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST))
    {
        reset_cause = "POWER-ON_RESET (POR) / POWER-DOWN_RESET (PDR)";
    }
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
    {
        reset_cause = "EXTERNAL_RESET_PIN_RESET";
    }
    // Needs to come *after* checking the `RCC_FLAG_PORRST` flag in order to ensure first that the reset cause is 
    // NOT a POR/PDR reset. See note below. 
    else if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
    {
        reset_cause = "BROWNOUT_RESET (BOR)";
    }
    else
    {
        reset_cause = "UNKNOWN";
    }

    // Clear all the reset flags or else they will remain set during future resets until system power is fully removed.
    __HAL_RCC_CLEAR_RESET_FLAGS();

    return reset_cause; 
}

// Note: any of the STM32 Hardware Abstraction Layer (HAL) Reset and Clock Controller (RCC) header
// files, such as "STM32Cube_FW_F7_V1.12.0/Drivers/STM32F7xx_HAL_Driver/Inc/stm32f7xx_hal_rcc.h",
// "STM32Cube_FW_F2_V1.7.0/Drivers/STM32F2xx_HAL_Driver/Inc/stm32f2xx_hal_rcc.h", etc., indicate that the 
// brownout flag, `RCC_FLAG_BORRST`, will be set in the event of a "POR/PDR or BOR reset". This means that a 
// Power-On Reset (POR), Power-Down Reset (PDR), OR Brownout Reset (BOR) will trip this flag. See the 
// doxygen just above their definition for the `__HAL_RCC_GET_FLAG()` macro to see this:
// "@arg RCC_FLAG_BORRST: POR/PDR or BOR reset." <== indicates the Brownout Reset flag will *also* be set in 
// the event of a POR/PDR. 
// Therefore, you must check the Brownout Reset flag, `RCC_FLAG_BORRST`, *after* first checking the 
// `RCC_FLAG_PORRST` flag in order to ensure first that the reset cause is NOT a POR/PDR reset.

当然,如果您打算不仅仅打印输出,而将上面函数的返回值转换为枚举而不是C字符串,则将其转换为枚举。