# 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]()