Перенесён из репозитория ds18b20, который подключался сабмодулем в KONOR_ds18b20. История библиотеки осталась там; сюда пришло состояние на момент переезда. Ядро на C99 без stm32f10x.h и динамической памяти. Порт — пять функций (Init, DelayUs, Reset, WriteBit, ReadBit); реализация для STM32F1 идёт в комплекте в ports/stm32f1. Хостовые тесты на модели шины с виртуальными датчиками проходят: tests/test_ds18b20.c.
6.5 KiB
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)
без изменения поведения: разделение на ядро и порт сделано переносом
функций, тела не правились.