RT-Thread ——RTC配置

本文介绍了STM32F103系列芯片RTC配置的步骤,包括在board.h和stm32xxxhal_config.h文件中的修改,以及如何通过FinSH命令查看和设置时间。此外,针对RTC在复位后日期不保存的问题,提供了在drv_rtc.c文件中修改get_rtc_timestamp()和set_rtc_time_stamp()函数的解决方案,确保设置的时间在掉电后仍能保留。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

RT-Thread ——RTC配置

STM32F103系列芯片的RTC功能存在一些缺陷。

一、显示时间戳

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

官方RTC讲解:RTC设备 (rt-thread.org)

步骤:

  • 首先,我们在drivers目录中打开board.h源文件,找到RTC相关内容如下,并且将宏定义注释去掉:

在这里插入图片描述

  • 在RT-Thread Setting中、将RTC进行详细配置,根据自己需求,配置RTC alarm和软件模拟RTC设备

    在这里插入图片描述

    • 在drivers目录下的stm32xxxhal_config.h文件中去掉如下代码的注释。

      在这里插入图片描述

      此时可以根据FinSH命令进行时间的查看:

      在这里插入图片描述

      设置你的日期与时间:

      在这里插入图片描述

二、解决复位日期不保存问题

通过以上操作发现所设置的时间与日期只是在那时设置成功,但下次下代码之后发现时间并不是所设置的。

原帖地址:RT-Thread-芯片掉电,只有rtc电源,rtthread读取年月日都为0,时分秒正常RT-Thread问答社区 - 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-ThreadRTC 模块的使用教程和配置方法 #### 1. 硬件 RTC 的初始化与配置 对于 STM32 单片机,在使用 RT-Thread 实现硬件 RTC 功能时,需先确保已正确配置硬件环境。具体来说,应通过 CubeMX 工具使能 RTC 并完成必要的时钟设置[^2]。 当硬件部分准备就绪后,进入 RT-Thread 的 ENV (Embedded NuttX Visual Studio Code Extension) 进行软件层面的配置- 开启 `RTC` 组件; - 不要选择软件模拟 RTC- 使能 RTC 片上外设; - 如果采用内部时钟作为时间基准,则相应地选择合适的时钟源。 #### 2. 软件开发环境构建 利用 SCons 构建工具生成项目工程文件之后,还需将由 CubeMX 自动生成的相关时钟配置代码移植至 RT-Thread 工程内,以保证底层驱动能够正常工作并支持 RTC 功能。 #### 3. 应用程序接口调用实例 下面给出一段简单的 C 语言代码片段来展示如何操作 RTC 设备: ```c #include "rtdevice.h" #include "drv_rtc.h" static struct rt_device *rtc_dev; int main(void) { /* 获取 rtc 设备 */ rtc_dev = rt_device_find("rtc"); if (!rtc_dev) return -RT_ERROR; /* 设置当前时间为指定日期时间和启动定时器 */ { struct tm timeinfo = { .tm_year = 2023 - 1900, .tm_mon = 5, .tm_mday = 1, .tm_hour = 8, .tm_min = 30, .tm_sec = 0 }; rt_device_control(rtc_dev, RT_DEVICE_CTRL_RTC_SET_TIME, &timeinfo); } while(1){ struct tm timeinfo; char buffer[64]; /* 查询当前的时间 */ rt_device_read(rtc_dev, 0, &timeinfo, sizeof(timeinfo)); strftime(buffer,sizeof(buffer),"%Y-%m-%d %H:%M:%S",&timeinfo); printf("Current Time is :%s\n",buffer); rt_thread_delay(RT_TICK_PER_SECOND*5); } } ``` 此段代码展示了获取 RTC 设备句柄、设定初始时间和周期性读取当前时间的方法[^1]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值