RT-Thread STM32F1 RTC时钟年月日掉电丢失的解决办法

2024-01-22 05:18

本文主要是介绍RT-Thread STM32F1 RTC时钟年月日掉电丢失的解决办法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

STM32F1系列官方库没有保存年月日的功能,断电上电后会恢复初始值。所以根据RT-Thread官方例程操作后,年月日断电并不能保存。

硬件RTC的使用方法

1.CubeMX Settings中打开外部晶振并配置时钟源,打开RTC功能
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.首先需要打开RT-Thread Settings中RTC的驱动支持,但不要打开软件模拟RTC设备
在这里插入图片描述

3.drivers/board.h中打开硬件RTC的定义
在这里插入图片描述

RTC驱动修改

修改RTC驱动,实现断电保存年月日功能,这里参考了RT-Tread论坛中帖子的解决方案,原贴地址:https://club.rt-thread.org/ask/question/422537.html

修改drivers/drv_rtc.c的以下两个函数,改为RTC CNT直接存时间戳

static time_t get_rtc_timestamp(void)
{
//    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);time_t timestamp;timestamp = RTC->CNTH;    /* 得到计数器中的值(秒钟数) */timestamp <<= 16;timestamp += RTC->CNTL;LOG_D("get rtc time.");return timestamp;}static rt_err_t set_rtc_time_stamp(time_t time_stamp)
{
//    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;
//    }/* 设置时钟 */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寄存器操作完成 */LOG_D("set rtc time.");HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA);return RT_EOK;
}

例程

经过上述修改过程,完美解决了掉电后无法保存年月日的问题,可用如下官方例程测试。

/** 程序清单:这是一个 RTC 设备使用例程* 例程导出了 rtc_sample 命令到控制终端* 命令调用格式:rtc_sample* 程序功能:设置RTC设备的日期和时间,延时一段时间后获取当前时间并打印显示。
*/#include <rtthread.h>
#include <rtdevice.h>static int rtc_sample(int argc, char *argv[])
{rt_err_t ret = RT_EOK;time_t now;/* 设置日期 */ret = set_date(2022, 1, 2);if (ret != RT_EOK){rt_kprintf("set RTC date failed\n");return ret;}/* 设置时间 */ret = set_time(5, 50, 50);if (ret != RT_EOK){rt_kprintf("set RTC time failed\n");return ret;}/* 延时3秒 */rt_thread_mdelay(3000);/* 获取时间 */now = time(RT_NULL);rt_kprintf("%s\n", ctime(&now));return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(rtc_sample, rtc sample);

这篇关于RT-Thread STM32F1 RTC时钟年月日掉电丢失的解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/631938

相关文章

SQL Server数据库磁盘满了的解决办法

《SQLServer数据库磁盘满了的解决办法》系统再正常运行,我还在操作中,突然发现接口报错,后续所有接口都报错了,一查日志发现说是数据库磁盘满了,所以本文记录了SQLServer数据库磁盘满了的解... 目录问题解决方法删除数据库日志设置数据库日志大小问题今http://www.chinasem.cn天发

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Thread如何划分为Warp?

1 .Thread如何划分为Warp? https://jielahou.com/code/cuda/thread-to-warp.html  Thread Index和Thread ID之间有什么关系呢?(线程架构参考这里:CUDA C++ Programming Guide (nvidia.com)open in new window) 1维的Thread Index,其Thread

Solr 使用Facet分组过程中与分词的矛盾解决办法

对于一般查询而言  ,  分词和存储都是必要的  .  比如  CPU  类型  ”Intel  酷睿  2  双核  P7570”,  拆分成  ”Intel”,”  酷睿  ”,”P7570”  这样一些关键字并分别索引  ,  可能提供更好的搜索体验  .  但是如果将  CPU  作为 Facet  字段  ,  最好不进行分词  .  这样就造成了矛盾  ,  解决方法

ORACLE 11g 创建数据库时 Enterprise Manager配置失败的解决办法 无法打开OEM的解决办法

在win7 64位系统下安装oracle11g,在使用Database configuration Assistant创建数据库时,在创建到85%的时候报错,错误如下: 解决办法: 在listener.ora中增加对BlueAeri-PC或ip地址的侦听,具体步骤如下: 1.启动Net Manager,在“监听程序”--Listener下添加一个地址,主机名写计

Anaconda 中遇到CondaHTTPError: HTTP 404 NOT FOUND for url的问题及解决办法

最近在跑一个开源项目遇到了以下问题,查了很多资料都大(抄)同(来)小(抄)异(去)的,解决不了根本问题,费了很大的劲终于得以解决,记录如下: 1、问题及过程: (myenv) D:\Workspace\python\XXXXX>conda install python=3.6.13 Solving environment: done.....Proceed ([y]/n)? yDownloa

C# dateTimePicker 显示年月日,时分秒

dateTimePicker默认只显示日期,如果需要显示年月日,时分秒,只需要以下两步: 1.dateTimePicker1.Format = DateTimePickerFormat.Time 2.dateTimePicker1.CustomFormat = yyyy-MM-dd HH:mm:ss Tips:  a. dateTimePicker1.ShowUpDown = t

笔记本电脑开机报错故障的原因及解决办法

笔记本电脑开机报错故障是指笔记本电脑开机自检时或启动操作系统前停止启动,在显示屏 出现一些错误提示的故障。   笔记本电脑开机报错故障的原因及解决办法   造成此类故障的原因一般是笔记本电脑在启动自检时,检测到硬件设备不能正常工作或在自 检通过后从硬盘启动时,出现硬盘的分区表损坏、硬盘主引导记录损坏、硬盘分区结束标志丢失 等故障,笔记本电脑出现相应的故障提示。   维修此类故障时

adb shell 执行后台程序后断开adb后台进程被结束的解决办法

环境:Android 版本 Android8 通常让程序后台执行就是在命令 最后加上 &即可,但是在Android 8上实验发现,程序的确后台了,但是拔掉USB线再连接上发现进程已结束。不确定Android早期版本是否存在此问题。 参考网上一些Linux方法,如加nohup 仍然无效,还是会结束。看来Android adb shell 与 Linux shell 还是有一定区别。 后来在网上

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.