1

我正在调整待机模式stm32l100MCU应该每秒唤醒 2 次。为此,我使用RTC 唤醒定时器。但在MCU进入STANDBY模式后,它会立即唤醒。

如果改为待机模式,我使用简单的睡眠模式(__WFI)一切正常。

我的代码在这里

  1. MCU启动后

    一个。保存标志CSR_SBFCSR_WUF,然后清除它们。

    if (PWR->CSR & PWR_CSR_SBF_BIT) {
       // ...
    }
    
    if (PWR->CSR & PWR_CSR_WUF_BIT) {
        // ...
    }
    
    PWR->CR |= PWR_CR_CSBF_BIT|PWR_CR_CWUF_BIT;
    
    //while (PWR->CSR & PWR_CSR_SBF_BIT);
    while (PWR->CSR & PWR_CSR_WUF_BIT);
    

    我注意到CSR_SBF永远不会清除。如果我取消注释字符串,whileMCU停在它的位置。我不明白为什么。

    湾。保存重置源标志,然后清除它们。

    volatile uint32_t csr;
    csr = RCC->CSR;
    
    // .... saving
    
    // clear flags
    RCC->CSR |= RCC_CSR_RMVF_BIT;
    

    MCU从STANDBY唤醒后,所有复位源标志都被清除。似乎没有重置源,但代码从 0x0 执行。

  2. 调整RTC 唤醒定时器

    void rtc_set_wakeup_mode(const uint32_t wakeup_counter)
    {
        RTC_WRITE_PROTECT_DISABLE();
        RTC->CR &= ~RTC_CR_WUTE_BIT;
        while (!(RTC->ISR & RTC_ISR_WUTWF_BIT));
    
        RTC->WUTR = wakeup_counter;
        RTC->CR &= 0xfffffff7;
        RTC->CR |= RTC_WAKEUPCLOCK_RTCCLK_DIV2;
    
        __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
        __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();
    
        RTC->CR |= RTC_CR_WUTIE_BIT|RTC_CR_WUTE_BIT;
        RTC_WRITE_PROTECT_ENABLE();
    }
    
  3. 进入待机模式

    void pwdm_enter_standby_mode(void)
    {
        PWR->CR |= PWR_CR_PDDS_BIT;
        SCB->SCR |= SCB_SCR_SLEEPDEEP_BIT;
    
        __WFI();
    }
    
4

1 回答 1

1

所以,最后我明白了。

这是我自己的启动初始化失败。关键在于:

我注意到 CSR_SBF 永远不会清除。如果我用 while 取消注释字符串,那么 MCU 就会停在它上面。我不明白为什么。

我将使用唤醒/待机标志的代码放在main. 但是这段代码没有做这个操作__HAL_RCC_PWR_CLK_ENABLE();,因为这个操作将在一个振荡器初始化例程中执行。因此,PWR->CSR处于未定义状态并且PWR_CSR_WUF标志永远不会清除。

于 2017-05-18T16:05:32.680 回答