Перейти к содержанию

Интерфейс 1-Wire

1-Wire — шина, в которой ведущему и ведомым хватает одной линии данных с подтягивающим резистором и общего провода, а ведомые могут питаться прямо от линии. Ниже — сброс и тайм-слоты по даташиту DS18B20 и AN126, поиск устройств по AN187, CRC, подключение DS18B20 и правила для длинных линий из AN148.

Обновлено Редакция GAW

1-Wire — последовательная шина, придуманная в Dallas Semiconductor (позже компания вошла в Maxim Integrated, а Maxim — в Analog Devices). Для обмена хватает одной сигнальной линии и общего провода. Ведущий, обычно микроконтроллер, начинает каждый бит, ведомые отвечают в отведённое им время, а адресом служит 64-битный номер, который производитель записывает в каждую микросхему. Многие ведомые не имеют вывода питания и берут энергию с той же линии. Так устроены термометры DS18B20, «таблетки» iButton, микросхемы серийного номера DS2401, память DS2431, двухканальные коммутаторы DS2413.

Все числа в статье — из документации производителя: даташита DS18B20 (ревизия 6, июль 2019 года), application notes Maxim 126 (программный ведущий), 187 (поиск устройств), 148 (длинные линии), 214 (ведущий на UART) и 27 (CRC), а также сборника Book of iButton Standards (AN937), где описаны общие для всех устройств временные параметры. Где расчёт или оценка наши, это сказано прямо.

Коротко

  • Линии: данные DQ и общий провод. Выходы всех устройств — с открытым стоком, линию подтягивает к питанию один резистор, в даташите DS18B20 — 4,7 кОм.
  • Обмен: каждую операцию начинает ведущий. Сброс — ноль не меньше 480 мкс, ответ ведомых — импульс присутствия 60–240 мкс. Бит занимает тайм-слот 60–120 мкс, данные идут младшим битом вперёд.
  • Скорость: до 16,3 кбит/с на стандартной скорости и до 142 кбит/с в режиме overdrive, который есть не у всех устройств.
  • Адрес: 64-битный ROM-код — 8 бит кода семейства (у DS18B20 — 28h), 48 бит серийного номера и 8 бит CRC с полиномом X⁸ + X⁵ + X⁴ + 1.
  • DS18B20: −55…+125 °C, погрешность ±0,5 °C в диапазоне −10…+85 °C, разрешение 9–12 бит, преобразование до 750 мс, питание 3,0–5,5 В от вывода VDD или паразитное от линии.
  • Длина: зависит от ведущего и кабеля. По AN148 ведущий с подтяжкой резистором держит сеть общей длиной около 200 м, ведущий с активной подтяжкой — до 500 м; звезду производитель не рекомендует.

Как устроена шина 1-Wire

Все устройства подключены к одной линии данных и к общему проводу. Каждое из них умеет только прижать линию к нулю или отпустить её: выход у всех — открытый сток. Единицу создаёт подтягивающий резистор, поэтому в покое на линии высокий уровень. Если линию одновременно тянут несколько устройств, побеждает ноль — это «монтажное И», как в I²C. На нём держатся общий импульс присутствия от нескольких устройств и поиск устройств на шине.

Шина 1-Wire: ведущий, три ведомых устройства и один подтягивающий резисторВсе устройства подключены к одной линии данных DQ и к общему проводу GND. Линию подтягивает к питанию единственный резистор 4,7 кОм, выходы ведущего и ведомых — с открытым стоком, поэтому в покое на линии высокий уровень. Каждое ведомое устройство отличается уникальным 64-битным кодом: два термодатчика DS18B20 с кодом семейства 28h и электронный серийный номер DS2401 с кодом семейства 01h.DQVDD, 3,0–5,5 ВRpu4,7 кОмВедущийМКодин выводDS18B20семейство 28hDS18B20семейство 28hDS2401семейство 01hGNDвыходы всех устройств — открытый сток, в покое линия в единицеобщий провод обязателен
Шина 1-Wire: одна линия DQ, общий провод и один подтягивающий резистор на всю линию. Ведомые различаются 64-битными кодами, тип устройства задаёт код семейства

Тактовой линии нет. Каждый бит начинается спадом, который делает ведущий, а ведомое отсчитывает время от этого спада своим внутренним таймером: по нему оно решает, когда читать линию в слоте записи и сколько держать ноль в слоте чтения. Так механизм описан, например, в даташите DS2401. Поэтому надёжность 1-Wire упирается во время: ведущий должен выдерживать длительности, а линия — успевать подняться к тому моменту, когда её читают.

Отдельная линия питания ведомому не нужна. Пока линия в единице, оно заряжает внутренний конденсатор, а пока в нуле — живёт за его счёт. Это паразитное питание. Тем, кому нужно больше энергии, — DS18B20 во время измерения, EEPROM во время записи — её дают через сильную подтяжку, о ней ниже.

Ещё три свойства шины, важные на практике:

  • Пауза между битами может быть любой. Пока линия в единице, ведомые ждут следующий слот сколько угодно: максимального времени восстановления нет. Поэтому прерывания можно разрешать между слотами.
  • Долгий ноль — это сброс. Если линия в нуле дольше 480 мкс, все устройства сбрасываются (даташит DS18B20). При обрыве контакта ведомые тоже уходят в сброс, а когда напряжение возвращается, сообщают о себе импульсом присутствия (AN1796).
  • Младший бит первым. Команды, данные и ROM-код передаются младшим битом вперёд.

Уникальный 64-битный ROM-код

В каждое ведомое при производстве записан 64-битный код. Младший байт — код семейства, он говорит о типе микросхемы: 28h — DS18B20, 01h — DS2401 и DS1990A, 2Dh — DS2431, 3Ah — DS2413. Следующие 48 бит — серийный номер, старший байт — CRC первых 56 бит. По Book of iButton Standards тип устройства задают младшие семь бит кода семейства, а старший бит помечает заказные версии, так что стандартных семейств может быть 128. 48 бит серийного номера — это 2,8·10¹⁴ номеров в каждом семействе.

Структура 64-битного ROM-кода устройства 1-WireСтарший байт ROM-кода — контрольная сумма CRC, следующие 48 бит — серийный номер, младший байт — код семейства. По линии код передаётся начиная с младшего бита кода семейства. Пример из application note 27: байты в порядке передачи 02, 1C, B8, 01, 00, 00, 00, A2 — код семейства 02h, серийный номер 00000001B81Ch и CRC A2h.Как в даташите: старший бит слеваCRC8 битсерийный номер48 битсемейство8 бит6356 | 558 | 70по линии: сначала бит 0 кода семейства, последним — бит 63 CRCПример AN27 — байты в порядке приёма:02байт 01Cбайт 1B8байт 201байт 300байт 400байт 500байт 6A2байт 7семействоCRCсерийный номер 00000001B81Ch, младший байт первым
ROM-код: код семейства, серийный номер и CRC. Внизу — пример из AN27 в том порядке, в каком байты приходят по линии

Код передаётся начиная с младшего бита кода семейства, поэтому программы и библиотеки обычно печатают его побайтно в порядке приёма: первым идёт код семейства, последним — CRC. Так, ROM-код DS18B20 в выводе библиотеки OneWire всегда начинается с 28. Даташиты рисуют тот же код наоборот, старшим байтом слева. Сравнивая коды из разных программ, сначала выясните, в каком порядке они записаны.

Последовательность обмена

Обращение к ведомому всегда состоит из трёх шагов (даташит DS18B20, раздел 1-Wire Bus System):

  1. Инициализация: ведущий посылает импульс сброса, ведомые отвечают импульсом присутствия.
  2. ROM-команда: выбор устройства по коду, обращение ко всем или поиск. За командой следуют её данные, например 64 бита кода.
  3. Функциональная команда конкретного устройства — у DS18B20 это запуск измерения, чтение или запись блокнота — и обмен данными.

Если шаг пропущен или нарушен порядок, устройство не ответит. Исключение — команды поиска Search ROM и Alarm Search: после них ведущий снова начинает со сброса.

Временные слоты 1-Wire

Весь обмен складывается из четырёх операций: сброс, запись 1, запись 0 и чтение бита. Все их, кроме импульса присутствия, начинает ведущий. Ниже — длительности по даташиту DS18B20 и Book of iButton Standards и рекомендованные значения из AN126.

Сброс и импульс присутствия

Временная диаграмма сброса 1-Wire и импульса присутствияВедущий прижимает линию к нулю не меньше чем на 480 мкс — это импульс сброса. Затем он отпускает линию, резистор поднимает её до напряжения питания, и ведущий не меньше 480 мкс слушает линию. Ведомое устройство, заметив фронт, ждёт 15–60 мкс и прижимает линию к нулю на 60–240 мкс — это импульс присутствия. Ведущий проверяет уровень через 70 мкс после того, как отпустил линию: ноль означает, что на шине есть хотя бы одно устройство. Масштаб по времени условный.VPU0импульс сбросаприсутствиеведущий держит 0 не меньше 480 мксведущий слушает линию не меньше 480 мкс15–60 мкс60–240 мксведущий читает линию через 70 мкс после отпусканиятянет ведущийтянет ведомыйподнимает резистор
Инициализация: импульс сброса от ведущего и импульс присутствия от ведомого. Масштаб по времени условный

Ведущий прижимает линию к нулю не меньше чем на 480 мкс (tRSTL), потом отпускает её и не меньше 480 мкс (tRSTH) слушает. Ведомое, увидев фронт, выжидает 15–60 мкс (tPDHIGH) и отвечает импульсом присутствия — нулём длительностью 60–240 мкс (tPDLOW). Если на шине несколько устройств, их импульсы накладываются и выглядят как один.

AN126 рекомендует проверять линию через 70 мкс после того, как ведущий её отпустил. Число не случайное: самое медленное ведомое начинает импульс присутствия не позже чем через 60 мкс, а самое быстрое держит ноль как минимум до 15 + 60 = 75 мкс. Момент 70 мкс попадает в окно 60–75 мкс, где ноль от любого исправного устройства гарантирован.

Слишком длинный сброс тоже вреден. Book of iButton Standards советует укладывать импульс сброса вместе с фронтом в 960 мкс, чтобы не заглушить сигналы прерывания, которые подают некоторые устройства. А DS18B20 с паразитным питанием, по даташиту, при импульсе сброса длиннее 960 мкс может перезапуститься по питанию: всё это время он живёт только за счёт внутреннего конденсатора.

Запись нуля и единицы

Каждый бит передаётся в тайм-слоте длительностью 60–120 мкс (tSLOT), а между слотами линия должна побыть в единице хотя бы 1 мкс (tREC). Чтобы записать 1, ведущий опускает линию и отпускает её не позже чем через 15 мкс: tLOW1 — от 1 до 15 мкс. Чтобы записать 0, он держит ноль весь слот, 60–120 мкс (tLOW0). Ведомое читает линию в окне от 15 до 60 мкс после спада, у DS18B20 типично через 30 мкс. Отсюда смысл границ: при записи 1 линия должна подняться раньше, чем откроется окно, а при записи 0 — оставаться в нуле, пока оно не закроется.

Тайм-слоты 1-Wire: запись 0 и 1, чтение 0 и 1Каждый бит передаётся в тайм-слоте длительностью 60–120 мкс, и каждый слот начинает ведущий, прижимая линию к нулю. Запись 1: ведущий отпускает линию через 1–15 мкс. Запись 0: ведущий держит ноль 60–120 мкс. Ведомое устройство читает линию в окне от 15 до 60 мкс после спада. Чтение: ведущий прижимает линию хотя бы на 1 мкс и отпускает её; ведомое, передавая ноль, продолжает держать линию, передавая единицу — не трогает её. Данные действительны 15 мкс от спада, поэтому ведущий должен прочитать линию не позже чем через 15 мкс. Масштаб: 4 пикселя на микросекунду.Запись 1ведомый читает линию1–15 мкс01530456070 мксЧтение: ведомый передаёт 1ведущий читает не позже 15 мксведомый не тянет — прочитана 101530456070 мксЗапись 0ведомый читает линию60–120 мкс01530456070 мксЧтение: ведомый передаёт 0ведущий читает не позже 15 мксведомый держит 0 до 15–60 мкс01530456070 мкстянет ведущийтянет ведомыйподнимает резисторокно выборки ведомого
Четыре тайм-слота в масштабе. Длительности нарисованы по рекомендациям AN126: ноль 6 мкс в начале записи 1 и чтения, 60 мкс при записи 0, чтение через 15 мкс от спада

Чтение бита: когда опрашивать линию

Ведомое передаёт данные, только когда ведущий даёт ему слот чтения. Слот начинается так же, как запись 1: ведущий опускает линию хотя бы на 1 мкс и отпускает. Если ведомому нужно передать 1, оно ничего не делает, и линия поднимается. Чтобы передать 0, оно подхватывает линию и держит её в нуле. Данные действительны 15 мкс от спада (tRDV), поэтому ведущий должен прочитать линию не позже чем через 15 мкс от начала слота. Отпускает линию ведомое через 15–60 мкс: по Book of iButton Standards после tRDV проходит ещё от 0 до 45 мкс (tRELEASE).

Эти 15 мкс делятся на три части: ведущий держит ноль (TINIT), линия поднимается через резистор (TRC), ведущий читает уровень (TSAMPLE). Даташит DS18B20 советует делать первые две как можно короче, а читать ближе к концу 15 мкс: тогда при передаче единицы у линии больше всего времени, чтобы подняться.

Самая частая ошибка программного ведущего, по AN148, — читать линию слишком поздно. Код, который читает через 30 мкс, может пройти лабораторные испытания: многие ведомые держат ноль заметно дольше 15 мкс. Но разброс времени у ведомых большой и меняется с температурой, напряжением и от партии к партии. Пример из AN148: если ноль у ведомых закончится через 29 мкс вместо 32, такой ведущий начнёт ошибаться. Граница 15 мкс — требование, а не рекомендация.

Рекомендуемые задержки из AN126

AN126 описывает операции через десять задержек и даёт значения, которые, по словам Maxim, обеспечивают самый надёжный обмен со всеми устройствами при разных состояниях линии:

ЗадержкаГде используетсяСтандартная скорость, мксOverdrive, мкс
Aноль в начале записи 1 и чтения61,0
Bзапись 1: остаток слота и восстановление647,5
Cзапись 0: длительность нуля607,5
Dзапись 0: восстановление102,5
Eчтение: от отпускания линии до чтения91,0
Fчтение: остаток слота и восстановление557
Gпауза перед сбросом02,5
Hимпульс сброса48070
Iот отпускания линии до проверки присутствия708,5
Jостаток последовательности сброса41040

Отсюда длительности операций на стандартной скорости: запись 1 — A + B = 70 мкс, запись 0 — C + D = 70 мкс, чтение — A + E + F = 70 мкс, сброс — G + H + I + J = 960 мкс. Бит каждые 70 мкс — это около 14,3 кбит/с. AN126 ставит два условия: задержку в 1 мкс (0,25 мкс для overdrive) нужно формировать точно и повторяемо, а операцию нельзя прерывать, пока она формируется. В примере кода той же AN126 для overdrive стоят A = 1,5 мкс и E = 0,75 мкс, не как в таблице, — на этой скорости сверяйтесь ещё и с даташитом устройства.

Стандартная скорость и overdrive

Overdrive ускоряет все временные параметры, включая сброс и присутствие, примерно на порядок. Значения ниже — для классических устройств 1-Wire, по сравнительной таблице в даташите DS2431 и по Book of iButton Standards:

ПараметрСтандартная скоростьOverdrive
Тайм-слот вместе с восстановлением, не меньше61 мкс7 мкс
Импульс сброса tRSTLот 480 мкс48–80 мкс
Ожидание перед присутствием tPDH15–60 мкс2–6 мкс
Импульс присутствия tPDL60–240 мкс8–24 мкс
Ноль при записи 0 tW0L60–120 мкс6–16 мкс
Ноль при записи 1 и в начале чтения1–15 мкс1–2 мкс
Данные действительны после спада tRDV15 мкс2 мкс
Наибольшая скорость обмена16,3 кбит/с142 кбит/с

На стандартной скорости работают все устройства 1-Wire. В overdrive переходят только те, что его поддерживают: команда Overdrive Skip ROM (3Ch) переводит все такие устройства, Overdrive Match ROM (69h) — одно выбранное. Обратно их возвращает обычный сброс длительностью не меньше 480 мкс. У новых микросхем скорость чуть ниже: у DS2431 — 15,4 и 125 кбит/с, у DS2413 — 14,9 и 100 кбит/с; производитель объясняет это увеличенным временем восстановления у входа с улучшенной помехоустойчивостью. DS18B20 режима overdrive не имеет, а AN148 предупреждает, что overdrive рассчитан только на очень короткие соединения и для сетей с кабелем не годится.

ROM-команды 1-Wire

После импульса присутствия ведущий посылает ROM-команду — один байт, который определяет, с каким устройством он будет говорить. Команды общие для всех устройств 1-Wire, но не каждое поддерживает все: у DS18B20 их пять, у DS2401 и DS1990A — только чтение кода и поиск.

КомандаКодЧто делаетКогда применять
Read ROM33hведомое выдаёт свой 64-битный кодтолько когда на шине одно устройство; DS2401 и DS1990A понимают ещё и 0Fh
Match ROM55hза командой ведущий передаёт 64 бита кода, дальше отвечает только совпавшее устройствообращение к конкретному устройству на общей шине
Skip ROMCChобращение ко всем без адресакоманда всем сразу, например запуск измерения во всех DS18B20, или шина с одним устройством
Search ROMF0hпоиск кодов всех устройствпри запуске системы и для проверки состава шины
Alarm SearchEChтот же поиск, но отвечают только устройства с флагом тревогиу DS18B20 — температура вне порогов TH и TL
Overdrive Skip ROM3ChSkip ROM с переводом всех поддерживающих устройств в overdriveDS2431, DS2413 и другие с overdrive; у DS18B20 нет
Overdrive Match ROM69hMatch ROM на скорости overdrive, выбранное устройство переходит в overdriveто же
ResumeA5hповторное обращение к последнему выбранному устройству без передачи кодаDS2431, DS2413 и другие новые устройства

Пояснения:

  • Read ROM на шине с несколькими устройствами даёт столкновение: отвечают все сразу, линия складывает коды по «монтажному И», и результат не проходит проверку CRC. Book of iButton Standards советует читать код поиском даже при одном устройстве: такой код работает и на общей шине.
  • Skip ROM удобен для общих команд: Skip ROM и Convert T запускают измерение во всех DS18B20 одновременно. Читать данные после Skip ROM можно, только если устройство на шине одно, иначе ответы столкнутся.
  • Resume экономит 64 бита адреса при повторных обращениях к одному устройству. Бит RC, на который она смотрит, устанавливают Match ROM, Search ROM и Overdrive Match ROM, а обращение к другому устройству его сбрасывает, поэтому ответить двоим не получится.

Поиск устройств на шине: алгоритм Search ROM

Поиск по команде F0h — это обход двоичного дерева, в листьях которого лежат коды устройств (AN187). Все участвующие ведомые выдают на линию первый, младший бит своего кода, затем этот же бит в инверсии. Ведущий читает оба значения, и каждое из них — «монтажное И» ответов всех устройств:

БитИнверсияЧто это значит
01у всех оставшихся устройств в этом разряде 0
10у всех оставшихся устройств 1
00есть и 0, и 1 — развилка
11никто не отвечает: устройств нет или одно из них отключили во время поиска

Затем ведущий записывает выбранное значение бита. Устройства, у которых в этом разряде другое значение, выбывают и ждут следующего сброса. Так повторяется 64 раза — по три слота на разряд, — и в конце ведущий знает код одного устройства. Чтобы найти остальные, поиск повторяют, на развилках выбирая другие ветви. Правило из AN187 для развилки:

  • разряд раньше последней развилки прошлого прохода — тот же бит, что в прошлый раз;
  • разряд совпадает с последней развилкой — 1;
  • разряд дальше — 0, и номер этого разряда запоминается.

Последняя развилка, где выбран 0, становится точкой ветвления для следующего прохода. Если таких развилок не было, найдено последнее устройство. Проходов столько, сколько устройств на шине.

Разберём на учебном примере: три устройства с 4-битными кодами D1 = 0101, D2 = 0110 и D3 = 1001 (биты в порядке передачи). Реальный код длиннее, но работает всё так же.

ПроходБит 1Бит 2Бит 3Бит 4НайденоСледующая развилка
10/0: развилка, новая — 0; D3 выбывает1/0: у всех 10/0: развилка, новая — 0; D2 выбывает1/0D1 = 0101бит 3
20/0: раньше бита 3 — как в прошлый раз, 01/00/0: последняя развилка — 1; D1 выбывает0/1D2 = 0110бит 1
30/0: последняя развилка — 1; D1 и D2 выбывают0/10/11/0D3 = 1001нет, поиск закончен
Поиск ROM-кодов как обход двоичного дереваУчебный пример с тремя устройствами и 4-битными кодами: D1 = 0101, D2 = 0110, D3 = 1001, биты в порядке передачи. Развилки, где у оставшихся устройств встречаются и 0, и 1, — на бите 1 и на бите 3. Первый проход на каждой новой развилке выбирает 0 и находит D1. Второй проход повторяет путь до последней развилки первого прохода, на бите 3 выбирает 1 и находит D2. Третий проход на бите 1 выбирает 1 и находит D3; новых развилок нет, поиск закончен.бит 1бит 2бит 3бит 40110010101после F0h: развилка на бите 1проходы 1 и 2 выбирают 0, проход 3 — 1развилка на бите 3проход 1 — 0, проход 2 — 1D1 = 0101проход 1D2 = 0110проход 2D3 = 1001проход 3
Тот же поиск как обход дерева: развилки на бите 1 и на бите 3, по одному устройству за проход

У реальных датчиков одного типа первые 8 бит совпадают — это код семейства, — поэтому развилки начинаются в серийном номере. Один проход занимает сброс и 8 + 64 × 3 = 200 слотов, то есть около 15 мс при задержках AN126, так что десять датчиков находятся примерно за 0,15 с. Реализация на C по AN187, с функциями нижнего уровня из раздела про AVR ниже:

static uint8_t rom[8];              /* last found ROM code, rom[0] = family code */
static uint8_t last_discrepancy;    /* bit 1..64 where 0 was taken last time, 0 = none */
static uint8_t last_device;

/* Finds the next device. Returns 1 and fills rom[]; 0 = no more devices or an error. */
uint8_t ow_search_next(void)
{
    uint8_t last_zero = 0;

    if (last_device || !ow_reset()) {
        last_discrepancy = 0;
        last_device = 0;
        return 0;
    }
    ow_write_byte(0xF0);                            /* Search ROM */
    for (uint8_t n = 1; n <= 64; n++) {             /* bit 1 = LSB of rom[0] */
        uint8_t *byte = &rom[(n - 1) / 8];
        uint8_t mask = (uint8_t)(1 << ((n - 1) % 8));
        uint8_t bit = ow_read_bit();
        uint8_t cmp = ow_read_bit();                /* complement of the same bit */
        uint8_t dir;

        if (bit && cmp) {                           /* nobody answered */
            last_discrepancy = 0;
            return 0;
        }
        if (bit != cmp) {
            dir = bit;                              /* all remaining devices agree */
        } else {                                    /* fork: both 0 and 1 present */
            if (n < last_discrepancy)
                dir = (*byte & mask) != 0;          /* same branch as last time */
            else
                dir = (n == last_discrepancy);      /* 1 at the last fork, 0 at a new one */
            if (!dir)
                last_zero = n;
        }
        if (dir) *byte |= mask; else *byte &= (uint8_t)~mask;
        ow_write_bit(dir);                          /* devices with the other bit drop out */
    }
    if (ow_crc8(rom, 8) != 0) {                     /* CRC over all 8 bytes must give 0 */
        last_discrepancy = 0;                       /* damaged code: start over next time */
        return 0;
    }
    last_discrepancy = last_zero;
    if (last_discrepancy == 0)
        last_device = 1;
    return 1;
}

uint8_t ow_search_first(void)
{
    last_discrepancy = 0;
    last_device = 0;
    return ow_search_next();
}

Логику этого кода мы проверили моделью шины с «монтажным И»: на 200 случайных наборах до 12 устройств он находит все коды, а на примере из таблицы делает те же три прохода.

AN187 описывает ещё три варианта на тех же переменных. Проверка конкретного устройства: записать его код в rom, поставить последнюю развилку 64 и выполнить поиск — устройство на месте, если код не изменился. Поиск семейства: записать код семейства в первый байт, остальные обнулить и поставить последнюю развилку 64 — первым найдётся устройство этого семейства, если оно есть. Пропуск семейства: продолжить поиск с последней развилки внутри первых 8 бит, чтобы не перебирать остальных устройств того же типа.

Аппаратные ведущие берут часть работы на себя. У DS2482 есть команда 1-Wire Triplet (78h): два слота чтения и слот записи по одной команде, на устройство их нужно 64. DS2480B ускоряет поиск сам, а DS2490 по AN187 выполняет его целиком.

Поиск — самая требовательная операция на шине: только в нём, не считая импульса присутствия, линию одновременно тянут все устройства. Поэтому проблемы сети по AN148 проявляются прежде всего так: устройства то находятся, то пропадают из результатов поиска.

Термодатчик DS18B20

DS18B20 — цифровой термометр с интерфейсом 1-Wire. Он выпускается в корпусе TO-92 с тремя выводами (DS18B20), в SO-8 (DS18B20Z) и µSOP-8 (DS18B20U). В корпусе TO-92 вывод 1 — GND, 2 — DQ, 3 — VDD.

Характеристики DS18B20

ПараметрЗначение
Диапазон измерения−55…+125 °C
Погрешность±0,5 °C при −10…+85 °C, ±1 °C при −30…+100 °C, ±2 °C при −55…+125 °C
Разрешение9, 10, 11 или 12 бит — шаг 0,5, 0,25, 0,125 или 0,0625 °C; заводская настройка — 12 бит
Время преобразования, не больше93,75 мс при 9 битах, 750 мс при 12 битах
Питание3,0–5,5 В на выводе VDD или паразитное от линии при подтяжке 3,0–5,5 В
Потреблениев покое 750 нА типично, до 1000 нА при температуре до +70 °C; при измерении и записи EEPROM — 1 мА типично, до 1,5 мА
Пороги входа DQноль — не выше 0,8 В; единица — не ниже 2,2 В при внешнем питании и 3,0 В при паразитном
Выход DQоткрытый сток, не меньше 4 мА при 0,4 В
Ёмкость вывода DQдо 25 пФ
EEPROM для TH, TL и конфигурации50 тыс. циклов записи, хранение 10 лет (при −55…+55 °C), запись до 10 мс
Код семейства28h

Функциональные команды

КомандаКодЧто делаетЧто после команды
Convert T44hзапускает измерение температурыпри внешнем питании слоты чтения дают 0, пока идёт измерение, и 1, когда оно закончено; при паразитном — сильная подтяжка не позже чем через 10 мкс и на всё время измерения
Read ScratchpadBEhчитает блокнот начиная с байта 0до 9 байт; чтение можно прервать сбросом
Write Scratchpad4Ehпишет TH, TL и конфигурацию в байты 2–4 блокнотаведущий передаёт три байта младшим битом вперёд, все три — до сброса
Copy Scratchpad48hкопирует TH, TL и конфигурацию в EEPROMпри паразитном питании — сильная подтяжка не позже чем через 10 мкс и не меньше 10 мс
Recall E²B8hзагружает TH, TL и конфигурацию из EEPROM в блокнотслоты чтения: 0 — идёт загрузка, 1 — готово; при включении питания это делается само
Read Power SupplyB4hпоказывает, есть ли на шине датчики с паразитным питаниемв слоте чтения такие датчики тянут линию к нулю, датчики с внешним питанием оставляют единицу

Блокнот и регистр конфигурации

Блокнот (scratchpad) — 9 байт оперативной памяти, через которые идёт весь обмен:

БайтСодержимоеПосле включения
0температура, младший байт50h
1температура, старший байт05h, вместе с байтом 0 — 0550h, то есть +85 °C
2порог TH или пользовательский байт 1из EEPROM
3порог TL или пользовательский байт 2из EEPROM
4регистр конфигурациииз EEPROM
5резервFFh
6резерв—
7резерв10h
8CRC байтов 0–7—

Байты 2–4 хранятся в EEPROM и при включении сами загружаются в блокнот. Если тревога не нужна, TH и TL можно использовать как два байта своей памяти, например для номера датчика. EEPROM выдерживает 50 тыс. циклов записи, поэтому копировать блокнот при каждом включении не стоит: записывайте, только если значение действительно изменилось.

В регистре конфигурации два значащих бита, R1 и R0, остальные зарезервированы: бит 7 всегда 0, биты 4–0 — единицы.

R1 R0РазрешениеШагВремя преобразования, не большеБайт конфигурации
009 бит0,5 °C93,75 мс1Fh
0110 бит0,25 °C187,5 мс3Fh
1011 бит0,125 °C375 мс5Fh
1112 бит0,0625 °C750 мс7Fh

Каждый бит разрешения удваивает время измерения. Если важнее частота опроса, чем сотые доли градуса, 10 или 11 бит дают выигрыш в 4 или 2 раза.

Формат температуры: дополнительный код и шаг 0,0625 °C

Температура хранится в байтах 0 и 1 как 16-битное число в дополнительном коде, расширенное знаком: старшие пять бит повторяют знак. Младшие четыре бита — дробная часть, поэтому при 12 битах единица младшего разряда равна 1/16 = 0,0625 °C. Чтобы получить градусы, нужно сложить байты в знаковое 16-битное число и умножить на 0,0625. Примеры из таблицы 1 даташита:

ТемператураКодРасчёт
+125 °C07D0h2000 × 0,0625 = 125
+85 °C0550h1360 × 0,0625 = 85, значение после включения
+25,0625 °C0191h401 × 0,0625 = 25,0625
−10,125 °CFF5EhFF5Eh − 10000h = −162; −162 × 0,0625 = −10,125
−25,0625 °CFE6Fh−401 × 0,0625 = −25,0625
−55 °CFC90h−880 × 0,0625 = −55

Отрицательное значение удобно проверять так: 10000h − FF5Eh = A2h = 162, значит FF5Eh — это −162. На C всё сводится к одному приведению типа, и знак получается сам:

int16_t raw = (int16_t)((uint16_t)sp[1] << 8 | sp[0]);   /* sp[] = scratchpad bytes */
float celsius = raw / 16.0f;                              /* 0x0191 -> 25.0625, 0xFF5E -> -10.125 */

При разрешении ниже 12 бит младшие биты не определены: при 11 битах — бит 0, при 10 — биты 1 и 0, при 9 — биты 2–0. Их нужно обнулять до пересчёта, иначе в результате появится мусор в последних знаках. При 9 битах это raw & ~7: если в неопределённых битах окажутся единицы, как в коде FE6Fh, маска даст FE68h, то есть −25,5 °C — значение с шагом 0,5 °C.

Почему DS18B20 показывает 85 °C

85 °C — значение регистра температуры после включения питания (код 0550h). Если программа его читает, датчик ещё не закончил ни одного преобразования после включения или после перезапуска. Причин три:

  • Измерение не запускали. Команду 44h не отправили или отправили не тому устройству.
  • Прочитали слишком рано. При 12 битах преобразование длится до 750 мс. Пока оно идёт, в блокноте остаётся прошлое значение, а у только что включённого датчика прошлого значения нет.
  • Датчику не хватило питания. При паразитном питании без сильной подтяжки резистор не может дать ток до 1,5 мА, который нужен во время измерения, датчик может перезапуститься и снова покажет 85 °C.

Настоящие 85 °C датчик тоже может измерить, поэтому само значение ещё не ошибка. Признак ошибки — 85 °C сразу после включения или при заведомо другой температуре.

Точность ±0,5 °C: где она действует

±0,5 °C гарантированы только в диапазоне −10…+85 °C. В диапазоне −30…+100 °C погрешность — до ±1 °C, во всём диапазоне −55…+125 °C — до ±2 °C. Это пределы 3σ, то есть так ведут себя практически все экземпляры. После 1000 часов работы при +125 °C показания могут сместиться ещё на ±0,2 °C. Разрешение 0,0625 °C — не точность: оно показывает, насколько мелко датчик различает изменения, а абсолютная ошибка остаётся в пределах ±0,5 °C.

После каждого измерения DS18B20 сравнивает температуру с порогами TH и TL — однобайтовыми числами в дополнительном коде. В сравнении участвуют биты 11–4 регистра температуры, то есть целые градусы. Если температура не выше TL или не ниже TH, датчик ставит флаг тревоги; следующее измерение пересчитывает флаг. Команда Alarm Search (ECh) работает как поиск, но отвечают только датчики с флагом, и ведущий за несколько проходов узнаёт, где температура вышла за пределы, не читая все датчики подряд.

Как выглядит обмен с датчиками

Один датчик с внешним питанием, адрес не нужен:

  1. Сброс, присутствие, Skip ROM (CCh), Convert T (44h).
  2. Слоты чтения, пока датчик не ответит 1, — не дольше 750 мс при 12 битах.
  3. Сброс, присутствие, Skip ROM (CCh), Read Scratchpad (BEh), девять байт, проверка CRC.

Несколько датчиков, по примеру 1 из даташита:

  1. Один раз при запуске — поиск, коды датчиков сохраняются.
  2. Сброс, Skip ROM (CCh), Convert T (44h) — измеряют все сразу. При паразитном питании сразу после команды включается сильная подтяжка на время tCONV.
  3. Для каждого датчика: сброс, Match ROM (55h) и его 64-битный код, Read Scratchpad (BEh), девять байт и проверка CRC.

При задержках AN126 сброс занимает 960 мкс, а каждый бит — 70 мкс. Чтение одного датчика по адресу — это 8 + 64 + 8 + 72 = 152 слота плюс сброс, около 11,6 мс. Измерение при 12 битах длится до 750 мс, поэтому цикл опроса десяти датчиков с общим запуском измерения укладывается примерно в 0,87 с, а с поочерёдным запуском занял бы больше 7,5 с.

Подключение DS18B20

Внешнее питание: три провода и резистор 4,7 кОм

Самая надёжная схема — с внешним питанием: на каждый датчик идут три провода, VDD, DQ и GND, а линию DQ подтягивает к питанию один резистор 4,7 кОм у микроконтроллера. Так подключение нарисовано в даташите. Датчик при этом может отвечать о конце преобразования, а линия свободна для обмена с другими устройствами, пока он измеряет.

Подключение нескольких DS18B20 с внешним питаниемТри датчика DS18B20 подключены параллельно к трём проводам: питанию +5 В, линии данных DQ и общему проводу. Линия DQ подтянута к +5 В одним резистором 4,7 кОм у микроконтроллера. Выводы корпуса TO-92: 1 — GND, 2 — DQ, 3 — VDD.+5 ВVDDRpu4,7 кОмDQМКпитание 5 ВGPIODS18B202 DQ3 VDD1 GNDDS18B202 DQ3 VDD1 GNDDS18B202 DQ3 VDD1 GNDGNDодна подтяжка Rpu на всю линию — у ведущего
Три DS18B20 с внешним питанием: три общих провода и одна подтяжка 4,7 кОм у ведущего. Номера выводов — для корпуса TO-92

Вывод VDD нельзя оставлять неподключённым: при паразитном питании его соединяют с GND, при внешнем — с питанием. В тексте даташита для подтяжки назван резистор «около 5 кОм», а на всех схемах стоит 4,7 кОм — ближайший к 5 кОм номинал ряда E12.

Расчёт подтяжки: ток и время нарастания

У резистора подтяжки две границы. Нижнюю задаёт ток: когда ведомое тянет линию к нулю, через него течёт ток резистора, а DS18B20 гарантирует ноль не выше 0,4 В только при токе до 4 мА:

Rmin=VPU−VOLIOL=5 В−0,4 В4 мА=1,15 кОмR_\text{min} = \frac{V_\text{PU} - V_\text{OL}}{I_\text{OL}} = \frac{5\ \text{В} - 0{,}4\ \text{В}}{4\ \text{мА}} = 1{,}15\ \text{кОм}

При 3,3 В та же граница — 725 Ом. Резистор 4,7 кОм при 5 В даёт ток около 0,98 мА — с четырёхкратным запасом.

Верхнюю границу задаёт время нарастания. После того как ведущий отпустил линию, её ёмкость C заряжается через резистор R, и до порога VIH напряжение доходит за время

t=−RC⋅ln⁡(1−VIHVPU)t = -RC \cdot \ln\left(1 - \frac{V_\text{IH}}{V_\text{PU}}\right)

При 5 В до порога 2,2 В (внешнее питание) это 0,58RC, до 3,0 В (паразитное) — 0,92RC. В слоте записи 1 по AN126 ведущий держит ноль 6 мкс, а DS18B20 может прочитать линию уже через 15 мкс от спада, так что на подъём остаётся 9 мкс. Отсюда постоянная времени RC должна быть не больше 15,5 мкс при внешнем питании и 9,8 мкс при паразитном. С резистором 4,7 кОм это 3,3 и 2,1 нФ ёмкости линии вместе с датчиками.

Сколько это в метрах? AN148 оценивает кабель категории 5e примерно в 52 пФ на метр, так что 2,1–3,3 нФ — это порядка 40–60 м витой пары при 5 В. При 3,3 В те же расчёты дают около 1,7 нФ (около 34 м) при внешнем питании и всего 0,8 нФ (около 15 м) при паразитном. Это наша оценка по простой RC-модели: она не учитывает отражения в кабеле и разброс порогов у ведущего, но порядок верный. Для сравнения, AN148 называет 200 м для ведущего с подтяжкой 1 кОм: у такой цепи на 200 м кабеля постоянная времени 1 кОм × 200 м × 52 пФ/м = 10,4 мкс, тот же порядок. Посчитать RC для своей линии поможет калькулятор RC-цепи.

Отсюда практические выводы:

  • 4,7 кОм — хороший номинал для платы и проводов в несколько метров или десятков метров.
  • 10 кОм вдвое уменьшает допустимую ёмкость: на длинном проводе единица будет читаться как ноль, и это проявится ошибками CRC.
  • Уменьшать резистор ниже 1,5–2 кОм при 5 В стоит только вместе с проверкой нуля на линии осциллографом: ток растёт, и уровень нуля поднимается.

Несколько датчиков на одной линии

Датчики подключаются параллельно к тем же трём проводам. Резистор подтяжки остаётся один на всю линию. Это важно для готовых модулей, у которых резистор 4,7 кОм уже стоит на плате: пять таких модулей на одной линии — это пять резисторов параллельно, 940 Ом, и ток нуля при 5 В — (5 − 0,4) / 940 Ом ≈ 4,9 мА, больше гарантированных 4 мА. Резисторы на модулях, кроме одного, нужно снять.

Порядок работы: один раз найти все датчики поиском и сохранить их коды, затем запускать измерение во всех сразу командой Skip ROM и Convert T и читать каждый по своему коду через Match ROM. Коды стоит хранить в программе с привязкой к месту установки — «котельная», «улица». Номер датчика в результатах поиска для этого не годится: поиск выдаёт устройства в порядке, который задают сами коды, и после замены одного датчика нумерация остальных может сдвинуться.

Паразитное питание и сильная подтяжка

При паразитном питании к датчику идут два провода: DQ и GND, а его вывод VDD соединяют с GND. Пока линия в единице, датчик заряжает внутренний конденсатор CPP и питается от него, когда линия в нуле. Для обмена этого хватает, а для измерения температуры и записи в EEPROM — нет: датчику нужно до 1,5 мА. Через резистор 4,7 кОм такой ток дал бы, по закону Ома, падение 1,5 мА × 4,7 кОм = 7,05 В — больше всего напряжения питания. Даже чтобы удержать на линии 3,0 В при подтяжке к 5 В, ток через резистор не может превышать (5 − 3) / 4,7 кОм ≈ 0,43 мА.

Поэтому на время измерения линию подключают прямо к питанию транзистором — это сильная подтяжка. Даташит DS18B20 требует включить её не позже чем через 10 мкс (tSPON) после последнего бита команды 44h или 48h и держать всё время преобразования (до 750 мс) или записи (не меньше 10 мс). Схема из AN4206 — P-канальный MOSFET BSS84, затвор которого управляется отдельным выводом с открытым стоком, а резистор 10 кОм держит транзистор закрытым, пока вывод отпущен:

Паразитное питание DS18B20 и сильная подтяжка через P-канальный MOSFETЛиния DQ подтянута к +5 В резистором 4,7 кОм. Параллельно резистору стоит P-канальный транзистор Q1: исток на +5 В, сток на линии DQ, затвор подключён к выводу микроконтроллера с открытым стоком и подтянут к истоку резистором R1 10 кОм, который держит транзистор закрытым. На время преобразования температуры или записи в EEPROM микроконтроллер прижимает затвор к нулю, и Q1 соединяет линию прямо с питанием. У обоих датчиков вывод VDD соединён с GND — это признак паразитного питания.VPU = +5 ВR110 кОмQ1BSS84Rpu4,7 кОмМКPIOXPIOYDQDS18B20DQGNDVDDDS18B20DQGNDVDDQ1 открывают не позже 10 мкспосле команды 44h или 48hPIOX и PIOY — выходы с открытым стокомVDD датчиков соединён с GND
Паразитное питание: VDD датчиков на GND, сильная подтяжка — P-канальный MOSFET параллельно резистору 4,7 кОм, по AN4206 и рис. 6 даташита DS18B20

Чем платят за экономию провода:

  • Линия занята на всё время измерения. Пока включена сильная подтяжка, любой другой обмен на шине запрещён — это до 750 мс при 12 битах.
  • Конец измерения не узнать. Слоты чтения после 44h при паразитном питании не работают, поэтому ведущий ждёт максимальное время преобразования для выбранного разрешения.
  • Ток суммируется. Если запустить измерение во всех датчиках сразу, через транзистор пойдёт до 1,5 мА на каждый: десять датчиков — 15 мА.
  • Не выше +100 °C. Производитель не рекомендует паразитное питание выше +100 °C: из-за токов утечки датчик может перестать отвечать.
  • Порог выше. Единица на входе DQ при паразитном питании — от 3,0 В, а не от 2,2 В. Для 3,3-вольтовой системы запас всего 0,3 В, и AN4206 прямо требует в такой системе сильную подтяжку. Кроме того, импульс сброса длиннее 960 мкс может перезапустить датчик.

Узнать, есть ли на шине датчики с паразитным питанием, можно командой Read Power Supply (B4h) после Skip ROM: в следующем слоте чтения такие датчики прижмут линию к нулю. Так делает библиотека DallasTemperature при запуске.

Длинные линии и топология сети (AN148)

1-Wire придумывали для коротких соединений, например чтобы добавить память на одну ножку процессора. Сети на десятки и сотни метров возможны, но требуют правильного ведущего, кабеля и топологии. Основной документ здесь — AN148 «Guidelines for Reliable Long Line 1-Wire Networks». Его рекомендации относятся к витой паре категории 5e и питанию сети 5 В от ведущего.

Радиус и вес сети

AN148 описывает сеть двумя числами:

  • Радиус — длина провода от ведущего до самого дальнего ведомого.
  • Вес — общая длина провода в сети.

Вес ограничивает время нарастания фронтов: чем больше провода, тем больше ёмкость, которую заряжает подтяжка. Радиус определяет, когда возвращаются отражения. Ведомые тоже добавляют вес: устройство в обычном корпусе — примерно как 0,5 м кабеля, iButton — как 1 м. 100 таблеток iButton добавляют 100 м веса, и на столько же нужно сократить кабель. Дорожки на плате и защитные цепи тоже нагружают линию: ёмкость 24 пФ AN148 приравнивает к 0,5 м веса.

Линия, отводы и звезда

Топологии сети 1-Wire по AN148: линия, отводы и звездаСлева линейная топология: одна пара идёт от ведущего к самому дальнему устройству, остальные подключены отводами короче 3 м; радиус и вес сети почти равны длине магистрали. В центре магистраль с отводами 3 м и длиннее: вес равен сумме длины магистрали и всех отводов. Справа звезда: ветви 10, 20 и 30 м расходятся от ведущего, радиус 30 м, вес 60 м; отражения от концов ветвей мешают друг другу, и AN148 такую топологию не рекомендует.ЛинияМКотводы короче 3 мрадиус ≈ вес ≈ длина магистралилучший вариантОтводы 3 м и длиннееМКвес = магистраль + все отводыотражения от концов отводовЗвездаМК10 м20 м30 мрадиус 30 м, вес 60 мAN148 не рекомендуетрадиус — длина провода до самого дальнего устройства, вес — вся длина провода в сети
Топологии по AN148: линия с короткими отводами, магистраль с отводами от 3 м и звезда. У звезды из примера AN148 с ветвями 10, 20 и 30 м радиус 30 м, а вес 60 м

AN148 различает три топологии:

  1. Линия: одна пара идёт от ведущего к самому дальнему устройству, остальные подключены отводами короче 3 м. Это лучший вариант.
  2. Магистраль с отводами 3 м и длиннее. Отражения от концов отводов возвращаются в магистраль и мешают остальным устройствам.
  3. Звезда: несколько ветвей расходятся от ведущего или рядом с ним. В точке разветвления сильно не согласованы сопротивления, отражение от конца одной ветви проходит путь, равный почти всему весу сети, и портит данные. AN148 называет звезду без коммутации самой трудной для надёжной работы, не рекомендует её и не даёт для неё гарантий.

Если сеть смешанная, AN148 советует применять самый строгий из критериев. Если без ветвей не обойтись, их коммутируют: каждую ветвь подключают аналоговым ключом по очереди, и электрически сеть остаётся линией. В примере AN148 сеть с радиусом 150 м и весом 450 м после коммутации ветвей нагружает ведущего как линия весом 150 м. Удобная готовая замена ключам — восьмиканальный ведущий DS2482-800, у которого каждая ветвь подключена к своему каналу.

Сколько метров выдержит линия

ВедущийПредел по AN148
Простая подтяжка резисторомвес около 200 м
Ключ с ограничением скорости спада и подтяжкой 1 кОм (приложение A)радиус и вес до 200 м
DS2480B с RC-фильтром 470 пФ (приложение B)радиус или вес до 200 м; фильтр нужен для сетей 10–100 м
Ведущий с активной подтяжкой по AN244радиус и вес до 500 м

Скорость распространения сигнала в кабеле — около 2/3 скорости света. В кабеле длиной 750 м сигнал идёт туда и обратно 7,5 мкс, и это уже сопоставимо с длительностью нуля в начале слота: ведущий просто не сможет общаться с быстрым ведомым у себя под боком. Так AN148 объясняет, почему радиус ограничен даже при идеальной подтяжке.

Ведущий из одного вывода микроконтроллера с резистором 4,7 кОм рассчитан на короткие сети. AN4206 описывает такие схемы для радиуса до 1 м и трёх–пяти ведомых, а у ведущего I²C — 1-Wire DS2482-100 ёмкость линии на стандартной скорости ограничена 1 нФ. По нашей оценке выше, обычная подтяжка 4,7 кОм к выводу микроконтроллера даёт при 5 В десятки метров кабеля.

Как сделать длинную линию надёжной

  • Топология — линия, отводы короче 3 м, без звёзд. Ветви — через ключи или отдельные каналы ведущего.
  • Кабель — витая пара категории 5e: именно для неё AN148 даёт свои цифры. Линию данных и общий провод разумно вести одной парой.
  • Внешнее питание датчиков. При паразитном питании на большой сети самый тяжёлый случай — длинная серия нулей: линия почти всё время внизу, и ведомые не успевают подзарядиться. Ошибки тогда зависят от данных и появляются то и дело. Ведомое, у которого питание просело, сбрасывается, а потом посылает импульс присутствия и может испортить чужой обмен.
  • Длиннее пауза между слотами. Восстановление не ограничено сверху, и лишние микросекунды в единице дают линии подняться и подзарядить ведомых.
  • Последовательные резисторы на отводах. AN148 описывает 150 Ом в каждой точке подключения отвода: несогласованность в этой точке уменьшается примерно на 20 %, отражения от отвода — на 40 %, но помехоустойчивость падает примерно на 80 %. 100 Ом тоже работают хорошо и меньше ухудшают помехоустойчивость. С активной подтяжкой DS2480B и DS2484 этот приём несовместим.
  • Специальный ведущий для сотен метров: DS2480B или схема с активной подтяжкой из AN244.
  • Без overdrive. На кабелях — только стандартная скорость.

Если нужно передавать данные на сотни метров по одной паре и узлы — не датчики 1-Wire, а контроллеры, удобнее дифференциальный RS-485.

Аппаратные ведущие: DS2482 и DS2480B

Отдельная микросхема-ведущий снимает с процессора точные задержки: она сама формирует слоты, сброс и присутствие, а процессор только передаёт ей байты по I²C или UART.

МикросхемаСвязь с процессоромВозможности
DS2482-100I²C, 100 и 400 кГц; адрес 0x18–0x1B, задаётся выводами AD1 и AD0стандартная скорость и overdrive, внутренняя подтяжка 1–1,675 кОм или активная, сильная подтяжка и вывод PCTLZ для внешнего MOSFET, команда 1-Wire Triplet для поиска; питание 2,9–5,5 В
DS2482-800I²Cвосемь независимых каналов 1-Wire
DS2480BUART или RS-232: 9600 бит/с по умолчанию, 19 200, 57 600 и 115 200 бит/сограничение скорости фронтов и активная подтяжка для длинных линий, сильная подтяжка до 5 В, программирование EPROM от 12 В, настраиваемые длительности; питание только 4,5–5,5 В

DS2482-100 управляется восемью командами: сброс микросхемы (F0h), установка указателя чтения (E1h), запись конфигурации (D2h), сброс 1-Wire (B4h), один бит (87h), запись байта (A5h), чтение байта (96h) и Triplet (78h). Свои слоты у неё такие (типичные значения): импульс сброса 600 мкс, проверка присутствия через 70 мкс, слот 69,3 мкс, ноль 8 мкс при записи 1 и 64 мкс при записи 0, чтение через 14 мкс. У DS2482 внутренняя подтяжка, отдельный резистор 4,7 кОм ей не нужен.

AN4206 называет DS2480B самым сильным одиночным ведущим 1-Wire, способным обслуживать большое число ведомых. AN148 добавляет, что его длительности по умолчанию рассчитаны на небольшие сети, а для сетей побольше их нужно настроить, и программа должна переводить DS2480B в гибкий режим.

CRC8 в 1-Wire

Контрольная сумма 1-Wire — 8-битная CRC с полиномом X⁸ + X⁵ + X⁴ + 1. Ею защищён ROM-код: старший байт — CRC первых семи байт. У DS18B20 ещё и блокнот: байт 8 — CRC байтов 0–7. В железе это сдвиговый регистр из восьми ячеек: входной бит складывается по модулю 2 с выходом последней ячейки, и результат через элементы «исключающее ИЛИ» после 4-й и 5-й ячеек возвращается в регистр (рис. 11 даташита DS18B20, AN27). Регистр в начале обнулён, данные входят в него младшим битом вперёд, как идут по линии, и после последнего бита в регистре остаётся CRC.

Полезные свойства из AN27:

  • Остаток ноль. Если после данных пропустить через регистр и саму CRC, получится 00h. Поэтому проверка сводится к одному сравнению: CRC всех восьми байт ROM-кода должна быть равна нулю.
  • Инверсия даёт 35h. Если вместо CRC пропустить её инверсию, результат всегда 35h. Это удобный тест для своей реализации.
  • Что обнаруживается. Любое нечётное число ошибочных бит в 64-битном коде, любые две ошибки, любая пачка ошибок в пределах 8 бит подряд и большинство более длинных пачек.

Пример из AN27 — код с семейством 02h, серийным номером 00000001B81Ch и CRC A2h. Табличный метод из той же AN27 считает CRC по байтам: новое значение — элемент таблицы с индексом «текущая CRC XOR очередной байт».

Байт по порядку02h1ChB8h01h00h00h00hA2h — сама CRC
CRC после байтаBChAFh1EhDChF4h15hA2h00h

Побитовая реализация на C — без таблицы, восемь проходов цикла на байт:

#include <stdint.h>

/* 1-Wire CRC8: x^8 + x^5 + x^4 + 1, data LSB first, initial value 0 (Maxim AN27) */
uint8_t ow_crc8(const uint8_t *data, uint8_t len)
{
    uint8_t crc = 0;
    while (len--) {
        uint8_t byte = *data++;
        for (uint8_t i = 0; i < 8; i++) {
            uint8_t mix = (crc ^ byte) & 0x01;
            crc >>= 1;
            if (mix)
                crc ^= 0x8C;   /* 0x31 (x^5 + x^4 + 1) with the bit order reversed */
            byte >>= 1;
        }
    }
    return crc;
}

/* Test vector from AN27: family 02h, serial number 00000001B81Ch, CRC A2h */
static const uint8_t an27_rom[8] = { 0x02, 0x1C, 0xB8, 0x01, 0x00, 0x00, 0x00, 0xA2 };
/* ow_crc8(an27_rom, 7) == 0xA2, ow_crc8(an27_rom, 8) == 0x00 */

Мы проверили эту функцию на примере AN27, на свойстве с инверсией и сравнили со всей таблицей из AN187: значения совпадают. Если память не жалко, таблица из 256 байт (она приведена в AN27 и AN187) ускоряет расчёт до одного обращения на байт. В avr-libc есть готовая функция _crc_ibutton_update() в util/crc16.h с тем же полиномом, и в её документации проверка сделана на том же коде 02h … A2h.

Две ловушки:

  • Нули проходят проверку. CRC восьми нулевых байт — тоже ноль. Если линия замкнута на землю, ведущий прочитает одни нули, и блокнот «сойдётся». Поэтому одни нули нужно проверять отдельно — так делает и DallasTemperature.
  • Датчик CRC не проверяет. По даташиту DS18B20 ничто внутри датчика не мешает продолжать обмен при неверной CRC: решение — за ведущим.

Для блоков памяти в микросхемах EEPROM и iButton AN27 описывает ещё CRC-16; ROM-коды и блокнот DS18B20 используют только 8-битную CRC.

Программная реализация на AVR

Программный ведущий нужен там, где под 1-Wire не выделили отдельную микросхему, а это почти любой проект на AVR. Линию DQ подключают к обычному выводу порта с внешним резистором 4,7 кОм. Открытый сток имитируют направлением вывода: бит PORT остаётся нулём, и чтобы прижать линию, вывод делают выходом, а чтобы отпустить — входом без встроенной подтяжки.

#include <avr/io.h>
#include <util/atomic.h>
#include <util/delay.h>   /* define F_CPU, e.g. -DF_CPU=16000000UL, and build with -Os */

/* DQ on PB0 with an external 4.7 kOhm pull-up: the pin only pulls low or releases */
#define OW_DDR  DDRB
#define OW_PORT PORTB
#define OW_PIN  PINB
#define OW_BIT  PB0

static inline void ow_low(void)      { OW_DDR |= (1 << OW_BIT); }   /* output, PORT bit = 0 */
static inline void ow_release(void)  { OW_DDR &= ~(1 << OW_BIT); }  /* input, no internal pull-up */
static inline uint8_t ow_level(void) { return (OW_PIN >> OW_BIT) & 1; }

void ow_init(void)
{
    OW_PORT &= ~(1 << OW_BIT);
    ow_release();
}

/* Reset and presence (AN126: H = 480, I = 70, J = 410 us). Returns 1 if a device answered. */
uint8_t ow_reset(void)
{
    uint8_t presence;
    ow_low();
    _delay_us(480);                 /* an interrupt here only makes the reset pulse longer */
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        ow_release();
        _delay_us(70);
        presence = !ow_level();     /* 0 on the line = presence pulse */
    }
    _delay_us(410);
    if (!ow_level())
        return 0;                   /* still low after the reset: the line is shorted */
    return presence;
}

void ow_write_bit(uint8_t bit)
{
    if (bit) {
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
            ow_low();
            _delay_us(6);           /* A: 1..15 us */
            ow_release();
        }
        _delay_us(64);              /* B: the slave samples 15..60 us after the edge */
    } else {
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
            ow_low();
            _delay_us(60);          /* C: 60..120 us */
            ow_release();
        }
        _delay_us(10);              /* D: recovery */
    }
}

uint8_t ow_read_bit(void)
{
    uint8_t bit;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        ow_low();
        _delay_us(6);               /* A */
        ow_release();
        _delay_us(8);               /* E = 9 us in AN126, minus the overhead: stay below 15 us */
        bit = ow_level();
    }
    _delay_us(55);                  /* F */
    return bit;
}

void ow_write_byte(uint8_t byte)
{
    for (uint8_t i = 0; i < 8; i++) {   /* LSB first */
        ow_write_bit(byte & 1);
        byte >>= 1;
    }
}

uint8_t ow_read_byte(void)
{
    uint8_t byte = 0;
    for (uint8_t i = 0; i < 8; i++) {
        byte >>= 1;
        if (ow_read_bit())
            byte |= 0x80;
    }
    return byte;
}

Что здесь важно:

  • Прерывания запрещены только внутри слота. Если прерывание растянет ноль при записи 0, слот может выйти за 120 мкс; если отложит чтение — ведущий прочитает линию позже 15 мкс. Восстановление после слота прерывания не портят: пауза между слотами не ограничена. Импульс сброса тоже не защищён целиком — 480 мкс с запрещёнными прерываниями могут стоить, например, потерянных байтов UART, а прерывание лишь удлинит импульс. С паразитным питанием помните об ограничении 960 мкс.
  • Задержки — константы. _delay_us() из avr-libc считает такты на этапе компиляции, поэтому её аргумент должен быть константой, F_CPU — заданным, а оптимизация — включённой. На частоте 1 МГц команда длится микросекунду, и требование AN126 о повторяемой задержке в 1 мкс выполнить трудно.
  • Чтение раньше 15 мкс. Вызов функций, сам ATOMIC_BLOCK и чтение порта добавляют такты, поэтому задержка E уменьшена на 1 мкс. Проверьте момент чтения осциллографом, если меняете частоту или компилятор: такты команд AVR помогут оценить накладные расходы.

Чтение одного DS18B20 с внешним питанием на этих функциях:

uint8_t ow_crc8(const uint8_t *data, uint8_t len);   /* see the CRC section */

/* One DS18B20 with external power. Returns 1 and the temperature in 1/16 degC, 0 on error. */
uint8_t ds18b20_read(int16_t *t16)
{
    uint8_t sp[9];
    uint8_t any = 0;

    if (!ow_reset())
        return 0;                          /* no presence pulse */
    ow_write_byte(0xCC);                   /* Skip ROM: the only device on the bus */
    ow_write_byte(0x44);                   /* Convert T */
    for (uint16_t n = 0; !ow_read_bit(); n++)
        if (n > 11000)                     /* 11000 read slots * 70 us = 770 ms */
            return 0;

    if (!ow_reset())
        return 0;
    ow_write_byte(0xCC);
    ow_write_byte(0xBE);                   /* Read Scratchpad, byte 0 first */
    for (uint8_t i = 0; i < 9; i++) {
        sp[i] = ow_read_byte();
        any |= sp[i];
    }
    if (!any || ow_crc8(sp, 8) != sp[8])   /* all zeros pass the CRC, check them apart */
        return 0;
    *t16 = (int16_t)((uint16_t)sp[1] << 8 | sp[0]);
    return 1;
}

Для нескольких датчиков вместо Skip ROM перед чтением ставится Match ROM: байт 55h и восемь байт кода, найденного поиском, начиная с кода семейства.

1-Wire через UART (AN214)

Если у микроконтроллера есть свободный UART со скоростью 115 200 бит/с, он может быть ведущим 1-Wire без программных задержек. Идея AN214: один байт UART — один тайм-слот 1-Wire. Стартовый бит UART — это ноль, с которого начинается слот, а данные байта решают, сколько он продлится.

Ведущий 1-Wire на UART по AN214Выход TXD через буфер с открытым стоком управляет линией DQ, вход RXD подключён к той же линии и читает её обратно, линию подтягивает резистор 4,7 кОм. Один байт UART в формате 8N1 — один тайм-слот 1-Wire: байт 0xFF на скорости 115 200 бит/с даёт короткий импульс 8,7 мкс — запись 1 или слот чтения; байт 0x00 даёт ноль на 78 мкс — запись 0; байт 0xF0 на скорости 9600 бит/с даёт ноль на 521 мкс — импульс сброса, после которого ведомые отвечают импульсом присутствия.UARTМКTXDRXDNC7WZ07VPU4,7 кОмDQк устройствам 1-Wire0xFF при 115 200 бит/с — запись 1 или чтение8,7 мкс0x00 при 115 200 бит/с — запись 078 мкс0xF0 при 9600 бит/с — сброс и присутствиеприсутствие521 мкс
Ведущий 1-Wire на UART по AN214: TXD через буфер с открытым стоком, RXD читает ту же линию. Справа — какие байты дают какие слоты, в масштабе внутри каждой строки

Выход TXD обычно двухтактный, поэтому к линии его подключают через буфер с открытым стоком. В AN214 два варианта: два транзистора 2N7002 с резистором 100 кОм или микросхема NC7WZ07. Вход RXD соединяют прямо с линией, и UART принимает байт на каждый переданный — как в режиме петли. Если вывод TX вашего микроконтроллера можно настроить как выход с открытым стоком, внешний буфер не нужен.

ОперацияСкорость UARTПередатьЧто придёт в ответНоль на линии
Сброс и присутствие9600 бит/сF0hF0h — никто не ответил; другое значение — есть импульс присутствия521 мкс: стартовый бит и четыре нуля
Запись 1115 200 бит/сFFhFFh8,7 мкс: только стартовый бит
Запись 0115 200 бит/с00h00h78 мкс: стартовый бит и восемь нулей
Чтение бита115 200 бит/сFFhFFh — прочитана 1; меньше FFh, младший бит 0, — прочитан 08,7 мкс от ведущего, дальше держит ведомое

Формат кадра — 8 бит, без чётности, один стоп-бит. Почему это работает, видно из чисел. На 115 200 бит/с бит длится 8,68 мкс: стартовый бит попадает в окно 1–15 мкс для записи 1, а девять нулей подряд, 78 мкс, — в окно 60–120 мкс для записи 0. Приёмник UART читает каждый бит посередине, и младший бит данных он прочитает через 1,5 бита, то есть через 13 мкс после спада — до границы 15 мкс. На 9600 бит/с пять нулевых бит дают 521 мкс — это импульс сброса, а импульс присутствия, пришедший в оставшейся половине кадра, превращает принятый байт из F0h в другое значение.

Допуски у 1-Wire широкие, поэтому погрешность скорости UART в пару процентов на обмен не влияет — проверить её для своей частоты поможет калькулятор скорости UART. Зато прерывания больше не страшны: слот формирует аппаратура, а между байтами может пройти сколько угодно времени. С очередями FIFO и DMA процессор отправляет целый байт 1-Wire — восемь байт UART — одной операцией.

/* Board-specific: change the baud rate, send a byte and return the byte received back */
extern void    uart_set_baud(uint32_t baud);
extern uint8_t uart_txrx(uint8_t byte);

uint8_t ow_uart_reset(void)               /* returns 1 if a presence pulse was seen */
{
    uart_set_baud(9600);
    uint8_t r = uart_txrx(0xF0);
    uart_set_baud(115200);
    return r != 0xF0;
}

uint8_t ow_uart_bit(uint8_t bit)          /* writes 0 or 1; with bit = 1 also reads */
{
    return uart_txrx(bit ? 0xFF : 0x00) & 0x01;
}

Arduino: библиотеки OneWire и DallasTemperature

В Arduino с 1-Wire работают две библиотеки. OneWire Пола Стоффрегена отвечает за слоты: сброс, запись, чтение, поиск и CRC. DallasTemperature Майлза Бёртона построена поверх неё и знает команды термометров DS18B20, DS18S20, DS1822 и DS1825. Подключение то же: DQ на цифровой вывод, резистор 4,7 кОм между DQ и 5 В — пример из OneWire прямо пишет, что резистор обязателен.

Как OneWire формирует слоты

В OneWire 2.3.8 длительности такие, а прерывания запрещены только на критичных участках:

ОперацияOneWire 2.3.8AN126
Сбросноль 480 мкс, проверка через 70 мкс, ожидание 410 мкс480, 70 и 410 мкс
Запись 1ноль 10 мкс, затем 55 мкс6 и 64 мкс
Запись 0ноль 65 мкс, затем 5 мкс60 и 10 мкс
Чтениеноль 3 мкс, чтение через 10 мкс, затем 53 мкс6, 9 и 55 мкс

Обратите внимание на запись. После нуля OneWire не просто отпускает линию, а выставляет на ней единицу выходом микроконтроллера и отпускает вывод только после байта. Если вызвать write(0x44, 1), вывод так и останется в единице, и сам микроконтроллер станет сильной подтяжкой для датчика с паразитным питанием. Снять её можно функцией depower() или следующим сбросом. На короткой линии с одним-двумя датчиками этого хватает; для большего тока нужен транзистор.

Что делает DallasTemperature

  • begin() ищет все устройства, считает термометры, по команде B4h проверяет, нет ли датчиков с паразитным питанием, и запоминает наибольшее разрешение.
  • requestTemperatures() посылает сброс, Skip ROM и 44h — измерение запускается во всех датчиках сразу. Дальше по умолчанию функция ждёт: при внешнем питании опрашивает слотами чтения, пока датчик не ответит 1, но не дольше 750 мс, а при паразитном выжидает фиксированное время — 94, 188, 375 или 750 мс для 9–12 бит.
  • getTempC(адрес) читает блокнот по Match ROM и возвращает градусы. Если датчик не ответил импульсом присутствия, блокнот состоит из одних нулей или CRC не сошлась, вместо температуры приходит −127.
  • getTempCByIndex(i) перед каждым чтением заново выполняет поиск до i-го устройства, поэтому для нескольких датчиков лучше один раз получить адреса через getAddress() и читать по ним.

Асинхронный режим освобождает программу на время измерения: setWaitForConversion(false) заставляет requestTemperatures() вернуться сразу, а дальше программа либо ждёт millisToWaitForConversion(), либо спрашивает isConversionComplete() — второе работает только при внешнем питании.

#include <OneWire.h>
#include <DallasTemperature.h>

OneWire oneWire(2);                       // DQ on pin 2, 4.7 kOhm to 5 V
DallasTemperature sensors(&oneWire);
DeviceAddress addr[4];
uint8_t count;
uint32_t started;
bool converting = false;

void setup() {
  Serial.begin(115200);
  sensors.begin();                        // Search ROM, power mode, resolution
  count = min(sensors.getDeviceCount(), (uint8_t)4);
  for (uint8_t i = 0; i < count; i++) sensors.getAddress(addr[i], i);
  sensors.setWaitForConversion(false);    // requestTemperatures() returns at once
}

void loop() {
  if (!converting) {
    sensors.requestTemperatures();        // Skip ROM + 44h: all sensors at once
    started = millis();
    converting = true;
  } else if (millis() - started >= sensors.millisToWaitForConversion(12)) {
    for (uint8_t i = 0; i < count; i++) {
      float t = sensors.getTempC(addr[i]);
      if (t == DEVICE_DISCONNECTED_C) Serial.println("no answer or CRC error");
      else Serial.println(t, 4);
    }
    converting = false;
  }
  // other work here: the bus is free while the sensors convert
}

Если датчики на паразитном питании и сильная подтяжка сделана транзистором, его затвор подключают к отдельному выводу и передают номер этого вывода вторым параметром конструктора: DallasTemperature sensors(&oneWire, 7). На время измерения библиотека выставит на нём ноль — под P-канальный транзистор из схемы выше. Делает она это только в блокирующем режиме, внутри ожидания: в асинхронном режиме транзистор придётся включать и выключать самому.

Что значат −127 и 85

  • −127 — не температура, а константа DEVICE_DISCONNECTED_C: датчик не ответил, блокнот пустой или CRC не сошлась. Проверяйте подтяжку, выводы, адрес и линию. Сравнивать с ней результат нужно до любых расчётов.
  • 85 — значение после включения питания, о нём выше. До версии 4.0.5 включительно DallasTemperature возвращала его как обычную температуру. В версии 4.0.6 (февраль 2026 года) появилась проверка: если в блокноте 50h и 05h, а в зарезервированном байте 6 — 0Ch, getTemp() возвращает код ошибки DEVICE_POWER_ON_RESET_RAW, а getTempC() в этом случае отдаёт те же −127. Байт 6 даташит не описывает, это наблюдение авторов библиотеки. Значения FFh и 07h в байтах 0 и 1 версия 4.0.6 считает признаком нехватки питания и в этом случае тоже возвращает −127.

iButton и другие устройства 1-Wire

УстройствоКод семействаЧто этоОсобенности
DS18B2028hтермометр−55…+125 °C, 9–12 бит, внешнее или паразитное питание
DS1990A01hсерийный номер в корпусе iButtonтолько чтение кода и поиск; читается быстрее 5 мс; 16,3 кбит/с
DS240101hсерийный номер в обычном корпусеTO-92, SOT-223, TSOC; питание от линии, подтяжка 2,8–6 В через 1,5–5 кОм
DS24312DhEEPROM на 1024 бита, четыре страницы по 256 битстраницы можно защитить от записи; 15,4 и 125 кбит/с; подтяжка не больше 2,2 кОм
DS24133Ahдва ключа с открытым стокомключи на 28 В и до 20 мА; питание от линии; 14,9 и 100 кбит/с
DS2482-100—ведущий I²C — 1-Wireсам не ведомое, ROM-кода у него нет

iButton — это микросхема 1-Wire в круглом корпусе MicroCan из нержавеющей стали диаметром 16,3 мм: крышка — контакт данных, нижняя часть с фланцем — общий провод, а ROM-код выгравирован на крышке. Микросхемы с номером на DS19 — всегда iButton (AN1796). Самая массовая из них — DS1990A с одним только серийным номером, её применяют для контроля доступа и учёта. Считыватель — контактная площадка, подключённая к линии 1-Wire, и ведущему достаточно время от времени посылать сброс: появился импульс присутствия — таблетку приложили. Book of iButton Standards описывает и обратный механизм: отсоединённая таблетка тянет свой вывод данных к нулю внутренним источником тока 5 мкА и, коснувшись линии, сама отвечает импульсом присутствия; у DS1990R такой импульс при касании гарантирован (AN1796). Поэтому поиск в сетях с iButton, по AN148, должен переживать случайные импульсы присутствия, а устройство из списка найденных удаляют, только если его не видно какое-то время.

DS2401 — тот же серийный номер, но для пайки на плату: им помечают платы, модули и сменные блоки, чтобы прибор узнавал, что в него вставили. DS2431 добавляет 128 байт памяти для калибровок и паспортных данных, а DS2413 — два управляемых вывода, например для светодиода и кнопки.

Типичные ошибки и отладка

СимптомВероятная причинаЧто проверить
Нет импульса присутствия, −127нет подтяжки, обрыв DQ или GND, перепутаны выводы, не тот вывод в программена свободной линии должно быть почти полное питание; выводы TO-92: 1 — GND, 2 — DQ, 3 — VDD
85 °Cизмерение не запускали, прочитали раньше времени, датчику не хватило питания44h перед чтением, ожидание до 750 мс, сильная подтяжка при паразитном питании
Один датчик работает, несколько — нетна каждом модуле свой резистор, слишком большой вес линииодин резистор на линию; ток нуля не больше 4 мА
На столе работает, на объекте сбоитдлинный кабель, звезда, паразитное питание на большой сетитопология «линия», внешнее питание, сильнее ведущий — по AN148
Ошибки CRC на длинном проводе, единицы читаются как нулислишком большой резистор подтяжки, например 10 кОм, или слишком большая ёмкость линиифронт осциллографом: к моменту чтения линия должна быть выше порога единицы; резистор 4,7 кОм или меньше, но не ниже предела по току
Редкие ошибки CRCпрерывания внутри слотов, чтение позже 15 мкс, помехизапрет прерываний в слоте, момент чтения осциллографом
Устройства пропадают из результатов поискаотражения, просадка паразитного питания, ложное срабатывание активной подтяжкивес и радиус сети, отводы, питание датчиков
Неверный ROM-кодRead ROM при нескольких устройствах, перепутан порядок байтовпоиск вместо Read ROM; первым байтом должен идти код семейства
Все датчики показывают одно и то же или мусорSkip ROM и Read Scratchpad при нескольких датчикахчтение по Match ROM

Что смотреть осциллографом

Осциллограф на DQ показывает сразу всё: уровни, длительности и форму фронтов. Сначала сброс — ноль не меньше 480 мкс от ведущего, затем пауза и импульс присутствия 60–240 мкс. На фронтах видно, успевает ли линия подняться: при записи 1 и при чтении единицы она должна выйти к порогу единицы задолго до 15 мкс от спада. Ноль от ведомого должен быть не выше 0,4–0,8 В — если выше, подтяжка слишком сильная. AN148 предупреждает: в любой точке сети, кроме стороны ведущего, сигнал смотрят только дифференциальным пробником, чтобы «земля» осциллографа не повлияла на линию.

Логический анализатор

Логический анализатор с декодером 1-Wire показывает обмен по командам: сброс, присутствие, ROM-команду, код, данные. Это быстрый способ понять, отвечает ли датчик и что именно он отвечает. Частоту выборки берите с запасом — хотя бы несколько мегагерц, чтобы декодер уверенно различал нули в 1–15 мкс. Аналоговых проблем анализатор не видит: медленные фронты и высокий ноль он покажет как случайные ошибки, поэтому при странных результатах переходите к осциллографу.

Дальше по теме: I²C — другая шина с открытым стоком и подтяжкой, SPI — для быстрого обмена внутри платы, RS-485 — для длинных линий. Остальные интерфейсы — в разделе интерфейсы, микроконтроллеры, к которым подключают датчики, — в разделе AVR.

Частые вопросы

Какой резистор подтяжки нужен для DS18B20: 4,7 кОм или 10 кОм?

4,7 кОм между DQ и питанием — номинал из даташита DS18B20, один резистор на всю линию у ведущего. 10 кОм хуже: фронты затягиваются, и на длинном проводе единица не успевает установиться к моменту чтения. Слишком маленький резистор тоже не годится: DS18B20 гарантированно втягивает 4 мА при 0,4 В, поэтому при 5 В нижняя граница — около 1,15 кОм. Другие устройства требуют своего: DS2431 — не больше 2,2 кОм, DS2401 — 1,5–5 кОм.

Почему DS18B20 показывает 85 °C?

85 °C, код 0550h, — значение регистра температуры сразу после включения питания. Его читают, если датчик ещё не закончил ни одного преобразования: не отправлена команда 44h, блокнот прочитан раньше, чем прошли 750 мс при 12 битах, или датчик перезапустился из-за нехватки питания во время измерения. Последнее типично для паразитного питания без сильной подтяжки.

Что значит −127 °C в библиотеке DallasTemperature?

Это не температура, а код ошибки DEVICE_DISCONNECTED_C. getTempC() возвращает его, если датчик не ответил импульсом присутствия, если прочитанный блокнот состоит из одних нулей или если не сошлась CRC. Частые причины — нет подтяжки, обрыв, перепутаны выводы, неверный адрес, помехи на длинной линии. Начиная с версии 4.0.6 тот же код возвращается и при чтении датчика, который ещё не измерял температуру после включения.

Сколько датчиков DS18B20 можно подключить к одной линии?

Адресов хватит на любое число: у каждого датчика свой 48-битный серийный номер. Ограничивает нагрузка на линию. По AN148 каждое устройство в обычном корпусе добавляет к сети столько же, сколько примерно 0,5 м кабеля, а ведущий с резистивной подтяжкой вытягивает около 200 м такой нагрузки. При паразитном питании нужен ещё и ток: при измерении каждый датчик берёт до 1,5 мА, и десять одновременных измерений требуют 15 мА через сильную подтяжку.

Какая максимальная длина линии 1-Wire?

Единой цифры нет: длина зависит от ведущего, кабеля, топологии и числа устройств. AN148 даёт ориентиры для витой пары категории 5e и питания 5 В: ведущий на ключе с подтяжкой 1 кОм — до 200 м, DS2480B с RC-фильтром — до 200 м, ведущий с активной подтяжкой по AN244 — до 500 м, причём в топологии «линия». С обычным резистором 4,7 кОм у вывода микроконтроллера по оценке в статье надёжны десятки метров.

Можно ли питать DS18B20 от 3,3 В?

Да: и внешнее, и паразитное питание по даташиту — от 3,0 до 5,5 В. Но при паразитном питании порог единицы на входе DQ — 3,0 В, и при 3,3 В запас всего 0,3 В: линия должна подняться почти до питания, поэтому длинный провод и много датчиков не получатся. При 3,3 В надёжнее подать на датчики внешнее питание, а если нужно паразитное — ставить сильную подтяжку, как советует AN4206.

Источники

  1. Analog Devices (Maxim Integrated). DS18B20 Programmable Resolution 1-Wire Digital Thermometer, 19-7487, Rev 6, 7/19 — таблицы DC и AC — пороги, токи, длительности слотов; рис. 4 и табл. 1 — формат температуры; рис. 6 и 7 — подключение; рис. 9 и 10 — блокнот и конфигурация; табл. 3 — функциональные команды; рис. 15–18 — сброс, запись и чтение
  2. Maxim Integrated. Application Note 126: 1-Wire Communication Through Software, версия 2.3 — табл. 1 и 2 — четыре операции и рекомендуемые задержки A–J для стандартной скорости и overdrive
  3. Maxim Integrated. Application Note 187: 1-Wire Search Algorithm — табл. 1 и 3 — разбор пары бит и выбор направления, табл. 4 — варианты поиска, код на C
  4. Maxim Integrated. Tutorial 148: Guidelines for Reliable Long Line 1-Wire Networks, 2014 — радиус и вес сети, топологии, вес устройств и кабеля, пределы для разных ведущих, ошибки программного ведущего
  5. Maxim Integrated. Tutorial 214: Using a UART to Implement a 1-Wire Bus Master, 2002 — рис. 2 — буфер с открытым стоком, рис. 4–8 — байты и скорости UART для сброса, записи и чтения
  6. Maxim Integrated. Application Note 27: Understanding and Using Cyclic Redundancy Checks with Maxim 1-Wire and iButton Products — полином CRC8, свойства, пример расчёта для кода 02h, 00000001B81Ch, A2h, табличный метод
  7. Dallas Semiconductor. Application Note 937: Book of iButton Standards, 1997 — гл. 4 — временные параметры стандартной скорости и overdrive, tRDV и tRELEASE; гл. 5 — ROM-команды и структура кода семейства
  8. Maxim Integrated. Application Note 4206: Choosing the Right 1-Wire Master for Embedded Applications, 2008 — рис. 1 — сильная подтяжка на BSS84 с резистором 10 кОм; категории ведущих, DS2480B и DS2482
  9. Maxim Integrated. Tutorial 1796: Overview of 1-Wire Technology and Its Use, 2008
  10. Analog Devices (Maxim Integrated). DS2482-100 Single-Channel 1-Wire Master, 19-4930, Rev 10, 1/15 — адрес I2C, команды, временные параметры, ёмкость линии не больше 1 нФ
  11. Analog Devices. DS2401 Silicon Serial Number, 19-5860, Rev 12/23
  12. Analog Devices (Maxim Integrated). DS2480B Serial to 1-Wire Line Driver
  13. Analog Devices (Maxim Integrated). DS2431 1024-Bit 1-Wire EEPROM, 19-4675, Rev 16, 5/21 — сравнительная таблица временных параметров стандартной скорости и overdrive, команды Resume и Overdrive
  14. Analog Devices (Maxim Integrated). DS2413 1-Wire Dual Channel Addressable Switch; DS1990A Serial Number iButton, 19-8145
  15. Paul Stoffregen и др. Библиотека OneWire для Arduino, версия 2.3.8 — OneWire.cpp — длительности сброса, записи и чтения, параметр power
  16. Miles Burton и др. Библиотека DallasTemperature (Arduino-Temperature-Control-Library), версия 4.0.6 — DallasTemperature.cpp — requestTemperatures(), ожидание преобразования, коды ошибок
  17. avr-libc: модуль util/crc16.h, функция _crc_ibutton_update — тот же полином и тот же тестовый код 02h … A2h; требования к _delay_us() — в описании модуля util/delay.h