跳转至

23 rtc 实时时钟

作者:王城钧 | 最后修改:2026-05-08

一、rtc(实时时钟)概述

rtc(实时时钟)是一种能独立于主系统电源持续运行的电子组件,经分频计数实现年、月、日、时、分、秒的精准计量,可与主系统实现时间读取、校准、闹钟触发等交互,具备高稳定性的特点,广泛应用于消费电子、物联网、工业控制、汽车电子等领域,为设备提供可靠的时间戳和时序基准,是保障系统时间同步的关键组件。

1.1 LuatOS 的 rtc 核心库有什么用?

rtc 核心库提供对 rtc 功能的设置以及获取能力,主要功能包括:

  • 设置 rtc 时钟初始时间,读取 rtc 时钟时间
  • 设置 rtc 的时区以及基准年

二、演示功能概述

本教程将使用 Air1601 开发板演示 rtc 核心库的核心功能,主要包括:

场景 1(无网络环境下的 rtc 功能演示)

  1. 设置基准年和时区信息初始化 rtc
  2. 通过时间戳设置具体时间后,每秒循环打印基于 rtc 的本地时间

场景 2(获取基站和 ntp 授时成功后的 rtc 时间和实时时间)

  1. 设置基准年和时区信息初始化 rtc
  2. 等待基站和 ntp 授时成功,随后每秒循环打印实时时间和 rtc 时钟时间

三、准备硬件环境

参考:硬件环境清单,准备以及组装好硬件环境。

本demo默认联网方式用的是SPI_以太网接口,以太网功能开关设置说明

  • V_LAN 电源开关:拨至 ON,为以太网 PHY 芯片供电。
  • U5(SPI/ETH 通道拨码开关):所有通道拨向左侧"ON",打开以太网,以太网使用 CS1 (GPIO14) 作为片选。
  • S15(WAKEUP/LAN_INT 中断开关):
  • 单独使用以太网时:拨至 ON,连接 WAKEUP 信号到 LAN_INT,启用以太网中断功能。
  • 与触摸(TP)同时使用时:拨至 OFF,断开以太网中断,将 WAKEUP 信号留给 TP 使用。

使用其它网络接线方式请参考:Air1601开发板使用说明

1、Air1601开发板一块

2、TYPE-C USB数据线一根

3、网线一根,网线一端插入开发板网口,另外一端连接可以上外网的路由器网口

4、Air1601开发板和数据线的硬件接线方式为

  • Air1601开发板通过TYPE-C USB口连接TYPE-C USB 数据线,数据线的另外一端连接电脑的USB口;
  • 在 Air1601 开发板上丝印标注 USB1,为芯片烧录下载接口;
  • 若遇到因电脑 USB 端口供电不足导致的烧录失败,也可改用外部稳压电源通过开发板上的 VIN 引脚进行供电;

购买链接:Air1601开发板 多功能5寸RGB屏 支持AirUI 摄像头 代开发固件-淘宝网

四、软件环境

在开始实践本示例之前,先筹备一下软件环境:

1.烧录工具: Luatools 工具

2.内核固件:本demo开发测试时使用的固件为LuatOS-SoC_V1012_Air1601_101.soc,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试。

3.LuatOS 需要的脚本和资源文件

脚本和资源文件:点我查看 demo 地址

准备好软件环境之后,接下来查看如何烧录项目文件到 Air1601 开发板中,将本篇文章中演示使用的项目文件烧录到Air1601开发板 中。

五、API 接口说明

详细 API 文档请参考:https://docs.openluat.com/osapi/core/rtc/

六、代码示例介绍

6.1 功能测试核心代码

注意:以下两个任务每次测试时只能选择其一进行测试

-- RTC时钟演示(测试环境为无网络环境)
local function rtc_task1()
    rtc.setBaseYear(1900) -- 设置基准年为1900年
    local result = rtc.timezone(32) -- 设置时区为东八区
    log.info("rtc.timezone()", result) -- 打印时区信息
    -- rtc.set({ year = 2025, mon = 10, day = 28, hour = 8, min = 10, sec = 53 }) -- 设置日期和时间
    rtc.set(1761639053) -- 设置时间戳(与上一行的设置效果相同,二选一即可)
    local t1 = rtc.get()
    log.info("rtc初始时间", json.encode(t1)) -- 打印当前日期和时间
    log.info("rtc设置后的本地时间", os.date()) -- 打印当前日期和时间    
    while true do
        log.info("os.date()", os.date()) -- 打印RTC时钟时间
        local t = rtc.get() -- 获取rtc时间
        log.info("循环rtc时间", json.encode(t)) -- 打印当前rtc时间
        sys.wait(1000) -- 等待1s,然后再次获取rtc时间和实时时间
    end
end

-- 获取基站和 NTP授时成功后的rtc时间
local function rtc_task2()
    rtc.setBaseYear(1900) -- 设置基准年为1900年
    local result = rtc.timezone(32) -- 设置时区为东八区
    log.info("rtc.timezone()", result) -- 打印时区信息
    -- rtc.set({ year = 2025, mon = 10, day = 28, hour = 19, min = 10, sec = 53 }) -- 设置日期和时间
    rtc.set(1761678653) -- 设置时间戳(与上一行的设置效果相同,二选一即可)
    log.info("rtc设置后时间", os.date()) -- 打印当前日期和时间
    while not socket.adapter(socket.dft()) do
        log.warn("sntp_task_func", "wait IP_READY", socket.dft())
        -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
        -- 或者等待1秒超时退出阻塞等待状态;
        -- 注意:此处的1000毫秒超时不要修改的更长;
        -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
        -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
        -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
        sys.waitUntil("IP_READY", 1000)
    end
    socket.sntp()
    sys.waitUntil("NTP_UPDATE", 5000)
    while true do
        log.info("os.date()", os.date()) -- 打印实时时间
        local t = rtc.get()              -- 获取rtc时间
        log.info("循环rtc时间", json.encode(t))
        -- 打印当前rtc时间,当收到基站和 NTP授时的时候,rtc时间会自动更新为当前UTC时间(零时区),于北京时间(东八区)相差8小时
        sys.wait(1000) -- 等待1s,然后再次获取rtc时间和实时时间
    end
end

-- 注意:以下两个任务每次测试时只能选择其一进行测试

-- 无网络情况下的rtc时间演示
sys.taskInit(rtc_task1)

-- 获取基站和 NTP授时成功后的rtc时间
-- sys.taskInit(rtc_task2)

6.2 功能验证

通过 luatools 工具查看相关日志:

任务 1:

任务 2:

七、总结

至此,本示例详细介绍了如何使用 rtc 核心库进行功能测试开发。