| 
 
新手上路 
 
	积分20金钱20 注册时间2022-4-16在线时间5 小时 | 
 
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]
 | 
 
 | 
 |