Files
templates/c/ds18b20/README.md
Andrey Kruchinkin 873ac438f3 feat(ds18b20): термометры DS18B20 поверх программной 1-Wire
Перенесён из репозитория ds18b20, который подключался сабмодулем в
KONOR_ds18b20. История библиотеки осталась там; сюда пришло состояние
на момент переезда.

Ядро на C99 без stm32f10x.h и динамической памяти. Порт — пять функций
(Init, DelayUs, Reset, WriteBit, ReadBit); реализация для STM32F1 идёт
в комплекте в ports/stm32f1. Хостовые тесты на модели шины с виртуальными
датчиками проходят: tests/test_ds18b20.c.
2026-08-23 01:15:34 +03:00

6.5 KiB
Raw Blame History

ds18b20

Драйвер термометров DS18B20 поверх программной шины 1-Wire. Вынесен из проекта KONOR_ds18b20 и подключается в него сабмодулем.

Ядро на C99: ни динамической памяти, ни ОС, ни stm32f10x.h. Всё аппаратно-зависимое собрано в порте — на новую платформу переносятся пять функций, остальное собирается как есть.

        приложение
             │
        ds18b20.c        поиск датчиков, чтение и запись scratchpad
             │
        onewire.c        побайтовый обмен, CRC8, SEARCH ROM, MATCH/SKIP ROM
             │
      ports/<платформа>  Init, DelayUs, Reset, WriteBit, ReadBit

Состав

Файл Что делает Зависимости
include/ds18b20.h, src/ds18b20.c перечень датчиков, измерения, запись TH/TL/разрешения onewire.h, stdint.h
include/onewire.h, src/onewire.c байты и блоки, CRC8 Dallas/Maxim, обход SEARCH ROM stdint.h
ports/stm32f1/ тайминги Maxim, вывод с открытым стоком, задержки по DWT CMSIS stm32f10x.h
tests/ симулятор шины с виртуальными датчиками и host-тесты

Порт: что нужно от платформы

void    OneWire_Init(void);                  /* настроить вывод и источник задержек */
void    OneWire_DelayUs(uint32_t us);
uint8_t OneWire_Reset(void);                 /* сброс и проверка presence */
void    OneWire_WriteBit(uint8_t bit);
uint8_t OneWire_ReadBit(void);

Всё остальное — OneWire_WriteByte, OneWire_ReadByte, OneWire_Crc8, OneWire_SearchNext, OneWire_SelectRom, OneWire_SkipRom и весь ds18b20.c — уже написано и от платформы не зависит.

Готовый порт STM32F1

Вывод настроен как выход с открытым стоком; чтение идёт через IDR, поэтому режим не переключается. Прерывания запрещаются только на длительность одного тайм-слота, чтобы не терять байты USART. Источник микросекундных задержек — счётчик тактов ядра DWT->CYCCNT.

Привязку вывода порт берёт из onewire_config.h, который предоставляет приложение — шаблон лежит рядом:

#include "stm32f10x.h"

#define ONEWIRE_GPIO        GPIOA
#define ONEWIRE_PIN         1U
#define ONEWIRE_GPIO_CLOCK  RCC_APB2ENR_IOPAEN

Требуется внешняя подтяжка 4.7 кОм к питанию.

Использование

DS18B20_Bus bus;

OneWire_Init();
DS18B20_Scan(&bus);                     /* найти датчики на шине */

DS18B20_StartConversion();              /* SKIP ROM + CONVERT T  */
/* выдержать DS18B20_ConversionTimeMs(config) */
DS18B20_ReadAll(&bus);                  /* обновить измерения    */

for (uint8_t i = 0; i < bus.count; i++) {
    if (bus.sensors[i].status & DS18B20_STATUS_VALID) {
        float celsius = bus.sensors[i].raw / 16.0f;
    }
}

Ошибка одного датчика не прерывает опрос остальных — она видна в поле status соответствующей записи.

Тесты

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

cmake -B build && cmake --build build && ctest --test-dir build
clang -std=c99 -Wall -Wextra -Iinclude -Itests \
    tests/test_ds18b20.c tests/fake_onewire.c src/onewire.c src/ds18b20.c -o test && ./test

Покрыто: CRC8, обход шины с несколькими датчиками и пустой шины, отсев чужих семейств по коду ROM, паразитное питание, битый scratchpad, пропажа датчика, подтверждение и отказ записи, сохранение в EEPROM датчика, пределы разрешения 9..12 бит.

Особенности, которые стоит знать

  • Порядок датчиков задаёт шина, а не код. SEARCH ROM обходит их в порядке битов идентификатора, поэтому индекс в bus.sensors[] не совпадает с порядком подключения. Искать датчик нужно по ROM через DS18B20_Find().
  • Пропажу датчика на живой шине не видно по presence. Импульс подтверждают соседи, и MATCH ROM к снятому датчику проходит без признаков ошибки — она проявится как DS18B20_STATUS_CRC_ERROR. DS18B20_STATUS_NO_PRESENCE означает, что молчит вся шина.
  • DS18B20_MAX_SENSORS равен 8 — столько датчиков помещается в один кадр SENSOR_DATA протокола SETGUI. Для другого применения значение можно поднять.
  • Обратное чтение после записи обязательно. Датчик может ответить и оставить регистры прежними; такой случай отличается от ошибки шины кодом DS18B20_WRITE_REJECTED.

Лицензия и происхождение

Код вынесен из KONOR_ds18b20 (модуль термометрии на STM32F103C8T6) без изменения поведения: разделение на ядро и порт сделано переносом функций, тела не правились.