关于STM32F091 调试RTC,读取时间年份总是不对的问题解决

在调试rtc时,通过hal库函数设置date,time后,读取的时间总是年不对,月日时分秒是对的,

如图:

通过这个连接中的问题http://www.openedv.com/thread-231322-1-22.html?/news/guonei/97663746655/h

找到一位网友的解决方法:

按照这个方法确实解决了我的问题,将星期填上后,年份读取就正确了:

代码实现:

void platform_rtc_set_time(struct tm *time)
{
	RTC_TimeTypeDef RTC_TimeStructure;
	RTC_DateTypeDef RTC_DateStructure;
    
    RTC_TimeStructure.TimeFormat = RTC_HOURFORMAT12_AM;
    RTC_TimeStructure.Hours    = time->tm_hour;
    RTC_TimeStructure.Minutes  = time->tm_min;
    RTC_TimeStructure.Seconds  = time->tm_sec;
    RTC_DateStructure.WeekDay = 0;  //这里必须要设置星期,否则读取年份不对
    RTC_DateStructure.Year   = time->tm_year - 100;
    RTC_DateStructure.Month  = time->tm_mon + 1;
    RTC_DateStructure.Date   = time->tm_mday;

	HAL_RTC_SetTime(&hrtc, &RTC_TimeStructure,RTC_FORMAT_BIN);
	HAL_RTC_SetDate(&hrtc,&RTC_DateStructure,RTC_FORMAT_BIN);
}

void platform_rtc_get_time(struct tm *time)
{
	RTC_TimeTypeDef RTC_TimeStructure;
	RTC_DateTypeDef RTC_DateStructure;

	HAL_RTC_GetTime(&hrtc,&RTC_TimeStructure,RTC_FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc,&RTC_DateStructure,RTC_FORMAT_BIN);

	time->tm_year = RTC_DateStructure.Year + 100;
	time->tm_mon =  RTC_DateStructure.Month - 1;
	time->tm_mday = RTC_DateStructure.Date;
	time->tm_wday = RTC_DateStructure.WeekDay;
	time->tm_hour = RTC_TimeStructure.Hours;
	time->tm_min =  RTC_TimeStructure.Minutes;
	time->tm_sec =  RTC_TimeStructure.Seconds;
}

long set_time(uint32_t year, uint32_t month, uint32_t day, uint32_t hour, uint32_t minute, uint32_t second)
{
	time_t now_time;
	struct tm tm_new;
    struct tm *p_tm;
	rt_device_t device;
	rt_err_t ret = -RT_ERROR;
    
	tm_new.tm_year = year - 1900;
	tm_new.tm_mon = month - 1;
	tm_new.tm_mday = day;
	tm_new.tm_hour = hour;
	tm_new.tm_min = minute;
	tm_new.tm_sec = second;

	now_time = mktime(&tm_new);

	device = rt_device_find("rtc");
	if (device == RT_NULL) 
    {
		return -RT_ERROR;
	}
	ret = rt_device_control(device, RT_DEVICE_CTRL_RTC_SET_TIME, &now_time);
	return ret;
}
//获取时间的函数,获取返回的是时间戳
time_t time(time_t *t)
{
	static rt_device_t device = RT_NULL;
	time_t time_now = 0;

	if (device == RT_NULL) {
		device = rt_device_find("rtc");
	}
	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);
		}
	}
	if (t != RT_NULL) {
		*t = time_now;
	}
	return time_now;
}
通过rtthread的device实现的控制函数rt_device_control, rtc的device实现如下:
#include <rtthread.h>
#include <time.h>
#include "stm32f0xx_hal.h"
#include "rtc.h"

#define DEVICE_NAME "rtc"

static struct rt_device rtc;

static rt_err_t drv_rtc_open(rt_device_t dev, rt_uint16_t oflag)
{
	return RT_EOK;
}

static rt_err_t drv_rtc_close(rt_device_t dev)
{
	return RT_EOK;
}

static rt_size_t drv_rtc_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
{
	struct tm ti;
    platform_rtc_get_time(&ti);
    rt_kprintf("%04d-%02d-%02d %02d:%02d:%02d\r\n", ti.tm_year + 1900, ti.tm_mon + 1, ti.tm_mday, ti.tm_hour, ti.tm_min, ti.tm_sec);
	rt_sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d", ti.tm_year + 1900, ti.tm_mon + 1, ti.tm_mday, ti.tm_hour, ti.tm_min, ti.tm_sec);
	return 0;
}

static rt_tick_t init_tick;
static time_t init_time;
static rt_err_t drv_rtc_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
    time_t *time;
	struct tm ti;
    struct tm *p_tm;
	RT_ASSERT(dev != RT_NULL);

	switch (cmd) {
	case RT_DEVICE_CTRL_RTC_GET_TIME:
		time = (time_t *) args;
		platform_rtc_get_time(&ti);
		*time = mktime(&ti);
		break;
	case RT_DEVICE_CTRL_RTC_SET_TIME:
		time = (time_t *) args;
		p_tm = localtime(time);
		platform_rtc_set_time(p_tm);
		break;
	}
    /* rtthread中rtc的实现方法
//    time_t *time;
//    struct tm time_temp;

//    RT_ASSERT(dev != RT_NULL);
//    memset(&time_temp, 0, sizeof(struct tm));

//    switch (cmd)
//    {
//    case RT_DEVICE_CTRL_RTC_GET_TIME:
//        time = (time_t *) args;
//        *time = init_time + (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
//        break;

//    case RT_DEVICE_CTRL_RTC_SET_TIME:
//    {
//        time = (time_t *) args;
//        init_time = *time - (rt_tick_get() - init_tick) / RT_TICK_PER_SECOND;
//        break;
//    }
//    }
*/
    return RT_EOK;
}

int drv_rtc_init(void)
{
	platform_rtc_init();
	rtc.init    = RT_NULL;
	rtc.open    = drv_rtc_open;
	rtc.close   = drv_rtc_close;
	rtc.read    = drv_rtc_read;
	rtc.write   = RT_NULL;
	rtc.control = drv_rtc_control;
	rtc.user_data = RT_NULL;
	rt_device_register(&rtc, DEVICE_NAME, RT_DEVICE_FLAG_RDWR);
	return 0;
}
INIT_BOARD_EXPORT(drv_rtc_init);

 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值