Не работает дежурный режим в stm32l100

Я настраиваю stm32l100 на режим STANDBY. MCU должен просыпаться 2 раза в секунду. Для этого я использую таймер пробуждения RTC. Но после того, как MCU перешел в режим STANDBY, он сразу же просыпается.

Если вместо режима STANDBY я использую простой спящий режим (__WFI), все работает нормально.

Мой код здесь

  1. После запуска MCU

    а. сохраняет флаги CSR_SBF и CSR_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 никогда не очищается. Если я раскомментирую строку с помощью while, тогда MCU остановится на этом месте. Не понимаю почему.

    б. сохраняет сброс исходных флагов, после чего их очищает.

    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. Войдите в режим STANDBY.

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

person Serge Maslyakov    schedule 18.05.2017    source источник
comment
Можете ли вы посмотреть на байты опций и убедиться, что переход в режим ожидания не сбрасывает MCU?   -  person phodina    schedule 18.05.2017
comment
Я не понимаю, что такое байты опций? После того, как MCU вернется из режима ожидания, значение RCC->CSR будет 0x00420003.   -  person Serge Maslyakov    schedule 18.05.2017
comment
В RCC- ›CSR нет источника сброса. Байты опций являются специальным разделом FLASH и позволяют указать некоторые функции для STM32. Вы можете запрограммировать их из утилиты STLink.   -  person phodina    schedule 18.05.2017
comment
@phodina Значение байта опции 'USER' по адресу 0x1FF80004 равно 0xFF870078   -  person Serge Maslyakov    schedule 18.05.2017
comment
@phodina MCU остается в режиме ожидания, если я не настраиваю таймер пробуждения. Это связано с таймером пробуждения.   -  person Serge Maslyakov    schedule 18.05.2017


Ответы (1)


Итак, наконец-то я понял.

Это была моя собственная неудача с инициализацией запуска. Ключ был в этом:

Я заметил, что CSR_SBF никогда не очищается. Если я раскомментирую строку с помощью while, MCU остановится на этом месте. Не понимаю почему.

Я поместил код, работающий с флагами пробуждения / ожидания в начале main. Но этот код не выполнял эту операцию __HAL_RCC_PWR_CLK_ENABLE();, потому что эта операция будет выполняться в подпрограмме инициализации осциллятора. Итак, PWR->CSR находился в неопределенном состоянии, а флаг PWR_CSR_WUF никогда не сбрасывается.

person Serge Maslyakov    schedule 18.05.2017