本文主要是介绍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时钟年月日掉电丢失的解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!