外观
I2C DS1307 示例
2026-05-15
概述
本文介绍如何在 睿擎工业开发平台 中创建并运行 I2C 总线通信 示例工程。通过驱动 DS1307 实时时钟芯片,演示了利用 RT-Thread 设备驱动框架进行 I2C 总线操作的完整流程。
DS1307 RTC
DS1307 是一款低功耗、全 BCD 码时钟日历实时时钟芯片。它通过 I2C 接口提供秒、分、时、日、星期、月和年信息,并支持闰年补偿(有效期至 2100 年)。芯片内部包含一个电池备份电路,在主电源掉电时可自动切换到备用电池供电,确保时钟持续稳定运行。
硬件连接
开发板的 I2C 与 RTC 硬件已经连接,RTC 芯片位置如图所示:

查手册获取 RTC 的设备地址
根据 DS1307 数据手册可知:
- DS1307 的 I2C 从设备地址为固定的
0x68(7 位地址)

读取 DS1307 RTC 设备的实时时钟
本示例展示如何通过 I2C 总线访问 DS1307 RTC 设备,启动其内部振荡器,并读取其年月日、时分秒等时间信息。
构建与烧录
创建工程点击展开
依次点击 “文件” -> “新建” -> "RT-Thread RuiChing App 项目"。

在弹出新建向导中选择 开发版 、BSP: 、示例 、 调试器/下载器。选择好之后点击 “完成”。

点击 “完成” 后,等待工程创建完成。

创建完成。

构建工程点击展开
单击工程使工程进入 Active-Debug 模式。

点击工具栏上的构建按钮进行工程编译。

构建成功后,会显示构建成功的信息。

固件下载点击展开
固化驱动

固化 APP

核心示例代码
i2c_ds1307_example.c
static rt_err_t _ds1307_read_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg,
rt_uint8_t *buf, rt_uint8_t len)// ds1307 读寄存器
{
struct rt_i2c_msg msgs[2];
msgs[0].addr = DS1307_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[1].addr = DS1307_ADDR;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = buf;
msgs[1].len = len;
if (rt_i2c_transfer(bus, msgs, 2) != 2)
{
return -RT_ERROR;
}
return RT_EOK;
}
static rt_err_t _ds1307_write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg,
rt_uint8_t *buf, rt_uint8_t len)// ds1307 写寄存器
{
struct rt_i2c_msg msg;
rt_uint8_t tmp[8];
if (len > 7)
{
return -RT_ERROR;
}
tmp[0] = reg;
rt_memcpy(&tmp[1], buf, len);
msg.addr = DS1307_ADDR;
msg.flags = RT_I2C_WR;
msg.buf = tmp;
msg.len = len + 1;
if (rt_i2c_transfer(bus, &msg, 1) != 1)
{
return -RT_ERROR;
}
return RT_EOK;
}
static rt_uint8_t _bcd_to_dec(rt_uint8_t bcd)
{
return ((bcd >> 4) * 10) + (bcd & 0x0F);
}
static rt_err_t _ds1307_get_time(struct rt_i2c_bus_device *bus, struct tm *time)// ds1307 获取时间
{
rt_err_t ret = RT_EOK;
rt_uint8_t buf[7];
ret = _ds1307_read_reg(bus, DS1307_REG_SECOND, buf, 7);
if (ret != RT_EOK)
{
return ret;
}
time->tm_sec = _bcd_to_dec(buf[0] & 0x7F);
time->tm_min = _bcd_to_dec(buf[1]);
time->tm_hour = _bcd_to_dec(buf[2] & 0x3F);
time->tm_wday = _bcd_to_dec(buf[3]);
time->tm_mday = _bcd_to_dec(buf[4]);
time->tm_mon = _bcd_to_dec(buf[5]) - 1;
time->tm_year = _bcd_to_dec(buf[6]) + 100;
return RT_EOK;
}
static rt_err_t _ds1307_start_clock(struct rt_i2c_bus_device *bus)// ds1307 开启时钟/
{
rt_err_t ret = RT_EOK;
rt_uint8_t sec = 0;
ret = _ds1307_read_reg(bus, DS1307_REG_SECOND, &sec, 1);
if (ret != RT_EOK)
{
return ret;
}
if (sec & DS1307_CH_BIT)
{
sec &= ~DS1307_CH_BIT;
ret = _ds1307_write_reg(bus, DS1307_REG_SECOND, &sec, 1);
if (ret != RT_EOK)
{
return ret;
}
rt_kprintf("DS1307 clock started\n");
}
return RT_EOK;
}
int i2c_ds1307_example(void)
{
struct tm time;
int i = 0;
if (_ds1307_device_init() != RT_EOK)
{
return -RT_ERROR;
}
if (_ds1307_start_clock(_i2c_bus) != RT_EOK)
{
rt_kprintf("DS1307 start clock failed\n");
return -RT_ERROR;
}
for (i = 0; i < 10; i++)
{
if (_ds1307_get_time(_i2c_bus, &time) == RT_EOK)
{
rt_kprintf("DS1307 time: 20%02d-%02d-%02d %02d:%02d:%02d\n",
time.tm_year - 100, time.tm_mon + 1, time.tm_mday,
time.tm_hour, time.tm_min, time.tm_sec);
}
else
{
rt_kprintf("read DS1307 time failed\n");
}
rt_thread_mdelay(1000);
}
return RT_EOK;
}运行示例
操作步骤
- 将程序下载到开发板
- 打开串口终端连接开发板
- 系统在启动后
main函数会自动调用其内容函数 - 也可在终端输入
i2c_ds1307_example命令
预期结果
验证 RTC 芯片的基本通信及 BCD 码时间解析功能正常。
RT-Thread 终端
msh />DS1307 time: 2000-01-01 00:27:41
DS1307 time: 2000-01-01 00:27:42
DS1307 time: 2000-01-01 00:27:43
DS1307 time: 2000-01-01 00:27:44
DS1307 time: 2000-01-01 00:27:45
DS1307 time: 2000-01-01 00:27:46
DS1307 time: 2000-01-01 00:27:47
DS1307 time: 2000-01-01 00:27:48
DS1307 time: 2000-01-01 00:27:49
DS1307 time: 2000-01-01 00:27:50
msh />i2c_ds1307_example
DS1307 time: 2000-01-01 00:03:54
DS1307 time: 2000-01-01 00:03:55
DS1307 time: 2000-01-01 00:03:56
DS1307 time: 2000-01-01 00:03:57
DS1307 time: 2000-01-01 00:03:58
DS1307 time: 2000-01-01 00:03:59
DS1307 time: 2000-01-01 00:04:00
DS1307 time: 2000-01-01 00:04:01
DS1307 time: 2000-01-01 00:04:02
DS1307 time: 2000-01-01 00:04:03