硬汉嵌入式论坛

 找回密码
 立即注册
查看: 924|回复: 2
收起左侧

[技术讨论] STM32进入待机模式后无法通过RTC闹钟事件唤醒

[复制链接]

1

主题

1

回帖

4

积分

新手上路

积分
4
发表于 2024-11-6 12:03:41 | 显示全部楼层 |阅读模式
int main(void)
{
        OLED_GPIOInit();
        MyRTC_Init();
        AD_Init();
        ESP_Init();
        Store_Init();
        Count_Init();
        Serial_UsartInit();
        Modbus_Init();
        Modbus_TimeIRQInit();
        W25QXX_Init();
        Encoder_Init();

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
        PWR_WakeUpPinCmd(ENABLE);                                                //使能位于PA0的WKUP引脚,WKUP引脚上升沿唤醒待机模式
        uint32_t Alarm = RTC_GetCounter() + 60;//60                        //闹钟为唤醒后当前时间的后60s
        RTC_SetAlarm(Alarm);                                                        //写入闹钟值到RTC的ALR寄存器

        Clean = Count_Data[1];
        Count = Count_Data[2];
        Count++;
       
        OLED_GUIInit();
        Paint_NewImage(Image_BW,OLED_W,OLED_H,0,WHITE);
        OLED_Clear(WHITE);
        Bry_Display();

        mqttconn();
       
        sys_data.error = Modbus_Event();
        if(sys_data.error != 0x05&&sys_data.error != 0x06)//
        {
                switch(sys_data.error)
                {
                        //如果错误码为ERR_CRC:表示未知错误
                        case 0x01:Flag = 0;break;
                        //如果错误码为ERR_CRC:表示地址错误
                        case 0x04:Flag = 3;break;
                        //如果错误码为ERR_ADDR:表示校验错误
                        case 0x03:Flag = 4;break;
                        default:break;           
                }
                if(Count >= 2|Clean == 1)
                {
                        OLED_Clear(WHITE);
                        OLED_GUIInit();
                        LCD_Display();
                        OLED_Display(Image_BW);                               
                        Count = 0;
                        Clean = 0;
                        Count_Data[1] = Clean;
                }
                Count_Data[2] = Count;
                Count_Save();
        }
        else if(sys_data.error == 0x06)
        {
                if(Count >= 2|Clean == 1)
                {
                        OLED_Clear(WHITE);
                        OLED_GUIInit();
                        LCD_Display();
                        OLED_Display(Image_BW);                               
                        Count = 0;
                        Clean = 0;
                        Count_Data[1] = Clean;
                }
                Count_Data[2] = Count;
                Count_Save();
                Flag = 1;
        }
        else
        {
                OLED_Clear(WHITE);
                OLED_GUIInit();
                LCD_Display();
                OLED_Display(Image_BW);
                Count = 0;
                Count_Data[2] = Count;
                Count_Save();
                Flag = 1;
                Light();
        }
        PUB();
        EPD_Sleep();
        Delay_ms(1000);
        PWR_EnterSTANDBYMode();

}

uint16_t MyRTC_Time[] = {2023, 1, 1, 23, 59, 55};        //定义全局的时间数组,数组内容分别为年、月、日、时、分、秒

void MyRTC_SetTime(void);                                //函数声明

/**
  * 函    数:RTC初始化
  * 参    数:无
  * 返 回 值:无
  */

void MyRTC_Init(void)
{
        /*开启时钟*/
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);                //开启PWR的时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP, ENABLE);                //开启BKP的时钟
       
        /*备份寄存器访问使能*/
        PWR_BackupAccessCmd(ENABLE);                                                        //使用PWR开启对备份寄存器的访问
       
        if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)                        //通过写入备份寄存器的标志位,判断RTC是否是第一次配置
                                                                                                                        //if成立则执行第一次的RTC配置
        {
                RCC_LSEConfig(RCC_LSE_ON);                                                        //开启LSE时钟
                while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);        //等待LSE准备就绪
               
                RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);                                //选择RTCCLK来源为LSE
                RCC_RTCCLKCmd(ENABLE);                                                                //RTCCLK使能
               
                RTC_WaitForSynchro();                                                                //等待同步
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
               
                RTC_SetPrescaler(32768 - 1);                                                //设置RTC预分频器,预分频后的计数频率为1Hz
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
               
                MyRTC_SetTime();                                                                        //设置时间,调用此函数,全局数组里时间值刷新到RTC硬件电路
               
                BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);                        //在备份寄存器写入自己规定的标志位,用于判断RTC是不是第一次执行配置
        }
        else                                                                                                        //RTC不是第一次配置
        {
                RTC_WaitForSynchro();                                                                //等待同步
                RTC_WaitForLastTask();                                                                //等待上一次操作完成
        }
}

进入待机模式后除非上拉wake引脚或者下拉NRST引脚唤醒单片机,不然单片机就一直睡着,请解答!!

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115434
QQ
发表于 2024-11-6 14:24:38 | 显示全部楼层
参考这个,他的是RTC可以,WAKEUP不行

STM32F103进入待机模式+WEAKUP和RTC闹钟双重唤醒,WEAKUP无法唤醒
https://www.armbbs.cn/forum.php? ... 2951&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

1

主题

1

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2024-11-7 08:34:51 | 显示全部楼层
eric2013 发表于 2024-11-6 14:24
参考这个,他的是RTC可以,WAKEUP不行

STM32F103进入待机模式+WEAKUP和RTC闹钟双重唤醒,WEAKUP无法唤醒 ...

好的,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-26 07:14 , Processed in 0.259610 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表