# RTC ***Copyright © Quectel Wireless Solutions Co., Ltd. 2026. All rights reserved.*** --- # 功能概述 RTC(Real-Time Clock,实时时钟)芯片是一种集成时钟计时功能的电路模块,支持对年、月、日、星期、时、分、秒进行精确计时,并具备闰年自动补偿功能。 ## RTC的工作原理 ### RTC的基本结构 - **低频时钟源**:通常为32.768 kHz外部晶振(LSE)或内部低速RC振荡器(LSI),为RTC提供高稳定性的时间基准。 - **预分频器(Prescaler)**:将输入时钟分频至1 Hz,产生精确的秒脉冲。 - **时间/日期寄存器**:以BCD或二进制格式存储当前时间与日期。 - **备份域(Backup Domain)**:包含一组由备用电源(如VBAT)供电的寄存器,主电源掉电后内容不丢失,用于保存RTC配置和用户数据。 - **闹钟(Alarm)单元**:可编程设置特定时间点触发中断或唤醒系统。 - **周期性唤醒定时器(Wakeup Timer)**:支持毫秒级到秒级的周期性事件。 - **控制与状态寄存器**:用于配置RTC功能、使能中断、检查标志位等。 - **中断输出机制**:支持秒更新、闹钟、唤醒等事件的中断或事件信号输出。 ### RTC的工作流程 1. **输入/输出端口** RTC芯片可通过输入/输出端口接收外部信号,据此调整系统时间。例如,通过串行通信接口(UART、I2C、SPI等)接收计算机或其他设备下发的时间信息,或通过网络协议(如NTP)同步网络时间。 2. **定时器/计数器** RTC芯片内部通常集成一个或多个定时器/计数器,用于产生时间基准。定时器/计数器由预分频器和计数器构成:预分频器将系统时钟分频至合适的计数频率,计数器在该频率下累计经过的时间。当计数值达到设定值时,会触发中断事件,通知系统更新时间。 3. **中断控制器** RTC芯片还包含中断控制器,用于处理定时器的溢出事件。当定时器/计数器的计数值达到设定值时,会向中断控制器发出中断请求;中断控制器识别该请求后,触发相应的中断服务程序(ISR)执行,如更新系统时间、唤醒等待处理的任务等。 4. **系统时间的更新** 需要校准系统时间时,RTC芯片会执行一系列操作:首先,通过输入/输出端口接收新的时间信息;然后,使用定时器/计数器计算经过的时间差;接着,将该时间差累加到当前系统时间上;最后,通过中断控制器通知系统其他部分时间已更新。 # RTC API ## 头文件 *qosa_rtc.h* ## 函数概览 | **函数** | **说明** | | --- | --- | | *qosa_rtc_set_time()* | 设置系统RTC时间 | | *qosa_rtc_get_time()* | 获取系统RTC时间 | | *qosa_rtc_get_localtime()* | 获取本地时间(UTC时间 + 时区偏移) | | *qosa_rtc_get_timezone()* | 获取系统的时区偏移量 | | *qosa_rtc_set_timezone()* | 设置系统的时区偏移量 | | *qosa_rtc_gmtime_r()* | 将Unix时间戳转换为分解时间(*struct tm* 格式) | | *qosa_rtc_mktime()* | 将分解时间(*struct tm* 格式)转换为Unix时间戳 | | *qosa_rtc_set_alarm()* | 设置RTC闹钟时间 | | *qosa_rtc_get_alarm()* | 获取RTC闹钟时间 | | *qosa_rtc_enable_alarm()* | 启用或禁用RTC闹钟 | | *qosa_rtc_register_cb()* | 注册RTC回调函数 | | *qosa_rtc_set_cfg()* | 设置RTC配置 | | *qosa_rtc_get_cfg()* | 获取RTC配置 | | *qosa_rtc_print_time()* | 打印RTC时间到指定输出设备 | ## 函数详解 ### qosa_rtc_set_time - **功能描述** 设置系统RTC时间。 - **函数原型** ```c int qosa_rtc_set_time(qosa_time_t time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *time* | 输入 | qosa_time_t | Unix时间戳 | - **返回值说明** *0*:函数执行成功 *-1*:函数执行失败 ### qosa_rtc_get_time - **功能描述** 获取系统RTC时间。 - **函数原型** ```c int qosa_rtc_get_time(qosa_time_t *time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *time* | 输出 | qosa_time_t * | 指向 *qosa_time_t* 的指针,用于存储获取到的Unix时间戳 | - **返回值说明** *0*:函数执行成功 *-1*:函数执行失败 ### qosa_rtc_get_localtime - **功能描述** 获取本地时间(UTC时间 + 时区偏移)。 - **函数原型** ```c int qosa_rtc_get_localtime(qosa_time_t *time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *time* | 输出 | qosa_time_t * | 指向 *qosa_time_t* 的指针,用于存储获取到的本地时间戳 | - **返回值说明** *0*:函数执行成功 *-1*:函数执行失败 ### qosa_rtc_get_timezone - **功能描述** 获取系统的时区偏移量。 - **函数原型** ```c int qosa_rtc_get_timezone(void); ``` - **参数说明** 无 - **返回值说明** 时区偏移量(单位:15分钟) ### qosa_rtc_set_timezone - **功能描述** 设置系统的时区偏移量。 - **函数原型** ```c int qosa_rtc_set_timezone(int time_zone); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *time_zone* | 输入 | int | 时区偏移量;范围:-48~56;单位:15分钟 | - **返回值说明** 当前始终返回 *0*,无论操作成功还是失败 ### qosa_rtc_gmtime_r - **功能描述** 将Unix时间戳转换为分解时间(*struct tm* 格式)。 - **函数原型** ```c qosa_rtc_time_t *qosa_rtc_gmtime_r(const qosa_time_t *timer, qosa_rtc_time_t *result); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *timer* | 输入 | const qosa_time_t * | 指向Unix时间戳的指针 | | *result* | 输出 | *qosa_rtc_time_t** | 指向 *qosa_rtc_time_t* 的指针,用于存储转换后的分解时间;详见 [*qosa_rtc_time_t*](#qosartctime_t) | - **返回值说明** *result* 指针:函数执行成功 *NULL*:函数执行失败 ### qosa_rtc_mktime - **功能描述** 将分解时间(*struct tm* 格式)转换为Unix时间戳。 - **函数原型** ```c int qosa_rtc_mktime(qosa_rtc_time_t *rtc_time, qosa_time_t *timer); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *rtc_time* | 输入 | *qosa_rtc_time_t** | 指向 *qosa_rtc_time_t* 的指针,表示分解时间;详见 [*qosa_rtc_time_t*](#qosartctime_t) | | *timer* | 输出 | qosa_time_t * | 指向 *qosa_time_t* 的指针,用于存储转换后的时间戳 | - **返回值说明** 当前始终返回 *QOSA_OK*,无论操作成功还是失败 ### qosa_rtc_set_alarm - **功能描述** 设置RTC闹钟时间。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_set_alarm(qosa_rtc_time_t *rtc_time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *rtc_time* | 输入 | *qosa_rtc_time_t** | 指向 *qosa_rtc_time_t* 的指针,表示闹钟时间;详见 [*qosa_rtc_time_t*](#qosartctime_t) | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 ### qosa_rtc_get_alarm - **功能描述** 获取RTC闹钟时间。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_get_alarm(qosa_rtc_time_t *rtc_time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *rtc_time* | 输出 | *qosa_rtc_time_t** | 指向 *qosa_rtc_time_t* 的指针,用于存储获取到的闹钟时间;详见 [*qosa_rtc_time_t*](#qosartctime_t) | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 ### qosa_rtc_enable_alarm - **功能描述** 启用或禁用RTC闹钟。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_enable_alarm(qosa_uint8_t on_off); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *on_off* | 输入 | qosa_uint8_t | 启用或禁用闹钟
*1*:启用闹钟
*0*:禁用闹钟 | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 ### qosa_rtc_register_cb - **功能描述** 注册RTC事件回调函数。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_register_cb(qosa_rtc_cb_ptr cb); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *cb* | 输入 | *qosa_rtc_cb_ptr* | 指向回调函数的指针;详见 [*qosa_rtc_cb_ptr*](#qosartccb_ptr) | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 #### qosa_rtc_cb_ptr - **功能描述** 接收闹钟到期通知的回调函数原型。 - **函数原型** ```c typedef void (*qosa_rtc_cb_ptr)(void); ``` ### qosa_rtc_set_cfg - **功能描述** 设置RTC配置。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_set_cfg(qosa_rtc_cfg_t *cfg); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *cfg* | 输入 | *qosa_rtc_cfg_t** | 指向 *qosa_rtc_cfg_t* 的指针,表示配置信息;详见 [*qosa_rtc_cfg_t*](#qosartccfg_t) | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 ### qosa_rtc_get_cfg - **功能描述** 获取RTC配置。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_get_cfg(qosa_rtc_cfg_t *cfg); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *cfg* | 输出 | *qosa_rtc_cfg_t** | 指向 *qosa_rtc_cfg_t* 的指针,用于存储获取到的配置信息;详见 [*qosa_rtc_cfg_t*](#qosartccfg_t) | - **返回值说明** *QOSA_RTC_ERR_OK*:函数执行成功 其他值(详见 [*qosa_rtc_error_e*](#qosartcerror_e)):函数执行失败 ### qosa_rtc_print_time - **功能描述** 打印RTC时间到指定输出设备。 - **函数原型** ```c qosa_rtc_error_e qosa_rtc_print_time(qosa_rtc_time_t *rtc_time); ``` - **参数说明** | **参数名** | **输入/输出** | **类型** | **说明** | | --- | --- | --- | --- | | *rtc_time* | 输入 | *qosa_rtc_time_t** | 指向 *qosa_rtc_time_t* 的指针,表示要打印的RTC时间;详见 [*qosa_rtc_time_t*](#qosartctime_t) | - **返回值说明** 当前始终返回 *QOSA_RTC_ERR_OK*,无论操作成功还是失败 ## 结构体定义 ### qosa_time_info_t 通用时间结构体定义如下: ```c typedef struct { qosa_uint64_t seconds; qosa_uint64_t microseconds; } qosa_time_info_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *seconds* | qosa_uint64_t | 自1970年1月1日00:00:00 UTC起经过的整秒数 | | *microseconds* | qosa_uint64_t | 当前这一秒内经过的微秒数 | ### qosa_rtc_time_t RTC时间结构体定义如下: ```c typedef struct { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; } qosa_rtc_time_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *tm_sec* | int | 秒;范围:0~59 | | *tm_min* | int | 分钟;范围:0~59 | | *tm_hour* | int | 小时;范围:0~23 | | *tm_mday* | int | 日;范围:1~31 | | *tm_mon* | int | 月;范围:0~11;*0*:1月,*11*:12月 | | *tm_year* | int | 年,从1900起算;如2024年对应值为124 | | *tm_wday* | int | 星期;范围:0~6;*0*:周日,*6*:周六 | ### qosa_rtc_cfg_t RTC配置结构体定义如下: ```c typedef struct { qosa_rtc_enable_e nv_cfg; qosa_rtc_enable_e rtc_cfg; qosa_rtc_enable_e nwt_cfg; qosa_rtc_tz_e tz_cfg; } qosa_rtc_cfg_t; ``` | **参数** | **类型** | **说明** | | --- | --- | --- | | *nv_cfg* | *qosa_rtc_enable_e* | 启动时是否读取NV中保存的时间作为RTC初始值;详见 [*qosa_rtc_enable_e*](#qosartcenable_e)
*QOSA_RTC_CFG_ENABLE*:读取
*QOSA_RTC_CFG_DISABLE*:不读取
默认值:*QOSA_RTC_CFG_DISABLE* | | *rtc_cfg* | *qosa_rtc_enable_e* | 启动时是否读取RTC寄存器时间作为初始值;若VBAT断电则时间重置为2000-01-01;详见 [*qosa_rtc_enable_e*](#qosartcenable_e)
*QOSA_RTC_CFG_ENABLE*:读取
*QOSA_RTC_CFG_DISABLE*:不读取
默认值:*QOSA_RTC_CFG_DISABLE* | | *nwt_cfg* | *qosa_rtc_enable_e* | 连接基站后是否将基站时间同步到RTC;详见 [*qosa_rtc_enable_e*](#qosartcenable_e)
*QOSA_RTC_CFG_ENABLE*:同步
*QOSA_RTC_CFG_DISABLE*:不同步
默认值:*QOSA_RTC_CFG_DISABLE* | | *tz_cfg* | *qosa_rtc_tz_e* | 网络注册后的时区配置;详见 [*qosa_rtc_tz_e*](#qosartctz_e)
默认值:*QOSA_RTC_CFG_TZ_UPDATE* | ## 枚举定义 ### qosa_rtc_enable_e RTC启用配置枚举定义如下: ```c typedef enum { QOSA_RTC_CFG_DISABLE = 0, QOSA_RTC_CFG_ENABLE = 1, } qosa_rtc_enable_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_RTC_CFG_DISABLE* | 禁用 | | *QOSA_RTC_CFG_ENABLE* | 启用 | ### qosa_rtc_tz_e RTC时区配置(网络注册后)枚举定义如下: ```c typedef enum { QOSA_RTC_CFG_TZ_UPDATE = 0, QOSA_RTC_CFG_TZ_NO_UPDATE = 1, QOSA_RTC_CFG_TZ_RESET_ZERO = 2, } qosa_rtc_tz_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_RTC_CFG_TZ_UPDATE* | 网络注册后更新为网络时区 | | *QOSA_RTC_CFG_TZ_NO_UPDATE* | 网络注册后保持原时区不变 | | *QOSA_RTC_CFG_TZ_RESET_ZERO* | 网络注册后将时区重置为0 | ### qosa_rtc_error_e RTC结果码枚举定义如下: ```c #define QOSA_COMPONENT_API_RTC (0x01 << 8) typedef enum { QOSA_RTC_ERR_OK = 0, QOSA_RTC_ERR_INVALID_PARAM = 1 | QOSA_COMPONENT_API_RTC, QOSA_RTC_ERR_SET_PARAM, QOSA_RTC_ERR_GET_PARAM, } qosa_rtc_error_e; ``` | **成员** | **说明** | | --- | --- | | *QOSA_RTC_ERR_OK* | 函数执行成功 | | *QOSA_RTC_ERR_INVALID_PARAM* | 无效参数 | | *QOSA_RTC_ERR_SET_PARAM* | 配置错误 | | *QOSA_RTC_ERR_GET_PARAM* | 读取错误 | # 应用逻辑流程图 ```{figure} images/board_LNtBw0nAOhg239bkdqtc1vGNnVf.jpg :align: center :alt: image ``` # 示例代码 完整示例代码请查看 [https://github.com/UniRTOS/UniRTOS-Doc-Examples/blob/main/peripheral/rtc/rtc_demo.c]()