RT-Thread Studio学习笔记之RTC——解决复位日期不保存问题

前言

最近使用RT-Thread Studio开发工程时,发现STM32F103系列芯片的RTC功能存在一些缺陷,和同学查找了一些资料后得以解决,希望以此博客作为记录以便温故知新。

RTC简介

RTC(Real-Time Clock)译为实时时钟,因为它一般是集成电路,故也称为时钟芯片。它能提供精确的实时时间,可以用于产生年、月、日、时、分、秒等信息。

在RT-Thread Studio中开启RTC

首先,我们在drivers目录中打开board.h源文件,找到RTC相关内容如下:
在这里插入图片描述
按照如上提示,通过以下三个步骤打开RTC。

1.打开RTC驱动

双击RT-Thread Setting,进入界面后点击更多配置。
在这里插入图片描述
接着找到RTC驱动并勾选。
在这里插入图片描述

2.打开RTC的宏定义

board.h文件中,去掉RTC宏定义的注释。
在这里插入图片描述

3.使能RTC

在drivers目录下的stm32xxxhal_config.h文件中去掉如下代码的注释。在这里插入图片描述

4.下载验证

编译工程后下载到开发板,参照官方开发手册进行验证。

官方文档
首先,使用date命令查询当前时间,随后按照格式输入当前时间,可以看到设置成功。

然而,当按下系统复位按键,系统重启后再使用date命令查询时间时,可以看到时分秒均正常保存,但是日期却并不正确。
在这里插入图片描述

解决复位不保存年月日问题

查找资料后,发现是因为STM32F1系列芯片不支持日历功能,但好在可以通过修改程序进行修正。

在RT-Thread社区看到一篇帖子,里面的方法解决了这个问题。原帖地址

操作步骤

1.打开drivers目录下的drv_rtc.c文件
2.修改get_rtc_timestamp()函数如下

static time_t get_rtc_timestamp(void)
{
#if 0
    RTC_TimeTypeDef RTC_TimeStruct = {0};
    RTC_DateTypeDef RTC_DateStruct = {0};
    struct tm tm_new;
    

    HAL_RTC_GetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN);
    HAL_RTC_GetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN);

    tm_new.tm_sec  = RTC_TimeStruct.Seconds;
    tm_new.tm_min  = RTC_TimeStruct.Minutes;
    tm_new.tm_hour = RTC_TimeStruct.Hours;
    tm_new.tm_mday = RTC_DateStruct.Date;
    tm_new.tm_mon  = RTC_DateStruct.Month - 1;
    tm_new.tm_year = RTC_DateStruct.Year + 100;

    LOG_D("get rtc time.");

    return mktime(&tm_new);
#else
    time_t timestamp;

    timestamp = RTC->CNTH;    /* 得到计数器中的值(秒钟数) */
    timestamp <<= 16;
    timestamp += RTC->CNTL;

    LOG_D("get rtc time.");
    
    return timestamp;
#endif
}

3.修改set_rtc_time_stamp()函数如下:

static rt_err_t set_rtc_time_stamp(time_t time_stamp)
{
#if 0
    RTC_TimeTypeDef RTC_TimeStruct = {0};
    RTC_DateTypeDef RTC_DateStruct = {0};
    struct tm *p_tm;

    p_tm = localtime(&time_stamp);
    if (p_tm->tm_year < 100)
    {
        return -RT_ERROR;
    }

    RTC_TimeStruct.Seconds = p_tm->tm_sec ;
    RTC_TimeStruct.Minutes = p_tm->tm_min ;
    RTC_TimeStruct.Hours   = p_tm->tm_hour;
    RTC_DateStruct.Date    = p_tm->tm_mday;
    RTC_DateStruct.Month   = p_tm->tm_mon + 1 ;
    RTC_DateStruct.Year    = p_tm->tm_year - 100;
    RTC_DateStruct.WeekDay = p_tm->tm_wday + 1;

    if (HAL_RTC_SetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN) != HAL_OK)
    {
        return -RT_ERROR;
    }
    if (HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) != HAL_OK)
    {
        return -RT_ERROR;
    }
    
    LOG_D("set rtc time.");
    HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);

    return RT_EOK;
#else
    /* 设置时钟 */
    RCC->APB1ENR |= 1<<28;                /* 使能电源时钟 */
    RCC->APB1ENR |= 1<<27;                /* 使能备份时钟 */
    PWR->CR |= 1 << 8;                    /* 取消备份区写保护 */
    
    /* 上面三步是必须的! */
    RTC->CRL |= 1 << 4;                    /* 允许配置 */
    RTC->CNTL = time_stamp & 0xffff;
    RTC->CNTH = time_stamp >> 16;
    RTC->CRL &= ~(1 << 4);                /* 配置更新 */
    while (!(RTC->CRL & (1 << 5)));        /* 等待RTC寄存器操作完成 */

    HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);
    LOG_D("set rtc time.");

    return RT_EOK;
#endif
}

调试验证

编译下载后可以看到,复位后年月日、时分秒均正常保存。
在这里插入图片描述

总结

RT-Thread Studio使用体验较好,RT-Thread社区大神云集,很多共性问题都能在其中找到答案。

这是我在CSDN发表的第一篇博客,内容和排版上都还有很大的改进空间。今后我也会通过这种方式记录我的RTT学习历程,希望大家多多指点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值