OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4313|回复: 1

STM32F1待机唤醒,无论是按键或者RTC都唤醒不了

[复制链接]

2

主题

5

帖子

0

精华

新手入门

积分
19
金钱
19
注册时间
2022-9-9
在线时间
8 小时
发表于 2022-9-19 15:32:20 | 显示全部楼层 |阅读模式
1金钱
#include "wkup.h"

static u8 t = 0 ;
void WKUP_Init(void) {
   
    GPIO_InitTypeDef    GPIO_InitStructure;
    EXTI_InitTypeDef    EXTI_InitStructure;
    NVIC_InitTypeDef    NVIC_InitStructure;
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);
   
    //POWER_KEY
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;      
    GPIO_Init(GPIOA, &GPIO_InitStructure);
   
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);        //配置外部中断与GPIOA连接
   
    EXTI_InitStructure.EXTI_Line = EXTI_Line0;
   
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        //中断模式
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;        //下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
   
    NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
   

}

void EXTI0_IRQHandler(void){
        
    EXTI_ClearITPendingBit(EXTI_Line0);        //清除外部中断线0上的中断标志位
   
    if(POWER_CHECK()) {
        
        LED3_9 =! LED3_9;
        RCC_APB2PeriphResetCmd(0X01FC,DISABLE);    //复位所有IO口
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
        PWR_WakeUpPinCmd(ENABLE);        //使能WKUP唤醒引脚
        PWR_EnterSTANDBYMode();        //进入待机模式
    }
}



u8 POWER_CHECK(void) {
   
    while(1) {
        
        if(power_check) {
            
            return 0;
        }
        else {
            
            t++;

            delay_ms(30);
            
            if(t >= 100) {
               
                t = 0;
                return 1;
            }               
        }
    }
}



#include "rtc.h"

u8 RTC_Init(void) {
   
    u8 temp = 0;
   
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP,ENABLE);
   
    PWR_BackupAccessCmd(ENABLE);    //使能对备份寄存器的操作
    //第一次初始化
    if(BKP_ReadBackupRegister(BKP_DR1) != 0x2020) {
        
        BKP_DeInit();        //复位备份寄存器
        
        RCC_LSEConfig(RCC_LSE_ON);        //打开外部低速晶振
        
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET) {
            
            temp++;
            
            delay_ms(10);            
        }
        //配置超时,RTC时钟初始化失败
        if(temp > 250) {
            
            return 1;
        }
        
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);        //使用外部低速晶振,32.768khz
        
        RCC_RTCCLKCmd(ENABLE);
        
        RTC_WaitForLastTask();        //等待上一次配置
            
        RTC_WaitForSynchro();        //等待同步
            
        RTC_ITConfig(RTC_IT_SEC | RTC_IT_ALR,ENABLE);        //配置使能秒,闹钟中断
        
        RTC_WaitForLastTask();
        
        RTC_EnterConfigMode();        //进入配置模式
        
        RTC_SetPrescaler(32767);    //RTC时钟分频函数,fTR_CLK = fRTCCLK / (PRL[19:0]+1),当前: 1HZ = 32768 / (32767+1)
        
        RTC_WaitForLastTask();
   
        RTC_SetCounter(0);        //设置计数初始值
        
        RTC_WaitForLastTask();
        
        RTC_SetAlarm(5);        //设置闹钟阈值
        
        RTC_WaitForLastTask();
        
        RTC_ExitConfigMode();    //退出配置模式
        
        BKP_WriteBackupRegister(BKP_DR1,0x2020);        //往备份寄存器写入4040,用来记录判断是否已经初始化
        
        //PWR_BackupAccessCmd(DISABLE);        //失能对备份寄存器的写操作
    }
    //第二次初始化
    else {
        
        RTC_WaitForSynchro();
        
        RTC_ITConfig(RTC_IT_SEC | RTC_IT_ALR,ENABLE);
        
        RTC_WaitForLastTask();
        
        //PWR_BackupAccessCmd(DISABLE);    //失能对备份寄存器的写操作
    }
   
    RTC_IT_NVIC();
   
    return 0;
}

void RTC_IT_NVIC(void) {
        
    NVIC_InitTypeDef    NVIC_InitStructre;
   
    NVIC_InitStructre.NVIC_IRQChannel = RTC_IRQn;
    NVIC_InitStructre.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructre.NVIC_IRQChannelSubPriority = 0x02;
    NVIC_InitStructre.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructre);   
}

void RTC_IRQHandler(void) {
   
    if(RTC_GetITStatus(RTC_FLAG_SEC) != RESET) {
        
        //LED2_5 =! LED2_5;
    }
   
    if(RTC_GetITStatus(RTC_IT_ALR) != RESET) {
        
        RTC_ClearITPendingBit(RTC_IT_ALR);
        
        RTC_SetAlarm(RTC_GetCounter()+10);
        
        LED2_5 =! LED2_5;
    }
   
    RTC_ClearITPendingBit(RTC_IT_SEC | RTC_IT_OW);        //清除秒,溢出中断的中断标志位
        
    RTC_WaitForLastTask();
}






按键外部中断和RTC都用LED测试过,能够正常触发,但是就是进入待机后,唤不醒


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
145
金钱
145
注册时间
2021-2-22
在线时间
25 小时
发表于 2023-9-19 10:27:55 | 显示全部楼层
楼主待机唤醒不了的问题解决了吗,按键待机唤醒是需要PA0的上升沿来触发的,进待机前要配置PA0的WAKEUP时钟等
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 23:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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