返回

在 Velxio 上使用 DS1307 的 I2C RTC 时钟

引言

是否曾想为你的 Arduino 项目添加一个实时时钟,但手头没有硬件?借助 Velxio,你可以在浏览器中直接模拟一个 I2C RTC(DS1307)。在本教程中,我们将构建一个简单的 I2C 读取器,从虚拟 DS1307 获取当前时间和日期,并将其打印到串行监视器。无需外部库——只需内置的 Wire 库。

Velxio 模拟器画布上 i2c-rtc-read 的电路图

电路讲解

这个示例非常简单,因为 DS1307 已经集成到虚拟 Arduino Uno 板中。无需添加任何外部元件或导线。I2C 总线(SDA 在 A4,SCL 在 A5)在内部连接到地址为 0x68 的 DS1307。唯一的元件就是 Arduino Uno 本身。

Velxio 元件选择器模态框,按类别浏览零件

首先,打开 Velxio 编辑器,从元件选择器中选择一个 Arduino Uno。DS1307 已内置于模拟环境中,因此无需单独添加。电路已准备就绪。

代码讲解

让我们逐步解析代码。

包含与定义

#include <Wire.h>

#define DS1307_ADDR 0x68

我们包含 Wire 库用于 I2C 通信,并将 DS1307 的 I2C 地址定义为 0x68。

BCD 转十进制

byte bcdToDec(byte val) {
  return ((val >> 4) * 10) + (val & 0x0F);
}

DS1307 以二进制编码十进制(BCD)格式存储时间值。这个辅助函数将 BCD 字节转换为常规十进制数。

初始化

void setup() {
  Wire.begin();
  Serial.begin(9600);

  Serial.println("===========================");
  Serial.println("  DS1307 RTC 读取器 (I2C)");
  Serial.println("===========================");
  Serial.println();
}

我们初始化 I2C 总线和串行通信,波特率为 9600。然后打印一个标题。

主循环

void loop() {
  // 将寄存器指针设置为 0(秒寄存器)
  Wire.beginTransmission(DS1307_ADDR);
  Wire.write(0x00);
  Wire.endTransmission();

  // 请求 7 个字节:秒、分、时、星期、日、月、年
  Wire.requestFrom(DS1307_ADDR, 7);

  if (Wire.available() >= 7) {
    byte sec   = bcdToDec(Wire.read() & 0x7F);
    byte min   = bcdToDec(Wire.read());
    byte hr    = bcdToDec(Wire.read() & 0x3F);
    byte dow   = bcdToDec(Wire.read());
    byte date  = bcdToDec(Wire.read());
    byte month = bcdToDec(Wire.read());
    byte year  = bcdToDec(Wire.read());

    // 打印格式化时间
    Serial.print("时间: ");
    if (hr < 10) Serial.print("0");
    Serial.print(hr);
    Serial.print(":");
    if (min < 10) Serial.print("0");
    Serial.print(min);
    Serial.print(":");
    if (sec < 10) Serial.print("0");
    Serial.print(sec);

    Serial.print("  日期: ");
    if (date < 10) Serial.print("0");
    Serial.print(date);
    Serial.print("/");
    if (month < 10) Serial.print("0");
    Serial.print(month);
    Serial.print("/20");
    if (year < 10) Serial.print("0");
    Serial.println(year);
  } else {
    Serial.println("错误: 无法读取 RTC");
  }

  delay(1000);
}

在主循环中,我们首先通过发送单个字节 0x00 将 DS1307 的寄存器指针设置为 0(秒寄存器)。然后从 RTC 请求 7 个字节。DS1307 以 BCD 格式返回秒、分、时、星期、日、月和年。我们屏蔽秒的最高位(第 7 位是时钟暂停标志)和时的最高两位(第 6-7 位是模式/上午-下午)。转换后,我们打印时间和日期,并补前导零。如果可用字节少于 7 个,则打印错误信息。最后,等待 1 秒。

关键概念

常见陷阱与调试技巧

Velxio 编辑器工具栏,包含编译和运行控件

建议的扩展

亲自尝试

准备好看看效果了吗?在 Velxio 上打开实时示例,点击运行按钮。你将看到时间在串行监视器中每秒更新一次。

在 Velxio 上启动 I2C RTC 读取器

Velxio 画布工具栏,位于模拟视口上方

祝模拟愉快!


分享到:
David Montero

作者

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

相关文章


上一篇
使用Arduino进行I2C EEPROM读写:完整指南
下一篇
使用Arduino的I2C扫描仪:发现总线上的每个设备