此工程没有读取亚秒值。
若想让时钟断电后持续计时,则不要使能RTC_Config() 函数中的后备域访问。
/**
******************************************************************************
* @file bsp_rtc.h
* @author Waao
* @version V1.0.0
* @date 17-Feb-2019
* @brief This file contains some board support package's definition for the RTC.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#ifndef __BSP_RTC_H_
#define __BSP_RTC_H_
#include "stm32f4xx_rtc.h"
#include
#include
//============== Date values =================
#define YEAR 19
#define MONTH 2 // RTC_Month_February
#define DATE 19
#define WEEKDAY 2 // RTC_Weekday_Tuesday
//============================================
//============== Time values =================
#define HOURS 0x00
#define MINUTES 0x00
#define SECONDS 0x00
//============================================
void RTC_Config(void);
void RTC_DateConfig(void);
void RTC_TimeConfig(void);
#endif
/**
******************************************************************************
* @file bsp_rtc.c
* @author Waao
* @version V1.0.0
* @date 17-Feb-2019
* @brief This file contains some board support package's functions for the RTC.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#include "bsp_rtc.h"
/**
* @brief Initialize the RTC.
* @param None
* @retval None
*/
void RTC_Config(void)
{
RTC_InitTypeDef RTC_InitStructure;
//RCC_APB1PeriphClockLPModeCmd(RCC_APB1Periph_PWR, ENABLE);
/* If we ENABLE the Backup Access, we can write the RTC, RCC_BDCR, PWR_CSR register.
* So that we can modify the time values again. But we cannot modify the time values
* if we disable that, the time values will keep count forever even through we power
* down the device.
* If you want to make it counter run forever, you can DISABLE that.
*/
PWR_BackupAccessCmd(ENABLE);
RCC_LSEConfig(RCC_LSE_ON);
while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKCmd(ENABLE);
RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
RTC_InitStructure.RTC_AsynchPrediv = 127;
RTC_InitStructure.RTC_SynchPrediv = 255;
RTC_Init(&RTC_InitStructure);
}
/**
* @brief Configure the now date.
* @param None
* @retval None
*/
void RTC_DateConfig(void)
{
RTC_DateTypeDef SetDate_InitStructure;
// SetDate_InitStructure
SetDate_InitStructure.RTC_Year = YEAR;
SetDate_InitStructure.RTC_Month =MONTH;
SetDate_InitStructure.RTC_WeekDay = WEEKDAY;
SetDate_InitStructure.RTC_Date = DATE;
RTC_SetDate(RTC_Format_BIN, &SetDate_InitStructure);
}
/**
* @brief Configure the now time.
* @param None
* @retval None
*/
void RTC_TimeConfig(void)
{
RTC_TimeTypeDef SetTime_InitStructure;
// SetTime_InitStructure
SetTime_InitStructure.RTC_H12 = RTC_H12_PM;
SetTime_InitStructure.RTC_Hours = HOURS;
SetTime_InitStructure.RTC_Minutes = MINUTES;
SetTime_InitStructure.RTC_Seconds = SECONDS;
RTC_SetTime(RTC_Format_BIN, &SetTime_InitStructure);
}
/**
******************************************************************************
* @file main.c
* @author Waao
* @version V1.0.0
* @date 19-Feb-2019
* @brief RTC operation.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#include
#include
#include
/**
1. @brief Main
2. @param None
3. @retval None
*/
int main(void)
{
RTC_DateTypeDef GetDate_InitStructure;
RTC_TimeTypeDef GetTime_InitStructure;
// We can use the print function
USART_GPIO_Config();
USART1_Config();
// We can use the Delay function
SysTick_Init();
RTC_Config();
RTC_DateConfig();
RTC_TimeConfig();
while(1)
{
RTC_GetDate(RTC_Format_BIN, &GetDate_InitStructure);
printf("\nToday is 20%d-%d-%d, and the WeekDay is %d", GetDate_InitStructure.RTC_Year, GetDate_InitStructure.RTC_Month, GetDate_InitStructure.RTC_Date, GetDate_InitStructure.RTC_WeekDay);
RTC_GetTime(RTC_Format_BIN, &GetTime_InitStructure);
printf("\nThe real time is %0.2d:%0.2d:%0.2d", GetTime_InitStructure.RTC_Hours, GetTime_InitStructure.RTC_Minutes, GetTime_InitStructure.RTC_Seconds);
printf("\n");
Delay(100000);
}
}
闹钟编程指南:
//================= Alarm ====================
#define RTC_Alarm_Channel RTC_Alarm_IRQn
#define RTC_Alarm_EXTI_LINE EXTI_Line17
#define Specified_RTC_Alarm RTC_Alarm_A
#define Alarm_HOURS 0
#define Alarm_MINUTES 0
#define Alarm_SECONDS 1
//============================================
/**
* @brief Configure the Alarm.
* @param None
* @retval None
*/
void RTC_AlarmConfig(void)
{
RTC_AlarmTypeDef Alarm_InitStructure;
NVIC_Config();
EXTI_Config();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
RTC_AlarmCmd(Specified_RTC_Alarm, DISABLE);
// Alarm_InitStructure
Alarm_InitStructure.RTC_AlarmTime.RTC_H12 = RTC_H12_PM;
Alarm_InitStructure.RTC_AlarmTime.RTC_Hours = Alarm_HOURS;
Alarm_InitStructure.RTC_AlarmTime.RTC_Minutes = Alarm_MINUTES;
Alarm_InitStructure.RTC_AlarmTime.RTC_Seconds = Alarm_SECONDS;
/* You can dicide which field is invalid.
* For example, if you configure the RTC_AlarmMask_DateWeekDay is invalid, the alarm will
* trigger each day.
*/
Alarm_InitStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay;
Alarm_InitStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_WeekDay;
Alarm_InitStructure.RTC_AlarmDateWeekDay = 19;
RTC_SetAlarm(RTC_Format_BIN, Specified_RTC_Alarm, &Alarm_InitStructure);
RTC_ITConfig(RTC_IT_ALRA, ENABLE);
RTC_AlarmCmd(Specified_RTC_Alarm, ENABLE);
RTC_ClearFlag(RTC_FLAG_ALRAF);
EXTI_ClearITPendingBit(EXTI_Line17);
}
/**
* @brief Configure the NVIC
* @param None
* @retval None
*/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
//Configure the NVIC to prioritygroup1
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
//Configure the preemption priority to 1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//Configure the subpriority to 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//Enable the interrupt channel
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_Channel;
NVIC_Init(&NVIC_InitStructure);
}
/**
* @brief Configure the EXTI
* @param None
* @retval None
*/
void EXTI_Config(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = RTC_Alarm_EXTI_LINE;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
/**
* @brief This function handles RTC Alarm.
* @param None
* @retval None
*/
void RTC_Alarm_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_ALRA) == SET)
{
LED1_ON;
printf("\nAlarm");
}
RTC_ClearITPendingBit(RTC_IT_ALRA);
EXTI_ClearITPendingBit(EXTI_Line17);
}
/**
******************************************************************************
* @file main.c
* @author Waao
* @version V1.0.0
* @date 19-Feb-2019
* @brief RTC operation.
*
******************************************************************************
* @attention
*
* None
*
******************************************************************************
*/
#include
#include
#include
#include
#include
#include
/**
* @brief Main
* @param None
* @retval None
*/
int main(void)
{
RTC_DateTypeDef GetDate_InitStructure;
RTC_TimeTypeDef GetTime_InitStructure;
// We can use the print function
USART_GPIO_Config();
USART1_Config();
// We can use the Delay function
SysTick_Init();
KEY_GPIO_Config();
LED_GPIO_Config();
RTC_Config();
RTC_DateConfig();
RTC_TimeConfig();
RTC_AlarmConfig();
while(1)
{
RTC_GetDate(RTC_Format_BIN, &GetDate_InitStructure);
printf("\nToday is 20%d-%d-%d, and the WeekDay is %d", GetDate_InitStructure.RTC_Year, GetDate_InitStructure.RTC_Month, GetDate_InitStructure.RTC_Date, GetDate_InitStructure.RTC_WeekDay);
RTC_GetTime(RTC_Format_BIN, &GetTime_InitStructure);
printf("\nThe real time is %0.2d:%0.2d:%0.2d", GetTime_InitStructure.RTC_Hours, GetTime_InitStructure.RTC_Minutes, GetTime_InitStructure.RTC_Seconds);
printf("\n");
// if(RTC_GetFlagStatus(RTC_FLAG_ALRAF) == SET)
// {
// LED1_ON;
// }
Delay(100000);
LED1_OFF;
}
}
自动唤醒编程指南:
//================== WKUP ====================
#define RTC_WKUP_Channel RTC_WKUP_IRQn
#define RTC_WKUP_EXTI_LINE EXTI_Line22
#define RTC_WKUP_CounterValues 3
//============================================
配置完中断参数后顺手清除中断位绝对是个好习惯,尤其是在和硬件打交道时。否则在某种特定情况下可能会出现一些程序上根本找不到的问题…
在此程序中,有一次我给单片机睡眠了,结果后面多次烧录原来的程序后,唤醒中断函数都不执行,直到一次我在配置完中断后清除了中断标志位…
/**
* @brief Configure the WKUP.
* @param None
* @retval None
*/
void RTC_WKUPConfig(void)
{
NVIC_Config();
EXTI_Config();
// CK_SPRE is the 1Hz system clock generally.
RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);
RTC_SetWakeUpCounter(RTC_WKUP_CounterValues);
RTC_WakeUpCmd(ENABLE);
RTC_ITConfig(RTC_IT_WUT, ENABLE);
// Clear the IT bits when we finished the configuring is a good habit.
RTC_ClearITPendingBit(RTC_IT_WUT);
}
/**
* @brief This function handles RTC WKUP.
* @param None
* @retval None
*/
void RTC_WKUP_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_WUT) != RESET)
{
printf("\nI am wake up!!");
RTC_ClearITPendingBit(RTC_IT_WUT);
EXTI_ClearITPendingBit(RTC_WKUP_EXTI_LINE);
}
}
我们也可以配置睡眠停止等状态下的自动唤醒,但要注意,从停止模式中唤醒后需要将系统时钟重新配置为HSE,否则会有部分的外设由于时钟配置不正确而产生异常