这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 物联网技术 » 【MAX78000】RTC时间打印

共4条 1/1 1 跳转至

【MAX78000】RTC时间打印

工程师
2025-06-27 16:56:55     打赏

MAX78000有RTC来实现日期时间,这一篇将如何快速配置RTC并实现时间的打印。

1、在工程中引用rtc.h

2、MAX78000的RTC读取的是一个32位的时间戳,单位为秒,另一个寄存器为16位的时间戳但是有效时间为低12位,单位为亚秒。

读取他们值,在sdk库中已经给出了:

int MXC_RTC_GetSubSeconds(uint32_t *ssec);
int MXC_RTC_GetSeconds(uint32_t *sec);

3、在初始化中,sdk给出了初始化的函数:

/**
 * @brief     Initialize the sec and ssec registers and enable RTC (Blocking function)
 * @param     sec    set the RTC Sec counter (32-bit)
 * @param     ssec   set the RTC Sub-second counter (12-bit)
 * @retval    returns Success or Fail, see \ref MXC_ERROR_CODES
 */
int MXC_RTC_Init(uint32_t sec, uint16_t ssec);

【注】在此篇中,我们不需要读取亚秒,因此只需要传入32位的时间戳即可。

【辅助函数】

为了转化时间戳,我添加了如下函数:

#define MSEC_TO_RSSA(x) \
    (0 - ((x * 4096) /  \
          1000)) /* Converts a time in milleseconds to the equivalent RSSA register value. */

#define SECS_PER_MIN 60
#define SECS_PER_HR (60 * SECS_PER_MIN)
#define SECS_PER_DAY (24 * SECS_PER_HR)


TaskHandle_t xTask1Handle = NULL;
extern BloodData g_blooddata ;
/* 任务函数声明 */
void vTask1(void *pvParameters);

// 判断是否为闰年
int isLeapYear(int year) {
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// 获取指定年份中每个月的天数
void getDaysInMonth(int year, int daysInMonth[]) {
    daysInMonth[0] = 0;  // 不使用索引0
    daysInMonth[1] = 31;
    daysInMonth[2] = isLeapYear(year) ? 29 : 28;  // 闰年2月29天
    daysInMonth[3] = 31;
    daysInMonth[4] = 30;
    daysInMonth[5] = 31;
    daysInMonth[6] = 30;
    daysInMonth[7] = 31;
    daysInMonth[8] = 31;
    daysInMonth[9] = 30;
    daysInMonth[10] = 31;
    daysInMonth[11] = 30;
    daysInMonth[12] = 31;
}

// 将从2000年1月1日起的时间戳转换为日期时间
void timestampToDateTime(long timestamp, int *year, int *month, int *day, int *hour, int *minute, int *second) {
    long sec = timestamp;

    // 计算时、分、秒(已有代码)
    // 计算天数(从2000年1月1日起)
    long dayCount = sec / SECS_PER_DAY;
    sec -= dayCount * SECS_PER_DAY;  // 剩余秒数用于计算时、分、秒

    // 计算时、分、秒
    *hour = sec / SECS_PER_HR;
    sec -= *hour * SECS_PER_HR;

    *minute = sec / SECS_PER_MIN;
    sec -= *minute * SECS_PER_MIN;

    *second = sec;

    // 计算天数(从2000年1月1日起)


    // 计算年份
    *year = 2000;
    while (1) {
        int daysInYear = isLeapYear(*year) ? 366 : 365;
        if (dayCount < daysInYear) break;
        dayCount -= daysInYear;
        (*year)++;
    }

    // 计算月份和日期
    int daysInMonth[13];
    getDaysInMonth(*year, daysInMonth);

    *month = 1;
    while (*month <= 12) {
        if (dayCount < daysInMonth[*month]) break;
        dayCount -= daysInMonth[*month];
        (*month)++;
    }

    *day = (int)dayCount + 1;  // +1是因为天数从0开始计数,而日期从1开始
}
// 计算从2000年1月1日起的天数
int daysSince2000(int year, int month, int day) {
    int days = 0;
    int i;

    // 计算完整年份的天数
    for (i = 2000; i < year; i++) {
        days += isLeapYear(i) ? 366 : 365;
    }

    // 计算当年到目标月份的天数
    int daysInMonth[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    if (isLeapYear(year)) {
        daysInMonth[2] = 29;  // 闰年2月29天
    }

    for (i = 1; i < month; i++) {
        days += daysInMonth[i];
    }

    // 加上当月的天数
    days += day;

    return days;
}

void printTime(void)
{
	int year, month, day, hour, minute, second,err;
    uint32_t rtc_readout;

//    do {
//        err = MXC_RTC_GetSubSeconds(&rtc_readout);
//    } while (err != E_NO_ERROR);
//    subsec = rtc_readout / 4096.0;

    do {
        err = MXC_RTC_GetSeconds(&rtc_readout);
    } while (err != E_NO_ERROR);

    // 转换时间戳为日期时间
        timestampToDateTime(rtc_readout, &year, &month, &day, &hour, &minute, &second);

        printf("timestamp %ld datetime: %04d-%02d-%02d %02d:%02d:%02d\n",
        		rtc_readout, year, month, day, hour, minute, second);
}

以上辅助函数功能为由给出的年月日函数转化为时间戳,或者是读出的时间戳转化为时间。

【测试】

在初始化中,给出初始的时间,然后转化为时间戳,通过rtcinit写入RTC寄存器,然后在任务函数中读取并通过串口输出:

	    int year = 2025;
	    int month = 6;
	    int day = 27;
	    int hour = 16;
	    int minute = 7;
	    int second = 0;

	    // 计算从2000年1月1日起的总秒数
	    int totalDays = daysSince2000(year, month, day);
	    long timestamp = (long)totalDays * SECS_PER_DAY +
	                    hour * SECS_PER_HR +
	                    minute * SECS_PER_MIN +
	                    second;

	    printf("从2000年1月1日00:00:00到%04d-%02d-%02d %02d:%02d:%02d的时间戳为: %ld\n",
	           year, month, day, hour, minute, second, timestamp);

	if (MXC_RTC_Init(timestamp, 0) != E_NO_ERROR) {
	        printf("Failed RTC Initialization\n");
	        printf("Example Failed\n");

	        while (1) {}
	    }
	if (MXC_RTC_Start() != E_NO_ERROR) {
	        printf("Failed RTC_Start\n");
	        printf("Example Failed\n");

	        while (1) {}
	    }

	    printf("RTC started\n");

打印时间:

image.png

实现效果:

image.png

【总结】

在MAX78000的sdk中给出了RTC封装好的函数,非常简单的就可以实现RTC的功能,当然如果想实现中断,还需要一简单的配置,大家可以创建一个RTC的示例,在示例中有详细的说明。




关键词: MAX78000     RTC    

专家
2025-06-28 14:53:44     打赏
2楼

感谢分享


专家
2025-06-28 14:55:00     打赏
3楼

感谢分享


专家
2025-06-28 14:56:19     打赏
4楼

感谢分享


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]