RTC设备
RTC简介
RTC(Real-Time Clock)实时时钟可以提供精确的实时时间,它可以用于产生年、月、日、时、分、秒等信息。UC8088采用内部32.768KHz时钟作为RTC时钟源。并且添加RTC报警功能,设置RTC报警日期和时间后在RTC设备计时到达后会产生一个RTC报警中断。
驱动支持
访问RTC设备前,需要保证相关驱动配置已选中。
Windows环境:利用RT-Thread官方env工具直接在代码根目录下执行menuconfig进入配置。
Linux环境:在代码根目录下执行scons --menuconfig进入配置。
RTC驱动所在路径如下:
RT-Thread Components -> Device Drivers -> Using RTC device drivers
访问RTC设备
访问RTC设备,库中提供了以下接口:
函数 | 描述 |
---|---|
rt_device_find() | 根据RTC名称查找设备获取设备句柄 |
rt_device_control() | 控制RTC设备 |
查找RTC设备
查找RTC设备,函数原型如下所示:
rt_device_t rt_device_find(const char* name);
-
参数
[IN]name:RTC设备名称,目前注册到的系统中的RTC设备名称为"rtc"。
-
返回值
RT_NULL:失败,设备不存在。
非RT_NULL:成功,该返回值是操作RTC设备的句柄,在后续的接口中作为函数入参。
控制RTC设备
控制RTC设备,函数原型如下所示:
rt_err_t rt_device_control(rt_device_t dev, int cmd, void* arg);
-
参数
[IN]dev:RTC设备句柄,查找RTC设备函数的返回值
[IN]cmd:命令控制字,在这里主要支持以下宏定义:
// 宏定义所在文件相对路径: // rt-thread/include/rtdef.h #define RT_DEVICE_CTRL_RTC_GET_TIME 0x10 // 获取时间 #define RT_DEVICE_CTRL_RTC_SET_TIME 0x11 // 设置时间 #define RT_DEVICE_CTRL_RTC_GET_ALARM 0x12 // 获取告警 #define RT_DEVICE_CTRL_RTC_SET_ALARM 0x13 // 设置告警
[INOUT]arg:对应结构体为 rtc_time_t、rtc_alarm_t还有涉及到的枚举、宏等,详情请查看头文件定义,所在路径为:libraries/UC8088_HAL_Driver/inc/uc_rtc.h
-
返回值
0,正常
其他:错误,RT-Thread定义的错误类型。
RTC使用示例
使用示例需要配置menuconfig打开配置(默认关闭),路径如下:
wiota APP -> open rtc, default close(_RTC_APP_)
以下提供RTC测试实例,测试步骤如下:
- 根据RTC设备名称,获取RTC设备句柄。
- 设置RTC输出。
#include <rtthread.h>
#ifdef _RTC_APP_
#include <rtdevice.h>
#include "uc_rtc_app.h"
#include "uc_rtc.h"
#define RTC_DEVICE_NAME "rtc"
static rt_device_t rtc_dev = NULL;
int rtc_app_init(void)
{
rt_err_t ret = RT_EOK;
rtc_dev = rt_device_find(RTC_DEVICE_NAME);
if (rtc_dev == RT_NULL)
{
rt_kprintf("find %s failed!\n", RTC_DEVICE_NAME);
return RT_ERROR;
}
return ret;
}
void rtc_app_sample(void)
{
int ret = 0;
time_t rtc_time;
rtc_time = 30;
rt_kprintf("rtc test demo.\r\n");
ret = rtc_app_init();
if (ret != RT_EOK)
{
rt_kprintf("init rtc error.\r\n");
return;
}
if (rtc_dev != NULL)
{
ret = rt_device_control(rtc_dev, RT_DEVICE_CTRL_RTC_SET_TIME, &rtc_time);
if (ret != RT_EOK)
{
rt_kprintf("set rtc error.\r\n");
return;
}
while (1)
{
rt_thread_mdelay(3000);
ret = rt_device_control(rtc_dev,
RT_DEVICE_CTRL_RTC_GET_TIME,
&rtc_time);
if (ret != RT_EOK)
{
rt_kprintf("set rtc error.\r\n");
return;
}
else
{
rt_kprintf("rtc value = %d.\r\n", rtc_time);
}
}
}
else
{
rt_kprintf("rtc test error.\r\n");
}
}
void alarm_app_sample(void)
{
int ret = 0;
rtc_alarm_t rtc_time;
rt_kprintf("alarm test demo.\r\n");
rtc_time.year = 2022;
rtc_time.mon = 11;
rtc_time.day = 20;
rtc_time.hour = 10;
rtc_time.min = 0;
rtc_time.sec = 0;
rtc_time.week = 7;
rtc_time.mask = RTC_AM_YEAR | RTC_AM_MON | RTC_AM_DAY | RTC_AM_WEEK;
ret = rtc_app_init();
if (ret != RT_EOK)
{
rt_kprintf("init alarm error.\r\n");
return;
}
if(rtc_dev != NULL)
{
ret = rt_device_control(rtc_dev, RT_DEVICE_CTRL_RTC_SET_ALARM, &rtc_time);
if (ret != RT_EOK)
{
rt_kprintf("set alarm error.\r\n");
return;
}
rt_thread_mdelay(3000);
ret = rt_device_control(rtc_dev, RT_DEVICE_CTRL_RTC_GET_ALARM, &rtc_time);
if (ret != RT_EOK)
{
rt_kprintf("set alarm error.\r\n");
}
else
{
rt_kprintf("alarm time = %d-%d-%d %d:%d:%d,week = %d.\r\n",
rtc_time.year, rtc_time.mon, rtc_time.day,
rtc_time.hour, rtc_time.min, rtc_time.sec,
rtc_time.week);
}
}
else
{
rt_kprintf("alarm test error.\r\n");
}
}
#endif