1-Wire – разработан фирмой Dallas Semiconductor (ныне MAXIM) в конце 90-х годов.
Фирменная документация здесь.
Этот интерфейс интересен тем, что для двустороннего обмена требуется всего одна линия! (отсюда и название 🙂
Правда, ещё требуется общий провод (земля), но это вроде как в расчёт не принимается 🙂
Причём, на эту одну линию можно повесить несколько устройств, а ассортимент таких устройств очень широк (от датчиков температуры до широко распространённых ключей-таблеток iButton).
Кроме того – протокол очень прост и легко реализуется на МК программно.
Ниже представлена блок-схема аппаратной реализации 1-Wire:
Вывод DQ устройства представляет собой вход КМОП-логического элемента, который может быть зашунтирован (замкнут на общий провод) полевым транзистором. Сопротивление канала этого транзистора в открытом состоянии — около 100 Ом. Когда транзистор заперт — имеется небольшой ток утечки (примерно 5 мкА) на общий провод.
Обратите внимание, что шина 1-Wire должна быть подтянута отдельным резистором к напряжению питания (может быть от 3V до 5V — нужно уточнять по характеристикам подключаемого устройства).
Сопротивление этого резистора 4.7k, однако, это значение подходит только для достаточно коротких линий.
Если шина используется для подключения устройств на большее расстояние, то сопротивление подтягивающего резистора необходимо уменьшить (сопротивление зависит от величины максимального втекающего тока линии DQ конкретного устройства 1-Wire).
Примечательный момент – некоторые устройства 1-Wire могут использовать т.н. «паразитное питание»/фантомное питание (Parasite power) – т.е. питание устройства осуществляется от линии данных
в полной мере относится к нашим ключам-таблеткам – батареек в них ведь нету 🙂
Электропитание осуществляется за счёт заряда встроенного конденсатора, который заряжается во время наличия высокого уровня напряжения на линии данных.
Опять же, следует учитывать, что связь с устройствами, использующими паразитное питание возможно только на коротких линиях. На длинных линиях возможны непонятные побочные эффекты.
Поэтому, если возможно – такого типа питания устройств следует избегать 🙂
Переходим к тому, как собственно происходит обмен информацией по 1-Wire.
Основные положения:
0. передача информации возможна только выдачей низкого уровня в линию, т.е. замыканием ее на общий провод. В высокий логический уровень линия вернется сама, из-за наличия подтягивающего резистора. (теперь становится понятно, что наличие внешнего подтягивающего резистора – обязательное условие работы 1-Wire)
1. обмен происходит по инициативе ведущего устройства (обычно — микроконтроллера)
2. обмен информацией начинается с подачи импульса сброса (RESET pulse) на линию
3. 1-wire устройства предусматривают «горячее» подключение (мы ведь втыкаем наши ключи-таблетки в в домофон, верно?)
4. при подключении, 1-wire устройство выдаёт в линию DQ импульс присутствия (PRESENCE pulse). Этот же импульс выдаётся при обнаружении сигнала RESET. (при втыкании ключа в домофон — ключ как-бы говорит ему – «вот он я!»)
5. обмен информации ведётся так называемыми тайм-слотами – один слот содержит один бит информации.
6. данные передаются побайтно – бит за битом, начиная с младшего байта. Достоверность данных (проверка отсутствия искажений) гарантируется путем подсчета циклической контрольной суммы (CRC).
алгоритм подсчета CRC должен быть одинаковым как для МК, так и для любого устройства 1-Wire. Он стандартизирован и описан в документации.
Как видно по диаграмме — МК формирует импульс RESET, переводя в низкий логический уровень шину 1-Wire и удерживая её не менее 480 микросекунд.
Затем МК “отпускает” шину и напряжение возвращается к высокому логическому уровню (время зависит от ёмкости линии и сопротивления подтягивающего резистора).
Протокол 1-Wire ограничивает это время диапазоном от 15 до 60 микросекунд, что и влияет на выбор подтягивающего резистора (на время возврата линии к высокому уровню большее влияние оказывает ёмкость лини, но, чаще всего, мы изменить её не можем).
Обнаружив импульс RESET, ведомое устройство формирует ответный импульс PRESENCE. Для этого устройство прижимает линию DQ к земле и удерживает от 60 до 240 микросекунд. Затем устройство так же “отпускает” шину.
После этого устройству еще дается время для завершения внутренних процедур инициализации, таким образом, МК должен приступить к любому обмену с устройством не ранее, чем через 480 микросекунд после завершения импульса RESET.
Т.о. процедура инициализации, с которой начинается обмен данными между устройствами, длится минимум 960 микросекунд.
Теперь рассмотрим процедуры обмена битами информации, которые осуществляются определенными тайм-слотами (определенная, жестко лимитированная по времени последовательность смены уровней сигнала в линии 1-Wire).
Различают 4 типа тайм-слотов:
1. передача «1» от МК,
2. передача «0» от МК,
3. прием «1» от устройства,
4. прием «0» от устройства.
Тайм-слот всегда начинает МК, прижимая шину к земле.
Длительность тайм-слота находится в пределах от 60 до 120 микросекунд.
Между тайм-слотами всегда должен быть интервал не менее 1 микросекунды (определяется параметрами ведомого устройства).
Тайм-слоты передачи отличаются от тайм-слотов приема поведением МК:
— при передаче МК только формирует сигналы,
— при приеме МК еще и опрашивает уровень сигнала в линии 1-Wire.
Тайм-слот передачи «0» заключается просто в прижимании шины 1-Wire к земле в течение всей длительности тайм-слота.
Передача «1» осуществляется путем «отпускания» шины 1-Wire со стороны МК не ранее чем через 1 микросекунду после начала тайм-слота, но не позже чем через 15 микросекунд.
Ведомое устройство опрашивает уровень в шине 1-Wire в течение временного интервала (показанного в виде серого прямоугольника), т.е. начиная с 15-й микросекунды от начала тайм-слота и заканчивая 60-й микросекундой от начала (для большинства устройств — около 30-й микросекунды от начала тайм-слота).
Заштрихованная область — это область «нарастания» уровня в шине 1-Wire, которая зависит от емкости линии и сопротивления подтягивающего резистора.
Тайм-слоты приема информации отличаются тем, что МК формирует только начало тайм-слота (так же, как при передаче «1»), а затем управление уровнем шины 1-Wire берет на себя устройство, а МК осуществляет ввод этого уровня так же в определенной зоне временных интервалов.
Зона эта, как видно из рисунка, довольно мала. Т.к. заштрихованная область — область неопределенности, поэтому для ввода, микроконтроллеру остается даже не промежуток, а скорее конкретный момент, когда он должен ввести уровень сигнала из линии. Этот момент времени — 14-я или 15-я микросекунда от начала тайм-слота.
Резюмируем:
— МК начинает тайм-слот, прижимая шину 1-Wire к логическому «0» в течение 1 микросекунды.
— Последующий уровень зависит от типа тайм слота: для приема и передачи «1» уровень должен стать высоким, а для передачи «0» — оставаться низким вплоть до конца тайм-слота, т.е. от 60 до 120 микросекунд.
— принимая данные, МК должен считать уровень в шины 1-Wire в промежутке от 13-й до 15-й микросекунде тайм-слота.
— МК должен обеспечить интервал между тайм-слотами не менее 1 микросекунды (лучше — больше, максимальное значение не ограничено).
Для достижения нужных временных интервалов нужно следовать простым правилам:
— все сигналы, которые должен формировать МК, следует формировать по принципу необходимого минимума длительности (т.е. немного больше, чем указанная минимальная длительность)
— от устройства следует ожидать сигналов по принципу наихудшего (т.е. ориентироваться на самые худшие варианты временных параметров сигнала).
Теперь настало время разобраться с протоколом обмена информации 🙂
Каждое устройство 1-Wire обладает уникальным идентификационным 64-битным номером, программируемым на этапе производства микросхемы (это относится не только к нашему ключу-таблетке, а ко всем устройствам 1-Wire).
Фирма-производитель гарантирует, что не найдется двух микросхем с одинаковым идентификационным номером (по крайней мере пока 🙂
Не трудно посчитать, что устройств одного типа может быть выпущено
281 474 976 710 655 (десятичное представление 0xFFFFFFFFFFFF – 48 бит — 6 байт идентификационного номера) – т.е. 281 биллион – довольно много – ага 🙂
Предположим, что на шине 1-Wire имеется более одного устройства.
В этом случае перед МК встают 2 проблемы: определение количества имеющихся устройств и выбор (адресация) одного конкретного из них для обмена данными.
Номера некоторых устройств наносятся прямо на корпус микросхем (например, для наших ключей-таблеток — iButton), а номера других можно определить при помощи специальных программ или устройств.
Итак, предположим, что мы знаем номера всех устройств 1-Wire на шине.
Алгоритм работы с ними следующий:
1. МК посылает, импульс RESET, и все имеющиеся устройства выдают PRESENCE.
2. МК посылает в шину команду, которую принимают все устройства. Определено несколько общих команд для всех типов 1-Wire-устройств, а так же есть команды, уникальные для отдельных типов устройств.
Общие команды:
Команда Значение байта Описание SEARCH ROM 0xF0 Поиск адресов - используется при универсальном алгоритме определения количества и адресов подключенных устройств READ ROM 0x33 Чтение адреса устройства - используется для определения адреса единственного устройства на шине MATCH ROM 0x55 Выбор адреса - используется для обращения к конкретному адресу устройства из многих подключенных SKIP ROM 0xCC Игнорировать адрес - используется для обращения к единственному устройству на шине, при этом адрес устройства игнорируется (можно обращаться к неизвестному устройству)
3. После того, как МК выдаст команду READ ROM, от устройства поступит 8 байт его собственного уникального адреса — МК должен их принять.
Любая процедура обмена данными с устройством должна быть завершена полностью либо прервана посылкой сигнала RESET.
4. Если отправлена команда MATCH ROM, то после нее МК должен передать 8 байт адреса конкретного устройства, с которым будет осуществляться последующий обмен данными.
5. Приняв эту команду, каждое устройство сравнивает передаваемый адрес со своим собственным. Все устройства, адрес которых не совпал, прекращают анализ и выдачу сигналов в линии 1-Wire, а опознавшее адрес устройство продолжает работу.
Теперь все данные, передаваемые МК будут попадать только к этому «адресованному» устройству.
Если устройство одно на шине — можно ускорить процесс взаимодействия с ним при помощи команды SKIP ROM. Поучив эту команду, устройство сразу считает адрес совпавшим, хотя никакого адреса за этой командой не следует.
Некоторые процедуры не требуют приема от устройства никаких данных, в этом случае команду SKIP ROM можно использовать для передачи какой-то информации сразу всем устройствам. Это можно использовать, например, для одновременного запуска цикла измерения температуры несколькими датчиками-термостатами типа DS18S20.
Прием и передача байтов, как уже отмечалось, всегда начинается с младшего бита. Порядок следования байтов при передаче и приеме адреса устройства так же ведется от младшего к старшему.
Порядок передачи другой информации зависит от конкретного устройства.
1-Wire и Arduino
Arduino/CraftDuino/Freeduino можно подружить с 1-Wire, используя библиотеку Jim Studt-а – OneWire.
скачать
— там же можно посмотреть на функции расчёта CRC.
Приложение
Алгоритм поиска устройств 1-Wire
К сожалению, я не смог найти в рунете материалов, которые бы описывали процесс – как собственно ведущее устройство сможет найти несколько устройств, подключённых к линии 1-Wire.
Однако, этот процесс подробно освещён в апноуте (Application Note):
AN187 — 1-Wire Search Algorithm
1. Итак, поиск начинается с импульса RESET от ведущего устройства и принятия PRESENCE от ведомых.
2. Затем, посылается 1 байт команды:
0xF0 – осуществляется поиск всех устройств на линии
или
0xEC – поиск среди устройств, находящихся в состоянии тревоги (alarm state).
3. Устройства отправляют первый бит своего уникального номера.
Если несколько устройств передают свой бит одновременно – результирующий бит на линии получится, как результат операции логического И (AND)
4. следующий бит, который отправляют устройства – это дополнение первого бита
(если первый бит был 1, то будет 0 и наоборот – если был 0 – теперь будет 1)
На основании этих двух битов – ведущее устройство может сделать вывод о первом бите устройств на линии:
5. Далее, МК отправляет бит назад. И теперь продолжат работу только те ведомые устройства у которых этот бит установлен. Если же устройство такого бита не имеет – оно должно перейти в режим ожидания до следующего сигнала RESET.
6. Данная «двубитная передача» повторяется для всех следующих 63 бит ROM.
7. Т.о. все устройства на линии, кроме одного перейдут в состояние ожидания, а код ROM этого единственного устройства будет известен 🙂
Cсылки
Интерфейс 1-Wire — данная замечательная статья использовалась при написании этой заметки
iButton
Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products
http://en.wikipedia.org/wiki/1-Wire
http://ru.wikipedia.org/wiki/Фантомное_питание
http://ru.wikipedia.org/wiki/Порядок_байтов
http://ru.wikipedia.org/wiki/CRC
библиотека Jim Studt-а – OneWire для Arduino
По теме
Интерфейс I2C
SPI
0 комментариев на «“1-Wire”»
Спасибо за статью!
хорошая доходчивая статья)респект
а каким образом программно реализовать чтение с нескольких датчиков температур и их идентификацию?
где поискать детальное описание 1-wire библиотеки?
Приветствую! Спасибо за статью. Вот я не очень понял такую вещь. А может ли Arduino выступать в качестве источника данных по 1-Wire? Как при этом определяется (задается) его уникальный номер? Как подключить его к другому ведущему устройству?
разумеется, может. пример —Arduino и 1-Wire — эмуляция ведомого устройства с помощью библиотеки OneWireSlave
номер, при этом, задаётся самостоятельно.
А в железе получалось эту библиотеку запустить?.. Вторые сутки бьюсь — не выходит. Явно что-то с таймингами в recv(), потому что кроме 0хFF в ответ ничего добиться от неё не удаётся. А детально поковыряться не выходит, осциллографа под рукой нет, к сожаланию.
Интересная статья, спасибо. Хотелось бы спросить, у меня есть некое устройство обладающее двумя GPIO где один работает на In, а другой на Out. Возможно ли с помощью протокола 1 Ware подключить к ним Arduino и управлять им? Если да, то как это осуществить?