OpenEdv-开源电子网

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

stm32f411使用待机模式+RTC闹钟事件,闹钟每秒都会被重设

[复制链接]

1

主题

2

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2022-4-16
在线时间
5 小时
发表于 2024-7-4 17:58:17 | 显示全部楼层 |阅读模式
5金钱
main.c

#include "stm32f4xx.h"
#include "delay.h"
#include "MyRTC.h"
#include "LED.h"


uint8_t TIME[6];
uint8_t Alarm;
uint8_t Status;
int main(void)
{
        LED_Init();
        MyRTC_Init();//初始化RTC时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR
        MyRTC_SetAlarm();//设置闹钟
        while(1)
        {
                MyRTC_GetCurrentTimeAndDate(TIME);// 读取并显示当前时间和日期
                Alarm = MyRTC_GetAlarm();//获取闹钟的时间
                Status = RTC_GetFlagStatus(RTC_FLAG_ALRAF);//查看闹钟标志位
                PWR_EnterSTANDBYMode();//待机模式
        }
}


MyRTC.c

#include "stm32f4xx.h"                  // Device header
#include "MyRTC.h"
#include "LED.h"


void MyRTC_Init(void)
{
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR
        PWR_BackupAccessCmd(ENABLE); //使能后备寄存器访问
      
        RCC_LSEConfig(RCC_LSE_ON);//开启外部低速时钟
        while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) != SET);//等待外部低速时钟准备完成
      
        RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择RTC的时钟源
        RCC_RTCCLKCmd(ENABLE);
      
        RTC_WaitForSynchro();
      


        if(RTC_ReadBackupRegister(RTC_BKP_DR1) != 0xA1A1)//通过读取BKP寄存器可防止重复的初始化
        {                                                                                                //,在主电源和备用电源都断电后重新上电,就会重新初始化RTC
                RTC_InitTypeDef RTC_InitStructure;
                RTC_InitStructure.RTC_AsynchPrediv = 127; // 异步预分频器值,设置 RTC_PRER 寄存器的 PREDIV_A 相关位
                RTC_InitStructure.RTC_SynchPrediv = 255;  // 同步预分频器值,设置 RTC_PRER 寄存器的 PREDIV_S 相关位
                //为了得到1 Hz的RTC时钟,通常设置异步预分频器为127,同步预分频器为255。
                RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//设置 RTC 的时间格式,
                RTC_Init(&RTC_InitStructure);
                //RTC_Init不需要调用RTC_EnterInitMode。底层会调用。但是设置具体的时间和日期时,仍需手动调用初始化模式。
                MyRTC_SetTime(12, 34, 56);// 设置时间为12:34:56
                MyRTC_SetDate(24, 6, 30, 7);// 设置日期为2024-06-30(星期日)
                RTC_WriteBackupRegister(RTC_BKP_DR1,0xA1A1);
        }
}


void MyRTC_SetTime(uint8_t hour, uint8_t minute, uint8_t second)
{
        RTC_TimeTypeDef RTC_TimeStructure;
        RTC_TimeStructure.RTC_H12 = RTC_H12_AM;
        RTC_TimeStructure.RTC_Hours = hour;
        RTC_TimeStructure.RTC_Minutes = minute;
        RTC_TimeStructure.RTC_Seconds = second;
    RTC_EnterInitMode();// 进入初始化模式
        RTC_SetTime(RTC_Format_BIN,&RTC_TimeStructure);
        RTC_ExitInitMode();// 退出初始化模式
}


void MyRTC_SetDate(uint8_t year, uint8_t month, uint8_t day, uint8_t weekday)
{
        RTC_DateTypeDef RTC_DateStructure;
        RTC_DateStructure.RTC_Date = day;
        RTC_DateStructure.RTC_Month = month;
        RTC_DateStructure.RTC_WeekDay = weekday;
        RTC_DateStructure.RTC_Year = year;
    RTC_EnterInitMode();
        RTC_SetDate(RTC_Format_BIN,&RTC_DateStructure);
        RTC_ExitInitMode();
}


void MyRTC_GetCurrentTimeAndDate(uint8_t *TIME)
{
    RTC_TimeTypeDef RTC_TimeStructure;
    RTC_DateTypeDef RTC_DateStructure;


    RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure); // 读取当前时间
    RTC_GetDate(RTC_Format_BIN, &RTC_DateStructure);// 读取当前日期
      
        TIME[0] = RTC_DateStructure.RTC_Year;
        TIME[1] = RTC_DateStructure.RTC_Month;
        TIME[2] = RTC_DateStructure.RTC_Date;
        TIME[3] = RTC_TimeStructure.RTC_Hours;
        TIME[4] = RTC_TimeStructure.RTC_Minutes;
        TIME[5] = RTC_TimeStructure.RTC_Seconds;
}


void MyRTC_SetAlarm(void)
{      
        RTC_TimeTypeDef RTC_TimeStructure;
        RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
      
        RTC_AlarmCmd(RTC_Alarm_A,DISABLE);
        RTC_AlarmTypeDef RTC_AlarmStructure;
        RTC_AlarmStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_AM;
        RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours = 0;
        RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = 0;
        RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = (RTC_TimeStructure.RTC_Seconds+10)%60;
        RTC_AlarmStructure.RTC_AlarmDateWeekDay = 0x31; // 任意日期
    RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
        RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;//使用掩码忽略日期、小时和分钟部分,只关注秒部分。
        RTC_SetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStructure);
        RTC_AlarmCmd(RTC_Alarm_A,ENABLE);
      
        //RTC_ClearFlag(RTC_FLAG_ALRAF);// 清除闹钟标志
        RTC_ITConfig(RTC_IT_ALRA, ENABLE);// 使能闹钟中断


        EXTI_InitTypeDef EXTI_InitStructure;
        EXTI_InitStructure.EXTI_Line = EXTI_Line17;                     // Line 17 connected to RTC Alarm
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;          // Trigger on rising edge
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);


        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;    // Set a low priority
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}


uint8_t MyRTC_GetAlarm(void)
{      
        RTC_AlarmTypeDef RTC_AlarmStructure;
        RTC_GetAlarm(RTC_Format_BIN,RTC_Alarm_A,&RTC_AlarmStructure);
        return RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds;
}


void RTC_Alarm_IRQHandler(void)
{
        if (RTC_GetITStatus(RTC_IT_ALRA) != RESET)
        {
        RTC_ClearITPendingBit(RTC_IT_ALRA);
        EXTI_ClearITPendingBit(EXTI_Line17); // 清除EXTI线路17(连接到RTC闹钟)的中断挂起位
        LED1_Turn();
        }
}

[td]

[/td]

待机模式+实时时钟.zip

607.07 KB, 下载次数: 1

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

使用道具 举报

1

主题

2

帖子

0

精华

新手上路

积分
20
金钱
20
注册时间
2022-4-16
在线时间
5 小时
 楼主| 发表于 2024-7-4 17:59:06 | 显示全部楼层
想要设一个10秒后的闹钟来唤醒设备,比如时间是10秒的时候就设一个20秒的闹钟,然后闹钟响了以后会重设一次30秒的闹钟,等待十秒后再次响起。结果在Keil调试器中看见闹钟的数值跟着我时钟的秒数一起,每秒都在重设,比如10秒的时候,闹钟就是20,但是时钟来到11秒的时候,闹钟就被设置成了21.
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4588
金钱
4588
注册时间
2015-1-10
在线时间
574 小时
发表于 2024-7-8 10:13:32 | 显示全部楼层
standby模式约等于复位
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 19:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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