STM32G4 RTC时间超过24小时问题记录

单片机型号:STM32G473RB

环境:使用HAL库,RTC使用LSE

问题:使用正点原子的RTC例子代码配置RTC,在读取时间的时候发现小时(RTC_TimeTypeDef的Hours)读取来会超过24小时,并且天数不会自动+1

原因分析:调用HAL_RTC_SetTime的时候DayLightSavingStoreOperation被弃用,见函数说明:

This interface is deprecated. To manage Daylight Saving Time,  please use HAL_RTC_DST_xxx functions

导致夏令时的管理开启。

解决方法:使用HAL_RTC_DST_ClearStoreOperation函数关闭夏令时管理,附上代码片段:

int DrvRTC::init(void){
    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;

    __HAL_RCC_PWR_CLK_ENABLE();//使能电源时钟PWR
    HAL_PWR_EnableBkUpAccess();//取消备份区域写保护
    
    RCC_OscInitStruct.OscillatorType=RCC_OSCILLATORTYPE_LSE;//LSE配置
    RCC_OscInitStruct.PLL.PLLState=RCC_PLL_NONE;
    RCC_OscInitStruct.LSEState=RCC_LSE_ON;                  //RTC使用LSE
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    PeriphClkInitStruct.PeriphClockSelection=RCC_PERIPHCLK_RTC;//外设为RTC
    PeriphClkInitStruct.RTCClockSelection=RCC_RTCCLKSOURCE_LSE;//RTC时钟源为LSE
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);

    __HAL_RCC_RTC_ENABLE();//RTC时钟使能

    memset(&RTC_Handler, 0, sizeof(RTC_Handler));
    RTC_Handler.Instance=RTC;
    RTC_Handler.Init.HourFormat=RTC_HOURFORMAT_24;//RTC设置为24小时格式 
    RTC_Handler.Init.AsynchPrediv=0X7F;           //RTC异步分频系数(1~0X7F)
    RTC_Handler.Init.SynchPrediv=0XFF;            //RTC同步分频系数(0~7FFF)
    RTC_Handler.Init.OutPut=RTC_OUTPUT_DISABLE;
    RTC_Handler.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
    RTC_Handler.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
    if(HAL_RTC_Init(&RTC_Handler)!=HAL_OK)
        return 2;

    HAL_RTC_DST_ClearStoreOperation(&RTC_Handler);
    if(HAL_RTCEx_BKUPRead(&RTC_Handler,RTC_BKP_DR0)!=0X5050)//是否第一次配置
    {
        RTC_Set_Time(23, 59, 46, RTC_HOURFORMAT12_PM);          //设置时间 ,根据实际时间修改
        RTC_Set_Date(22, 5, 4, 4);                             //设置日期
        HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR0, 0X5050);//标记已经初始化过了
    }
    return 0;
}

int DrvRTC::setTime(uint8_t year, uint8_t mon, uint8_t day, uint8_t hour, uint8_t min, uint8_t sec){
    if(RTC_Set_Time(hour, min, sec, RTC_HOURFORMAT12_PM) != HAL_OK)
        return -1;
    if(RTC_Set_Date(year, mon, day, 4) != HAL_OK)
        return -1;
    return 0;
}

int DrvRTC::getTime(uint8_t *year, uint8_t *mon, uint8_t *day, uint8_t *hour, uint8_t *min, uint8_t *sec){
    RTC_DateTypeDef RTC_DateStructure;
    RTC_TimeTypeDef RTC_TimeStructure;
    memset(&RTC_DateStructure, 0, sizeof(RTC_DateTypeDef));
    memset(&RTC_TimeStructure, 0, sizeof(RTC_TimeTypeDef));

    HAL_StatusTypeDef status;
    status = HAL_RTC_GetTime(&RTC_Handler, &RTC_TimeStructure, RTC_FORMAT_BIN);
    status = HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStructure, RTC_FORMAT_BIN);
    if(status != HAL_OK)
        return -1;
    *year = RTC_DateStructure.Year;
    *mon = RTC_DateStructure.Month;
    *day = RTC_DateStructure.Date;
    *hour = RTC_TimeStructure.Hours;
    *min = RTC_TimeStructure.Minutes;
    *sec = RTC_TimeStructure.Seconds;
    return 0;
}

//RTC时间设置
//hour,min,sec:小时,分钟,秒钟
//ampm:@RTC_AM_PM_Definitions:RTC_HOURFORMAT12_AM/RTC_HOURFORMAT12_PM
//返回值:SUCEE(1),成功
//       ERROR(0),进入初始化模式失败 
HAL_StatusTypeDef DrvRTC::RTC_Set_Time(u8 hour,u8 min,u8 sec,u8 ampm)
{
	RTC_TimeTypeDef RTC_TimeStructure;
	
	RTC_TimeStructure.Hours=hour;
	RTC_TimeStructure.Minutes=min;
	RTC_TimeStructure.Seconds=sec;
	RTC_TimeStructure.TimeFormat=ampm;
	RTC_TimeStructure.DayLightSaving=RTC_DAYLIGHTSAVING_NONE;
    RTC_TimeStructure.StoreOperation=RTC_STOREOPERATION_RESET;
	return HAL_RTC_SetTime(&RTC_Handler, &RTC_TimeStructure, RTC_FORMAT_BIN);
}

//RTC日期设置
//year,month,date:年(0~99),月(1~12),日(0~31)
//week:星期(1~7,0,非法!)
//返回值:SUCEE(1),成功
//       ERROR(0),进入初始化模式失败 
HAL_StatusTypeDef DrvRTC::RTC_Set_Date(u8 year,u8 month,u8 date,u8 week)
{
	RTC_DateTypeDef RTC_DateStructure;
    
	RTC_DateStructure.Date=date;
	RTC_DateStructure.Month=month;
	RTC_DateStructure.WeekDay=week;
	RTC_DateStructure.Year=year;
	return HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStructure, RTC_FORMAT_BIN);
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值