/* RTC init function */
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
RTC_AlarmTypeDef sAlarm;
/**Initialize RTC Only
*/
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 310;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
HAL_StatusTypeDef err_code = HAL_RTC_Init(&hrtc);
APP_ERROR_CHECK(err_code);
/**Initialize RTC and set the Time and Date
*/
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
err_code = HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
APP_ERROR_CHECK(err_code);
sDate.WeekDay = RTC_WEEKDAY_MONDAY;
sDate.Month = RTC_MONTH_JUNE;
sDate.Date = 0x1;
sDate.Year = 0x0;
err_code = HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
APP_ERROR_CHECK(err_code);
/**Enable the Alarm A
*/
sAlarm.AlarmTime.Hours = 0;
sAlarm.AlarmTime.Minutes = 0;
sAlarm.AlarmTime.Seconds = 1;
sAlarm.AlarmTime.SubSeconds = 0;
sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
|RTC_ALARMMASK_MINUTES;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
err_code = HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
APP_ERROR_CHECK(err_code);
}
/* USER CODE BEGIN 1 */
void TimeRsset(void)
{
RTC_TimeTypeDef sTime;
sTime.Hours = 0x0;
sTime.Minutes = 0x0;
sTime.Seconds = 0x0;
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
sTime.StoreOperation = RTC_STOREOPERATION_RESET;
HAL_StatusTypeDef err_code = HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
APP_ERROR_CHECK(err_code);
}
void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/* RTC clock enable */
__HAL_RCC_RTC_ENABLE();
/* USER CODE BEGIN RTC_MspInit 1 */
HAL_NVIC_SetPriority(RTC_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(RTC_IRQn);
/* USER CODE END RTC_MspInit 1 */
}
}
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
{
if(rtcHandle->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspDeInit 0 */
/* USER CODE END RTC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
/* RTC interrupt Deinit */
HAL_NVIC_DisableIRQ(RTC_IRQn);
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
TimeRsset();
}
/**
* @brief 校验1HZ RTC频率
*/
void cali_rtc(uint32_t ms)
{
uint32_t t = hrtc.Init.SynchPrediv+1;
t = t * 1000000/ms;
hrtc.Init.SynchPrediv = t;
NRF_LOG_INFO("cali=%d\n",hrtc.Init.SynchPrediv );
HAL_StatusTypeDef err_code = HAL_RTC_Init(&hrtc);
APP_ERROR_CHECK(err_code);
}
typedef enum
{
CALI_RTC_BEGING_TIME,
CALI_RTC_END_TIME,
CALI_RTC_FINISH,
}E_CALI_RTC_PROGRESS;
/**
* @brief This function handles RTC Alarm interrupt request.
* @param None
* @retval None
*/
void RTC_IRQHandler(void)
{
HAL_RTC_AlarmIRQHandler(&hrtc);
s_wakeup_flag |= TICK_FOR_1HZ;
// NRF_LOG_INFO("RTC_IRQHandler");
if(cali_rtc_flag == CALI_RTC_BEGING_TIME)
{
cali_rtc_flag = CALI_RTC_END_TIME;
BSP_tim14_init();
}
else if(cali_rtc_flag==CALI_RTC_END_TIME)
{
cali_rtc_flag = CALI_RTC_FINISH;
uint32_t t = BSP_tim14_deinit();
cali_rtc(t);
// NRF_LOG_INFO("RTC_IRQHandler %d\n",t);
}
首先第一次进入RTC中断启动TIM14,第二次中断进入后停止TIM14,2次中断所花的时间作为参数进行RTC 1秒校准参数
#define CALI_RTC_INTERVAL 6 // 测试6秒钟校验一次,一般1小时以上检验一次
/**
* @brief 每天校验一次
* @note 此函数在1HZ中调用
*/
void start_cali_rtc(void)
{
static uint32_t tick_cnt;
if(++tick_cnt > CALI_RTC_INTERVAL)
{
tick_cnt = 0;
cali_rtc_flag = 0;
}
}
/**
* @brief 1Hz handler
*
*/
static void tick_1hz_handler(void)
{
if((s_wakeup_flag & TICK_FOR_1HZ) == 0)
return;
s_wakeup_flag &= CLEAR_TICK_FOR_1HZ;
//####################################################################################
//---------TODO this to add 1hz event handler-----------
start_cali_rtc();
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
RTT_INIT();
HAL_Init();
SystemClock_Config();
BSP_wdt_init(5000);
delay_init();
MX_RTC_Init();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(s_wakeup_flag) //任务处理模式
{
BSP_wdt_feed();
tick_25hz_handler();
tick_1hz_handler();
}
else // 省电模式
{
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}