STM32 每 10 秒从待机模式唤醒

Posted

技术标签:

【中文标题】STM32 每 10 秒从待机模式唤醒【英文标题】:STM32 wake up from standby mode every 10 seconds 【发布时间】:2021-11-04 19:23:14 【问题描述】:

我曾经在 arduino 上有一个项目,使用 atmega328p 芯片,代码如下:

// used for deep sleep
#include <avr/wdt.h>

static void go_to_sleep_and_power_down_and_wake_up_again_in_2_seconds()

    // wake up again in 4 seconds
    wdt_enable(WDTO_4S);

    // go to deep sleep    
    
        // BIG difference when in sleep
        // Diable ADC (analog to digital converter)
        ADCSRA &= ~(1 << 7);

        SMCR |= (1 << 2); // power down mode
        SMCR |= 1;        // enable sleep;

        // BOD DISABLE (big difference when in sleep only)
        MCUCR |= (3 << 5);                      // set both BODS and BODSE at the same time
        MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); // then set the BODS bit and clear the BOSE bit at the same time

        __asm__ __volatile__("sleep");
    

    // this line should not execute


void setup()

    // init code...

    // read sensor value
    // pseudo code:
    if(valueReadFromSensor == 0)
    
        turnOnAlarm();
        return;
    

    go_to_sleep_and_power_down_and_wake_up_again_in_2_seconds()


void loop()
   // not used

代码非常简单,一旦唤醒,它就会从传感器读取数据并重新进入睡眠状态。 2 秒后,它再次唤醒并重复相同的过程。

例如,我如何在 bluepill 上的 stm32 上做同样的事情?我已经设法使用此功能HAL_PWR_EnterSTANDBYMode(); 进入待机模式。但是,例如,我怎样才能在 2 秒内再次唤醒?

编辑

我试过这个来源:

使用旧版本的 stm32 cube ide 和不同的板。我尝试了执行相同步骤的视频,并且一些定义使代码无法编译。 https://www.youtube.com/watch?v=zQ1sT9fjd3E

没有代码 https://www.stm32duino.com/viewtopic.php?t=922

没有代码 STM32 wake up from standby by RTC

我没有使用 freeRtos https://electronics.stackexchange.com/a/562120/56969

【问题讨论】:

可能有帮助的讨论:stm32duino.com/viewtopic.php?t=922 我不确定是否存在 1:1 匹配的能力,但我对 TI MCU 所做的是在进入程序循环之前保存当前的活动电源状态。在程序循环结束时,我让 MCU 进入睡眠状态。为了触发唤醒,我设置了一个在 10 秒后触发的中断,并在中断处理程序中将 MCU 恢复到之前的活动电源状态,这会强制程序循环再次执行(在程序循环结束时再次进入睡眠状态)。这是一种常见的策略,它允许保持 ISR 函数很小,本质上只是设置标志来触发主循环中的处理。 这看起来像你想要的 STM32 wake up from standby by RTC -- 或者关闭。 【参考方案1】:

终于找到了使用 IWDG 的解决方案。此代码适用于使用 arduino 框架的 PlatformIO

#include <Arduino.h>
#include <IWatchdog.h> // <----------- needed

void setup(void)

    // start serial
    Serial.begin(115200);

    // set pins
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(A0, INPUT_PULLUP); // connect button to this pin to simulate a sensor for purposes of this example.

    // flash led to indicate board is starting
    Serial.println("starting...");
    digitalWrite(LED_BUILTIN, HIGH);
    delay(250);
    digitalWrite(LED_BUILTIN, LOW);

    // read value from sensor. In this case just tell if button is presses
    // connect one side of button to pin A0 and the other to ground
    int sensorValue = digitalRead(A0);

    // if button is not pressed
    if (sensorValue == 1)
    
        // go to sleep and try again in 4 seconds
        Serial.println("going to sleep and trying again in 4 seconds...");

        // Initialize the IWDG with 4 seconds timeout.
        // This would cause a CPU reset if the IWDG timer
        // is not reloaded in approximately 4 seconds.
        IWatchdog.begin(4000000);

        // go to sleep
        HAL_PWR_EnterSTANDBYMode();

        Serial.println("This line should NOT print!!!!!");
    


    // at this point it means the button is was pressed
    Serial.println("staying awake!");
    // stay awake flashing led
    while (true)
    
        digitalWrite(LED_BUILTIN, HIGH);
        delay(50);
        digitalWrite(LED_BUILTIN, LOW);
        delay(50);
    


void loop()


本视频解释了如何使用 stm32CubeIDE 实现相同功能:https://www.youtube.com/watch?v=AelNsnpfbcM&t=472s

【讨论】:

以上是关于STM32 每 10 秒从待机模式唤醒的主要内容,如果未能解决你的问题,请参考以下文章

stm32在进入standby状态如何唤醒,求个简单参考代码

stm32待机唤醒原理

STM32F103低功耗与IO唤醒

STM32的待机与唤醒试验

STM32Cube STM32L053配置RTC WAKEUP中断唤醒

STM32Cube STM32L053配置RTC WAKEUP中断唤醒