Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RTC
rthread
RttreadV5.10上,GD32F450Z RTC时间显示问题
发布于 2025-01-14 20:16:33 浏览:132
订阅该版
本文主是要基于GD32F450上移植rttread_V5.10上的RTC时,遇到的一系列问题。最后都修改在drv_rtc.c中。 参考了这篇链接 https://club.rt-thread.org/ask/article/c059995282a64573.html ```c /* * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2022-01-25 iysheng first version */ #include
#include
#define DBG_TAG "drv.rtc" #define DBG_LVL DBG_INFO #include
#ifdef RT_USING_RTC #define RTC_CLOCK_SOURCE_IRC32K //内部晶振 //#define RTC_CLOCK_SOURCE_LXTAL //外部32K晶振 #define BKP_VALUE 0x32F0 rtc_timestamp_struct rtc_timestamp; rtc_parameter_struct rtc_initpara; __IO uint32_t prescaler_a = 0, prescaler_s = 0; uint32_t RTCSRC_FLAG = 0; typedef struct { struct rt_device rtc_dev; } gd32_rtc_device; static gd32_rtc_device g_gd32_rtc_dev; uint8_t RTC_BCDToByte(uint8_t Value); uint8_t RTC_ByteToBCD(uint8_t Value); void rtc_pre_config(void); void rtc_setup(void); void rtc_show_time(void); void rtc_show_timestamp(void); uint8_t RTC_BCDToByte(uint8_t Value)//BCD转二进制 { uint8_t tmp; tmp = ((Value & 0xF0u) >> 4u) * 10u; return (tmp + (Value & 0x0Fu)); } uint8_t RTC_ByteToBCD(uint8_t Value)//二进制转BCD { uint32_t bcdhigh = 0u; uint8_t Param = Value; while(Param >= 10u) { bcdhigh++; Param -= 10u; } return ((uint8_t)(bcdhigh << 4u) | Param); } //club.rt-thread.org/ask/article/c059995282a64573.html static time_t get_rtc_timestamp(void) { rtc_parameter_struct para; rtc_current_time_get(¶); struct tm timeinfo = { .tm_year = 100 + RTC_BCDToByte(para.year), //para.year, 00-99 time是从1900年开始计算 .tm_mon = RTC_BCDToByte(para.month) - 1, //para.month, 1-12 time 0-11 .tm_mday = RTC_BCDToByte(para.date), //para.date, 1-31 time 1-31 .tm_wday = RTC_BCDToByte(para.day_of_week) - 1, //1-7 time 0-6 //.tm_yday = , .tm_hour = RTC_BCDToByte(para.hour), //para.hour, .tm_min = RTC_BCDToByte(para.minute), //para.minute, .tm_sec = RTC_BCDToByte(para.second), //para.second, .tm_isdst = -1, // 自动判断是否是夏令时 }; rt_kprintf("get_rtc_timestamp()---year is %02x, month is %02x, day is %02x, hour is %02x, minute is %02x, second is %02x\r\n", para.year, para.month, para.date, para.hour, para.minute,para.second); time_t rawtime = mktime(&timeinfo); return rawtime; } static rt_err_t set_rtc_timestamp(time_t time_stamp) { time_t stamp = time_stamp; struct tm *timeinfo = gmtime(&stamp); rtc_parameter_struct rtcPara = { .factor_asyn = prescaler_a, .factor_syn = prescaler_s, .year = RTC_ByteToBCD(timeinfo->tm_year - 100), .day_of_week = RTC_ByteToBCD(timeinfo->tm_wday + 1), .month = RTC_ByteToBCD(timeinfo->tm_mon + 1), .date = RTC_ByteToBCD(timeinfo->tm_mday), .display_format = RTC_24HOUR, .hour = RTC_ByteToBCD(timeinfo->tm_hour), .minute = RTC_ByteToBCD(timeinfo->tm_min), .second = RTC_ByteToBCD(timeinfo->tm_sec), .am_pm = RTC_AM, }; if (timeinfo->tm_hour > 12) { rtcPara.am_pm = RTC_PM; } if(ERROR == rtc_init(&rtcPara)) { LOG_E("RTC time configuration failed !!!"); return -RT_EINVAL; } else { RTC_BKP0 = BKP_VALUE; } return RT_EOK; } static rt_err_t rt_gd32_rtc_control(rt_device_t dev, int cmd, void *args) { rt_err_t result = RT_EOK; RT_ASSERT(dev != RT_NULL); switch (cmd) { case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: case RT_DEVICE_CTRL_RTC_GET_TIME: *(rt_uint32_t *)args = get_rtc_timestamp(); break; case RT_DEVICE_CTRL_RTC_SET_TIME: if (set_rtc_timestamp(*(rt_uint32_t *)args)) { result = -RT_ERROR; } break; } return result; } #ifdef RT_USING_DEVICE_OPS const static struct rt_device_ops g_gd32_rtc_ops = { RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL, rt_gd32_rtc_control }; #endif /*! \brief RTC configuration function \param[in] none \param[out] none \retval none */ void rtc_pre_config(void) { #if defined (RTC_CLOCK_SOURCE_IRC32K) rcu_osci_on(RCU_IRC32K); rcu_osci_stab_wait(RCU_IRC32K); rcu_rtc_clock_config(RCU_RTCSRC_IRC32K); prescaler_s = 0x13F; prescaler_a = 0x63; #elif defined (RTC_CLOCK_SOURCE_LXTAL) rcu_osci_on(RCU_LXTAL); rcu_osci_stab_wait(RCU_LXTAL); rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); prescaler_s = 0xFF; prescaler_a = 0x7F; #else #error RTC clock source should be defined. #endif /* RTC_CLOCK_SOURCE_IRC32K */ rcu_periph_clock_enable(RCU_RTC); rtc_register_sync_wait(); } /*! \brief use hyperterminal to setup RTC time and alarm \param[in] none \param[out] none \retval none */ void rtc_setup(void) { rtc_initpara.factor_asyn = prescaler_a; rtc_initpara.factor_syn = prescaler_s; rtc_initpara.year = 0x25; rtc_initpara.day_of_week = RTC_TUESDAY; rtc_initpara.month = RTC_JAN; rtc_initpara.date = 0x14; rtc_initpara.display_format = RTC_24HOUR; rtc_initpara.am_pm = RTC_AM; rtc_initpara.hour = 0x08; rtc_initpara.minute = 0x22; rtc_initpara.second = 0x33; /* RTC current time configuration */ if(ERROR == rtc_init(&rtc_initpara)){ rt_kprintf("\n\r** RTC time configuration failed! **\n\r"); }else{ rt_kprintf("\n\r** RTC time configuration success! **\n\r"); rtc_show_time(); RTC_BKP0 = BKP_VALUE; } // rtc_interrupt_enable(RTC_INT_ALARM0); // rtc_alarm_enable(RTC_ALARM0); } /*! \brief display the timestamp time \param[in] none \param[out] none \retval none */ void rtc_show_timestamp(void) { uint32_t ts_subsecond = 0; uint8_t ts_subsecond_ss,ts_subsecond_ts,ts_subsecond_hs ; rtc_timestamp_get(&rtc_timestamp); /* get the subsecond value of timestamp time, and convert it into fractional format */ ts_subsecond = rtc_timestamp_subsecond_get(); ts_subsecond_ss=(1000-(ts_subsecond*1000+1000)/400)/100; ts_subsecond_ts=(1000-(ts_subsecond*1000+1000)/400)%100/10; ts_subsecond_hs=(1000-(ts_subsecond*1000+1000)/400)%10; rt_kprintf("Get the time-stamp time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ rtc_timestamp.timestamp_hour, rtc_timestamp.timestamp_minute, rtc_timestamp.timestamp_second,\ ts_subsecond_ss, ts_subsecond_ts, ts_subsecond_hs); } /*! \brief display the current time \param[in] none \param[out] none \retval none */ void rtc_show_time(void) { uint32_t time_subsecond = 0; uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0; rtc_current_time_get(&rtc_initpara); /* get the subsecond value of current time, and convert it into fractional format */ time_subsecond = rtc_subsecond_get(); subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100; subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10; subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10; rt_kprintf("Current time: %0.2x:%0.2x:%0.2x .%d%d%d \n\r", \ rtc_initpara.hour, rtc_initpara.minute, rtc_initpara.second,\ subsecond_ss, subsecond_ts, subsecond_hs); } //https://club.rt-thread.org/ask/article/c059995282a64573.html static int rt_hw_rtc_init(void) { rcu_periph_clock_enable(RCU_PMU); pmu_backup_write_enable(); rtc_pre_config(); /* get RTC clock entry selection */ RTCSRC_FLAG = GET_BITS(RCU_BDCTL, 8, 9); if((BKP_VALUE != RTC_BKP0) || (0x00 == RTCSRC_FLAG)) { /* backup data register value is not correct or not yet programmed or RTC clock source is not configured (when the first time the program is executed or data in RCU_BDCTL is lost due to Vbat feeding) */ rtc_setup(); } else { if(RESET != rcu_flag_get(RCU_FLAG_PORRST))/**< 检测复位时钟源 */ { LOG_I("power on reset occurred ..."); } else if(RESET != rcu_flag_get(RCU_FLAG_EPRST)) { LOG_I("external reset occurred ..."); } //LOG_I("no need to configure RTC ..."); rtc_show_time(); } rcu_all_reset_flag_clear(); #ifdef RT_USING_DEVICE_OPS g_gd32_rtc_dev.rtc_dev.ops = &g_gd32_rtc_ops; #else g_gd32_rtc_dev.rtc_dev.init = RT_NULL; g_gd32_rtc_dev.rtc_dev.open = RT_NULL; g_gd32_rtc_dev.rtc_dev.close = RT_NULL; g_gd32_rtc_dev.rtc_dev.read = RT_NULL; g_gd32_rtc_dev.rtc_dev.write = RT_NULL; g_gd32_rtc_dev.rtc_dev.control = rt_gd32_rtc_control; #endif g_gd32_rtc_dev.rtc_dev.type = RT_Device_Class_RTC; g_gd32_rtc_dev.rtc_dev.rx_indicate = RT_NULL; g_gd32_rtc_dev.rtc_dev.tx_complete = RT_NULL; g_gd32_rtc_dev.rtc_dev.user_data = RT_NULL; rt_err_t ret = rt_device_register(&g_gd32_rtc_dev.rtc_dev, "rtc", RT_DEVICE_FLAG_RDWR); if (ret != RT_EOK) { LOG_E("failed register internal rtc device, err=%d", ret); } return ret; } INIT_DEVICE_EXPORT(rt_hw_rtc_init); #endif ```
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
yc985055
这家伙很懒,什么也没写!
文章
1
回答
38
被采纳
0
关注TA
发私信
相关文章
1
RTC驱动框架几点建议
2
求助:RTT在STM32F407上使用内置的RTC设置日期需重启生效,设置时间即时生效,有遇到同样问题的吗?
3
[新人试水] LPC1768 Nano3_9 添加RTC
4
STM32 关于RTC的问题
5
stm32f4xx-HAL BSP的RTC设置不对
6
关于STM32的RTC设置年份不正确的问题
7
RTT的RTC驱动调试
8
rtc驱动中的bkp模块起不到防止时间的重新设置
9
rtc时钟跑十几个小时后,比实际时间快几秒怎么解决
10
stm32如何断电之后开发板rtc时间继续往前跑
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
I2C_IIC
UART
ESP8266
cubemx
WIZnet_W5500
ota在线升级
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
10
个答案
3
次被采纳
xiaorui
3
个答案
2
次被采纳
winfeng
2
个答案
2
次被采纳
三世执戟
8
个答案
1
次被采纳
KunYi
8
个答案
1
次被采纳
本月文章贡献
catcatbing
3
篇文章
5
次点赞
lizimu
2
篇文章
8
次点赞
swet123
1
篇文章
4
次点赞
Days
1
篇文章
4
次点赞
YZRD
1
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部