Назад

Чтение виртуальных часов DS1307 RTC через I2C на Raspberry Pi Pico

Введение

Хотели когда-нибудь добавить часы реального времени (RTC) в свой проект, но не имели под рукой нужного оборудования? С Velxio вы можете симулировать полное чтение I2C RTC, используя Raspberry Pi Pico и виртуальный DS1307 — прямо в вашем браузере. В этом руководстве мы разберём схему, код и ключевые концепции, чтобы вы могли уверенно использовать I2C-коммуникацию в своих проектах.

Разбор схемы

Давайте начнём с рассмотрения схемы. Откройте пример в Velxio, и вы увидите следующие компоненты:

Схема pico-i2c-rtc-read на холсте симулятора Velxio

Схема проста: Raspberry Pi Pico (nano-rp2040) подключён к двум светодиодам и виртуальному DS1307 RTC (не показан как отдельный компонент — RTC встроен в симуляцию). Светодиоды используются как визуальные индикаторы активности I2C.

Оба светодиода используют общий земляной контакт (GND.1). Шина I2C состоит из линий SDA (данные) и SCL (тактирование). Часы DS1307 RTC внутренне подключены к этим линиям по адресу 0x68. Светодиоды не обязательны для I2C-коммуникации, но они дают визуальный сигнал о переключении линий.

Чтобы собрать эту схему самостоятельно, вы можете использовать палитру компонентов Velxio:

Модальное окно выбора компонентов Velxio с просмотром деталей по категориям

Найдите “Raspberry Pi Pico” и “LED”, затем соедините их, как описано. Панель инструментов холста помогает масштабировать и располагать компоненты:

Панель инструментов холста Velxio над окном симуляции

Разбор кода

Теперь давайте углубимся в код. Скетч использует библиотеку Wire (встроенную) для связи с DS1307 через I2C. Вот полный код:

// Raspberry Pi Pico — I2C DS1307 RTC Read
// Reads time from virtual RTC at address 0x68

#include <Wire.h>

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

void setup() {
  Serial.begin(115200);
  delay(500);
  Wire.begin();
  Serial.println("=== Pico I2C RTC Read ===");
  Serial.println("Reading DS1307 at 0x68 (system time)");
  Serial.println();
}

void loop() {
  // Set register pointer to 0
  Wire.beginTransmission(0x68);
  Wire.write(0x00);
  Wire.endTransmission();

  // Read 7 bytes: sec, min, hr, dow, date, month, year
  Wire.requestFrom(0x68, 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());

    const char* days[] = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

    Serial.print("Time: ");
    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("  Date: ");
    Serial.print(days[dow]); Serial.print(' ');
    if (date < 10) Serial.print('0'); Serial.print(date); Serial.print('/');
    if (month < 10) Serial.print('0'); Serial.print(month); Serial.print('/');
    Serial.print("20"); if (year < 10) Serial.print('0'); Serial.println(year);
  } else {
    Serial.println("RTC not responding!");
  }

  delay(1000);
}

Как это работает

  1. Настройка: Мы запускаем последовательную связь на скорости 115200 бод и инициализируем шину I2C с помощью Wire.begin(). Часы DS1307 находятся по адресу 0x68.

  2. Цикл: Каждую секунду мы:

    • Отправляем beginTransmission на адрес 0x68, записываем 0x00 (указатель регистра на регистр секунд) и завершаем передачу endTransmission.
    • Запрашиваем 7 байт от RTC с помощью Wire.requestFrom(0x68, 7).
    • Читаем каждый байт и преобразуем из BCD (двоично-десятичного кода) в десятичный с помощью вспомогательной функции bcdToDec.
    • Форматируем и выводим время и дату в последовательный монитор.
  3. Преобразование BCD: DS1307 хранит значения времени в формате BCD. Например, байт 0x45 представляет 45 в BCD (4*10 + 5 = 45). Функция bcdToDec извлекает цифру десятков (старший полубайт) и цифру единиц (младший полубайт) и объединяет их.

  4. Маскирование: Мы применяем маски к определённым регистрам:

    • Секунды: & 0x7F очищает бит CH (остановка часов).
    • Часы: & 0x3F очищает бит режима 12/24 часа (предполагается 24-часовой режим).

Ключевые концепции

Частые ошибки и советы по отладке

Предлагаемые расширения

Попробуйте сами!

Готовы экспериментировать? Откройте живой пример в Velxio и запустите симуляцию. Вы увидите время, выводимое в последовательный монитор каждую секунду. Измените код, чтобы изменить интервал обновления или добавить новые функции.

Запустить пример Pico I2C RTC Read

Удачной симуляции!


Поделиться:
David Montero

Автор

David Montero

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

GitHub velxio.dev

Похожие статьи


Предыдущая статья
Pico I2C EEPROM Чтение/Запись: Симуляция энергонезависимой памяти в вашем браузере
Следующая статья
Pico I2C Сканер: Поиск устройств на шине