Литмир - Электронная Библиотека
Содержание  
A
A

  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.

Программируем Arduino. Основы работы со скетчами - _58.jpg

Рис. 8.1. Подключение устройства 1-Wire к плате Arduino

1-Wire — это именно шина, а не соединение «точка–точка». К ней можно подключить до 255 устройств, взяв за основу схему, изображенную на рис. 8.1. Если вы пожелаете использовать устройство в режиме нормального питания, то сопротивление 4,7 кОм можно убрать, а вывод Vdd датчика DS18B20 вместо GND соединить непосредственно с контактом 5 В на плате Arduino.

Протокол 1-Wire

Так же как I2C, интерфейс 1-Wire использует понятия ведущего и ведомого устройств. Микроконтроллер играет роль ведущего, а периферийные устройства — ведомых. Каждое ведомое устройство еще на заводе получает уникальный идентификационный номер, который часто называют адресом, чтобы его можно было идентифицировать на шине, к которой подключено множество ведомых. Адрес имеет размер 64 бита, что позволяет иметь примерно 1,8 × 1019 разных идентификационных номеров.

Подобно I2C, протокол 1-Wire предусматривает переключение режима работы шины ведущим устройством на ввод и вывод, чтобы иметь возможность двусторонних взаимодействий. Однако в шине 1-Wire отсутствует отдельная линия передачи тактовых сигналов, поэтому нули и единицы передаются длинными и короткими импульсами. Импульс длительностью 60 мкс обозначает 0, а длительностью 15 мкс — 1.

Обычно линия данных находится под напряжением с уровнем HIGH, но, когда микроконтроллеру (ведущему) требуется послать команду устройству, он генерирует специальный импульс сброса с уровнем LOW длительностью не менее 480 мкс. Вслед за ним следует последовательность импульсов 1 и 0.

Библиотека OneWire

Работу с интерфейсом 1-Wire здорово упрощает библиотека OneWire, которая доступна по адресу http://playground.arduino.cc/Learning/OneWire.

Инициализация 1-Wire

Чтобы инициализировать Arduino как ведущее устройство на шине 1-Wire, сначала нужно подключить библиотеку OneWire:

#include <OneWire.h>

Затем создать экземпляр OneWire и указать, какой контакт Arduino будет использоваться как линия данных на шине 1-Wire. Эти два действия можно объединить в одну команду, а в роли линии данных использовать любой контакт на плате Arduino — достаточно просто передать номер контакта в виде параметра:

OneWire bus(10);

В данном случае роль линии данных шины будет играть контакт D10.

Сканирование шины

Поскольку каждое ведомое устройство, подключенное к шине, имеет уникальный идентификационный номер, присвоенный на заводе, нужен какой-то способ определить адреса устройств, подключенных к шине. Было бы неблагоразумно «зашивать» адреса устройств в скетч, потому что в случае замены новое ведомое устройство будет иметь уже другой адрес и скетч не сможет обращаться к нему. Поэтому ведущее устройство (Arduino) должно создать своеобразную опись устройств на шине. Здесь следует отметить, что первые 8 бит в адресе определяют «семейство», которому принадлежит устройство, то есть по ним можно определить, является ли устройство, например, датчиком DS18B20 или относится к какому-то другому типу.

В табл. 8.1 перечислены некоторые из наиболее известных кодов семейств для шины 1-Wire. Полный список можно найти на странице http://owfs.sourceforge.net/family.html.

Таблица 8.1. Коды семейств устройств для шины 1-Wire

Код семейства (шестнадцатеричный)

Семейство

Описание

06

iButton 1993

Идентификационный ключ

10

DS18S20

Высокоточный температурный датчик с разрешающей способностью 9 бит

28

DS18B20

Высокоточный температурный датчик с разрешающей способностью 12 бит

1C

DS28E04-100

ЭСППЗУ емкостью 4 Кбайт

В библиотеке OneWire имеется функция search, которую можно использовать для поиска всех ведомых устройств на шине. Следующий пример выводит адреса всех устройств на шине в монитор последовательного порта:

// sketch_08_01_OneWire_List

#include <OneWire.h>

OneWire bus(10);

void setup()

{

  Serial.begin(9600);

  byte address[8]; // 64 бита

  while (bus.search(address))

  {

    for(int i = 0; i < 7; i++)

    {

      Serial.print(address[i], HEX);

      Serial.print(" ");

    }

    // проверить контрольную сумму

    if (OneWire::crc8(address, 7) == address[7])

    {

      Serial.println(" CRC OK");

    }

    else

    {

      Serial.println(" CRC FAIL");

    }

  }

}

void loop()

{

}

На рис. 8.2 показан результат выполнения этого скетча при наличии двух температурных датчиков DS18B20, подключенных к Arduino. Обратите внимание на то, что оба устройства имеют один и тот же код семейства в первом байте, равный 28 (в шестнадцатеричном формате).

Программируем Arduino. Основы работы со скетчами - _59.jpg

28
{"b":"566417","o":1}