Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RTC
使IAR中使用RTC,设置时间会后得到的时间会比设置...
发布于 2019-11-13 08:59:53 浏览:2898
订阅该版
DEBUG发现是date命令行传递进来的值时没问题的,但是RTC_TimeStruct 结构体的时间是不对的。 rtc在设置时间前会调用time(),time()在 libc目录下的 time.c,发现这里对IAR编译器做了专门的宏定义。 ```/* for IAR 6.2 later Compiler */ #if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 #pragma module_name = "?time" #if _DLIB_TIME_USES_64 time_t __time64(time_t *t) #else time_t __time32(time_t *t) #endif #else time_t time(time_t *t) #endif```支持这个函数的时候MDK和IAR产生了不一样的值,这个值给到了RTC_TimeStruct,MDK能正确设置,但是IAR就推迟了2个小时。
查看更多
yesiqi2019
2020-07-02
这家伙很懒,什么也没写!
我同样遇到了这样的问题,几个点你关注一下: 1、MCU的内部时钟是BCD格式的,而tm里面的是十六进制格式的,也就是说: MCU的分钟为0x33,tm_min应该为0x21,这里在读取和设置时间的时候注意 2、这个应该是你的关键 tm这个结构体中有关于夏令时,也就是日光节约时间的标志,默认是-1,让系统自动判断,这里有问题的 不用时都给他初始化为0 。tm_isdst = 0,
25
个回答
默认排序
按发布时间排序
whj467467222
认证专家
2019-11-13
开源,分享,交流,共同进步
顶一下贴,万一大佬看见了呢?
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
一个星期过去了,再顶一下贴,贴一下自己调试的流程,路过的大佬有空的话 能帮忙分析一下吗?
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
[i=s] 本帖最后由 whj467467222 于 2019-11-20 20:28 编辑 [/i] 1:命令行输入 date 2019 01 01 01 01 01 2::进入date(uint8_t argc, char **argv) ``` uint16_t year; uint8_t month, day, hour, min, sec; year = atoi(argv[1]); month = atoi(argv[2]); day = atoi(argv[3]); hour = atoi(argv[4]); min = atoi(argv[5]); sec = atoi(argv[6]); set_time(hour, min, sec); set_date(year, month, day); ``` 这里就把命令行写入的数据赋值给了 年月日 时分秒 3:这里先使用set_time 来设置时分秒 ``` rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second) { time_t now; struct tm *p_tm; struct tm tm_new; rt_device_t device; rt_err_t ret = -RT_ERROR; /* get current time */ now = time(RT_NULL); /* lock scheduler. */ rt_enter_critical(); /* converts calendar time time into local time. */ p_tm = localtime(&now); /* copy the statically located variable */ memcpy(&tm_new, p_tm, sizeof(struct tm)); /* unlock scheduler. */ rt_exit_critical(); /* update time. */ tm_new.tm_hour = hour; tm_new.tm_min = minute; tm_new.tm_sec = second; /* converts the local time in time to calendar time. */ now = mktime(&tm_new); device = rt_device_find("rtc"); if (device == RT_NULL) { return -RT_ERROR; } /* update to RTC device. */ ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); return ret; } ``` 设置时间这里先通过now = time(RT_NULL); 来获取时间戳,这个时间戳的数值表示自1970年1月1日0时0分0秒开始 具体当前时间已经过去了多少秒。这里读出来的值是 0x5C2AA1EA p_tm = localtime(&now); 这里返回的数据类型如下 ``` struct tm { int tm_sec; /* 秒,范围从 0 到 59 */ int tm_min; /* 分,范围从 0 到 59 */ int tm_hour; /* 小时,范围从 0 到 23 */ int tm_mday; /* 一月中的第几天,范围从 1 到 31 */ int tm_mon; /* 月份,范围从 0 到 11 */ int tm_year; /* 自 1900 起的年数 */ int tm_wday; /* 一周中的第几天,范围从 0 到 6 */ int tm_yday; /* 一年中的第几天,范围从 0 到 365 */ int tm_isdst; /* 夏令时 */ }; ``` 这里读出来的值见图[attach]12372[/attach]
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
4:接下来就是更新时间 ``` /* update time. */ tm_new.tm_hour = hour; tm_new.tm_min = minute; tm_new.tm_sec = second; ``` 把set_time传递进来的值,赋值给tm_new [attach]12373[/attach] 这里就能看到时间是 2018年11月31日 01时01分34秒
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
5:把获取到的时间转换成时间戳,然后设置时间 ``` now = mktime(&tm_new); ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); ``` 6,调用STM32的RTC API来进行设置时间 ``` 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; HAL_RTC_SetTime(&RTC_Handler, &RTC_TimeStruct, RTC_FORMAT_BIN) HAL_RTC_SetDate(&RTC_Handler, &RTC_DateStruct, RTC_FORMAT_BIN) HAL_RTCEx_BKUPWrite(&RTC_Handler, RTC_BKP_DR1, BKUP_REG_DATA); ``` [attach]12374[/attach] 第一次是设置时间,能看到时分秒的数值是 01 01 01 月是0X0C 既12月 date是0x1F 既31
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
7,设置时间结束了,接下来是设置日期。 ``` now = time(RT_NULL); p_tm = localtime(&now); memcpy(&tm_new, p_tm, sizeof(struct tm)); tm_new.tm_year = year - 1900; tm_new.tm_mon = month - 1; /* tm_mon: 0~11 */ tm_new.tm_mday = day; now = mktime(&tm_new); ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now); ``` 可以看到set_date和set_time还是非常相似的。 8,set_date设置日期时的结构体数值 [attach]12375[/attach] 这里能看到 date 0x01 month 0x01 但是hours是 0x00 minutes 是0x08
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
9,到上面位置对RTC的时间更新已结束 ``` msh />date 2019 01 01 01 01 01 msh />date Mon Dec 31 23:10:16 2018 ``` 可以看到设置时间为2019年1月1日1时1分1秒的 读出来的数据就不是设置值了,时间变成了2018年12月31日23时10分,这个10分和我DEBUG有关,就是慢了2小时。
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
10;综合以上来看,传递时间给到STM32的API的时候数值已经错了。数值从哪错的呢? 再来倒推一下, now = mktime(&tm_new); 把时间转换成时间戳的形式,这个时C库的函数 暂时不考虑这个会出问题,毕竟MDK设置时间正常 再往上回退一步, ``` tm_new.tm_hour = hour; tm_new.tm_min = minute; tm_new.tm_sec = second; ``` 这里把set_time的值 赋值给这个结构体的成员,DEBUG过了,这里传递的时分秒也没错 再回退一步 p_tm = localtime(&now); localtime 这个也是C库函数,暂时不考虑 最大的嫌疑来了 now = time(RT_NULL); 要么就是这里获取的当前时间就一直时错的,导致后面的都错了
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
[i=s] 本帖最后由 whj467467222 于 2019-11-20 21:06 编辑 [/i] 11; ``` /* for IAR 6.2 later Compiler */ #if defined (__IAR_SYSTEMS_ICC__) && (__VER__) >= 6020000 #pragma module_name = "?time" #if _DLIB_TIME_USES_64 time_t __time64(time_t *t) #else time_t __time32(time_t *t) #endif #else time_t time(time_t *t) #endif { time_t time_now = 0; #ifdef RT_USING_RTC static rt_device_t device = RT_NULL; /* optimization: find rtc device only first. */ if (device == RT_NULL) { device = rt_device_find("rtc"); } /* read timestamp from RTC device. */ if (device != RT_NULL) { if (rt_device_open(device, 0) == RT_EOK) { rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); rt_device_close(device); } } #endif /* RT_USING_RTC */ /* if t is not NULL, write timestamp to *t */ if (t != RT_NULL) { *t = time_now; } return time_now; } ``` 这个函数实现了读取时间戳的功能,这里对IAR编译器专门做了宏定义支持6.2以上版本 这个函数这么长,实际就干了一件事 rt_device_control(device, RT_DEVICE_CTRL_RTC_GET_TIME, &time_now); 去读RTC时间
whj467467222
认证专家
2019-11-20
开源,分享,交流,共同进步
12.读取到当前时间的函数 ``` 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); } ``` 通过这里发现MDK和IAR 执行的代码都是一样的,出了time()那么对IAR做了宏定义,但是IAR时间就时一定慢2个小时。
撰写答案
登录
注册新账号
关注者
2
被浏览
2.9k
关于作者
whj467467222
开源,分享,交流,共同进步
提问
29
回答
1222
被采纳
148
关注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组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
13
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
本月文章贡献
程序员阿伟
7
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部