2.8. RTC 时间

Overview

提供 RTC 系统时间应用示例、配置介绍和常见问题。

2.8.1. 应用实例

示例演示:

  • 设置和获取系统的 RTC 时间

  • 获取系统 NTP 时间

  • 获取系统运行时间

  • 闹钟响铃

  • 时间字符串格式化方法

  • gettimeofday() 使用方法

  • time_lapse() 使用方法

example: 具体示例代码详见 apps/common/example/peripheral/rtc/main.c ,示例工程实现需在 apps/demo/demo_DevKitBoard/include/demo_config.h 中开启宏 USE_RTC_TEST_DEMO

Important

  1. 测试例程rtc默认是本地sdk编译时间

  2. 用户若要自己设置rtc时间,则还需要开启宏 USER_SET_RTC_TIME ,并在user_set_rtc_time()函数中设置时间参数

  3. 在user_set_rtc_time()函数中设置的时间一定要比当前编译的时间偏后,否则rtc会按当前编译时间计时间

  • RTC介绍 79系列RCT支持内部RC200k走时和外部32.768k时钟走时,支持外部供电和内部供电两种方式。支持闹钟响铃唤醒,能提供年月日时分秒以及星期等信息。 使用外部32.768K时钟能更精确的走时,内部RC会产生走时误差。 需要注意的是当使用内部供电的时候需要将HSB配置为2,LSB配置为5以降低IC于RTC模块通信时钟.

  • RTC版籍参数说明

    #ifdef CONFIG_RTC_ENABLE
     //下面配置为7913使用内部RTC的配置使用内部电源的配置
      const struct rtc_init_config rtc_init_data = {
        .rtc_clk_sel = RTC_CLK_SEL_INSIDE,
        .rtc_power_sel = RTCVDD_FLOAT,
        .rtc_power_res_sel = RES_6K,
      };
    #endif
    //下面配置为使用外部32.768k时钟配置
    const struct rtc_init_config rtc_init_data = {
      .rtc_clk_sel = RTC_CLK_SEL_OUTSIDE,
      .rtc_power_sel = RTCVDD_SUPPLY_OUTSIDE,
    };
    enum sel_rtc_clk {
      RTC_CLK_SEL_INSIDE = 0,//使用内部RC时钟
      RTC_CLK_SEL_OUTSIDE, //使用外部32.768K时钟
    };
    enum sel_rtcvdd { //提供了三种供电选择
      RTCVDD_SUPPLY_OUTSIDE = 0, //使用外部供电
      RTCVDD_SUPPLY_BOUND_INSIDE_VDDIO,//内部已经将RTCVDDIO供电
      RTCVDD_FLOAT,//浮空需要自己配置电源库里已经做了操作 列如7913,7915需要使用内部供电
    };
    

2.8.2. 常见问题

  • 如何添加 RTC 设备并进行 RTC 初始化? 答:在 board.c 中添加 RTC 设备并进行 RTC 初始化:

    //设备列表 device_table 添加RTC设备,默认demo_hello和demo_wifi已经添加,例如demo_hello的board.c如下。
    REGISTER_DEVICES(device_table) = {
        {"rtc", &rtc_dev_ops, NULL},//添加RTC设备
    };
    
    //添加RTC初始化函数,系统上电会调用(有wifi功能的在board_init()函数检查有没有rtc_early_init(),没有就需要加上该函数),如demo_hello的board.c
    void board_init()
    {
        rtc_early_init();
    }
    
  • 如何获取内部RTC电压值
    u8 rtc_vdd_value;
    int get_rtc_vddio();
    rtc_vdd_value = get_rtc_vddio();
    
  • 当使用内部RTC时如何使用外部PR0, PR1引脚用做GPIO,用法与其余GPIO一样
    u8 time=0;
    time = ++time % 2;
    if(time){
      gpio_direction_output(IO_PORT_PR_00, 1);
      gpio_direction_output(IO_PORT_PR_01, 1);
    }else{
      gpio_direction_output(IO_PORT_PR_00, 0);
      gpio_direction_output(IO_PORT_PR_01, 0);
    }
    
  • 当使用内部电源时需要注意关机后的电压需要配置到3.2v不然会存在关机不走时
    #define TCFG_LOWPOWER_VDDIOW_LEVEL                              VDDIOW_VOL_32V       //弱VDDIO电压档位
    

Note

注意事项:
  1. rtc_early_init()

  2. RTC内部系统有一个SDK发布时间作为默认时间:当应用层重定义set_rtc_default_time原函数时(例如上述测试例子 的set_rtc_default_time函数定义),则设置默认时间为该函数设置的时间。

  3. 当没有定义set_rtc_default_time函数则是系统默认时间为SDK发布时间,RTC设置时间不能小于默认时间。

  4. 外部晶振接芯片的PR0和PR1引脚,当在某些封装中PR口可能会和其他IO内绑在一块,此时在board_init()函数首先需要把其他IO关闭上下拉并设置输入模式,才能调用rtc_early_init初始化RTC。

  • 外部晶振已经接了,为什么RTC不走时?

    答:① 先查看外部晶振是否震荡起来,如果不震荡,确定晶振是否已坏,同时晶振引脚需要接电容到地。② 检查芯片封装是否有内部IO和晶振的PR口内绑在一起,有则设置IO关闭上下拉并设置输入模式。

2.8.3. API参考

  • rtc 的 API 接口说明如下:

Functions

void *dev_open(const char *name, void *arg)

dev_open:用于打开一个设备

Parameters
  • name – 设备名称

  • arg – 控制参数,一般为NULL

int dev_read(void *device, void *buf, u32 len)

dev_read:用于设备数据的接收。

Parameters
  • device – 设备句柄

  • buf – 要读入的 buffer 缓冲区

  • len – 要读入的长度

int dev_write(void *device, void *buf, u32 len)

dev_write:用于设备数据的发送。

Parameters
  • device – 设备句柄

  • buf – 要写入的 buffer 缓冲区

  • len – 要写入的长度

int dev_ioctl(void *device, int cmd, u32 arg)

dev_ioctl:用于对设备进行控制和参数的修改

Parameters
  • device – 设备句柄

  • cmd – 设备控制命令

  • arg – 控制参数

int dev_close(void *device)

dev_close:用于关闭一个设备

Parameters

device – 设备句柄