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

128 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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-тесты | — |
## Порт: что нужно от платформы
```c
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`, который предоставляет
приложение — шаблон лежит рядом:
```c
#include "stm32f10x.h"
#define ONEWIRE_GPIO GPIOA
#define ONEWIRE_PIN 1U
#define ONEWIRE_GPIO_CLOCK RCC_APB2ENR_IOPAEN
```
Требуется внешняя подтяжка 4.7 кОм к питанию.
## Использование
```c
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`. Так на хосте проверяется именно то,
что иначе проверялось бы только осциллографом.
```bash
cmake -B build && cmake --build build && ctest --test-dir build
```
```bash
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)
без изменения поведения: разделение на ядро и порт сделано переносом
функций, тела не правились.