Шрифт:
Следующие фрагменты кода тоже взяты из примеров, поставляемых с библиотекой:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
void setup
{
Serial.begin(9600);
Wire.begin;
RTC.begin
if (! RTC.isrunning) {
Serial.println("RTC is NOT running!");
// записать в модуль дату и время компиляции скетча
RTC.adjust(DateTime(__DATE__, __TIME__));
}
}
void loop {
DateTime now = RTC.now;
Serial.print(now.year, DEC);
Serial.print('/');
Serial.print(now.month, DEC);
Serial.print('/');
Serial.print(now.day, DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek]);
Serial.print(") ");
Serial.print(now.hour, DEC);
Serial.print(':');
Serial.print(now.minute, DEC);
Serial.print(':');
Serial.print(now.second, DEC);
Serial.println;
delay(1000);
}
Если вам интересно увидеть, как в действительности выполняются взаимодействия через интерфейс I2C, просто загляните в файлы библиотеки. Например, исходный код библиотеки RTClib хранится в файлах RTClib.h и RTClib.cpp. Эти файлы находятся в папке libraries/RTClib.
Например, в файле RTClib.cpp можно найти определение функции now:
DateTime RTC_DS1307::now {
Wire.beginTransmission(DS1307_ADDRESS);
Wire.write(i);
Wire.endTransmission;
Wire.requestFrom(DS1307_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire.read & 0x7F);
uint8_t mm = bcd2bin(Wire.read);
uint8_t hh = bcd2bin(Wire.read);
Wire.read;
uint8_t d = bcd2bin(Wire.read);
uint8_t m = bcd2bin(Wire.read);
uint16_t y = bcd2bin(Wire.read) + 2000;
return DateTime (y, m, d, hh, mm, ss);
}
Функция Wire.read возвращает значения в двоично-десятичном формате (Binary-Coded Decimal, BCD), поэтому они преобразуются в байты с помощью библиотечной функции bcd2bin.
В формате BCD байт делится на два 4-битных полубайта. Каждый полубайт представляет одну цифру двузначного десятичного числа. Так, число 37 в формате BCD будет представлено как 0011 0111. Первые четыре бита соответствуют десятичному значению 3, а вторые четыре бита — значению 7.
В заключение
В этой главе вы познакомились с интерфейсом I2C и приемами его использования для организации взаимодействий плат Arduino с периферийными устройствами и другими платами Arduino.
В следующей главе мы исследуем еще одну разновидность последовательного интерфейса, используемого для взаимодействий с периферией. Он называется 1-Wire. Этот интерфейс не получил такого широкого распространения, как I2C, но он используется в популярном датчике температуры DS18B20.
8. Взаимодействие с устройствами 1-Wire
Шина 1-Wire служит целям, похожим на цели шины I2C (глава 7), то есть она обеспечивает возможность взаимодействий микроконтроллеров с периферийными устройствами посредством минимального количества линий передачи данных. Стандарт 1-Wire, разработанный в компании Dallas Semiconductor, свел потребность в линиях до логического минимума — всего одной. Шина имеет более низкое быстродействие, чем I2C, но обладает интересной особенностью — паразитным питанием (parasitic power), позволяющее подключать периферийные устройства к микроконтроллеру всего двумя проводами: GND (ground — земля) и комбинированным проводом питания и передачи данных.
Шина 1-Wire поддерживается более узким диапазоном устройств, чем I2C. Большинство из них производят компании Dallas Semiconductor и Maxim. К их числу относятся устройства идентификации картриджей для принтеров, флеш-память и ЭСППЗУ, а также АЦП. Однако наибольшую популярность среди устройств 1-Wire у радиолюбителей завоевал температурный датчик DS18B20 компании Dallas Semiconductor.
Аппаратная часть 1-Wire
На рис. 8.1 показано, как подключить датчик DS18B20 к плате Arduino, используя всего два контакта и режим паразитного питания DS18B20.
Рис. 8.1. Подключение устройства 1-Wire к плате Arduino
1-Wire — это именно шина, а не соединение «точка–точка». К ней можно подключить до 255 устройств, взяв за основу схему, изображенную на рис. 8.1. Если вы пожелаете использовать устройство в режиме нормального питания, то сопротивление 4,7 кОм можно убрать, а вывод Vdd датчика DS18B20 вместо GND соединить непосредственно с контактом 5 В на плате Arduino.
Протокол 1-Wire