A lightweight and efficient 1-Wire protocol library written in C for STM32 (HAL-based).
Unlike blocking implementations, this library uses asynchronous, non-blocking operation driven by a single timer interrupt.
It can run on any GPIO pins.
It supports a wide range of Maxim/Dallas devices, including:
- π‘οΈ DS18B20 β Temperature sensor
- π DS2431 β EEPROM
- π DS28E17 β IΒ²C master bridge
- π DS1990A iButton β Authentication token
- β‘ Any other standard 1-Wire device
The library is designed for:
- Projects where CPU blocking must be avoided
- Applications that need multi-device 1-Wire bus support
- Easy portability across different STM32 families (F0/F1/F3/F4/F7/G0/G4/H7, etc.)
- πΉ Single or multiple device support (
OW_MAX_DEVICE
) - πΉ Full STM32 HAL compatibility
- πΉ ROM ID operations (read, match, skip, search)
- πΉ Robust error handling (reset, bus, ROM, length)
- πΉ Non-blocking operation via timer callbacks
- πΉ Clean and modular API
- πΉ Support Single and Dual pins (for insolation circuits)
You can install in two ways:
Add these files to your STM32 project:
ow.h
ow.c
ow_config.h
Available in the official pack repo:
π STM32-PACK (Not Ready)
Defines library limits and timing values. Example:
#define OW_MAX_DEVICE 4 // Max number of devices
#define OW_MAX_DATA_LEN 32 // Max data length
#define OW_DUAL_PINS 0 // Enable if using dual pins(TX/RX) for isolation
-
GPIO Pin
- Configure as Output Open-Drain (e.g.,
PC8
). - In dual pins mode, set TX pin as Output Push-PULL and set RX pin as ** INPUT ** (e.g.,
PC8
,PC7
).
- Configure as Output Open-Drain (e.g.,
-
Timer
- Use internal clock source.
- Prescaler set for
1 Β΅s
tick.- Example: 170 MHz bus β Prescaler =
170 - 1
.
- Example: 170 MHz bus β Prescaler =
- Enable Timer NVIC interrupt.
- In Project Manager β Advanced Settings, enable Register Callback for the timer.
- In Project Manager β Code Generator, enable Generate Peripheral initialization as a pair ".c/.h" files per peripheral.
#include "ow.h"
ow_handle_t ds18;
void ds18_tim_cb(TIM_HandleTypeDef *htim)
{
ow_callback(&ds18);
}
void ds18_done_cb(ow_err_t error)
{
}
ow_init_t ow_init_struct;
ow_init_struct.tim_handle = &htim1;
ow_init_struct.gpio = GPIOC;
ow_init_struct.pin = GPIO_PIN_8;
ow_init_struct.tim_cb = ds18_tim_cb;
ow_init_struct.done_cb = ds18_done_cb; // Optional: callback when transfer is done, or can use NULL
ow_init_struct.rom_id_filter = 0; // 0 = Accept All, or use a value. (Available if OW_MAX_DEVICE > 1)
ow_init(&ds18, &ow_init_struct);
Now the library is readyβuse any ow_*
functions.
uint8_t data[16];
ow_update_rom_id(&ds18);
while (ow_is_busy(&ds18));
HAL_Delay(10);
ow_xfer_by_id(&ds18, 0, 0x44, NULL, 0, 0);
HAL_Delay(1000);
ow_xfer_by_id(&ds18, 0, 0xBE, NULL, 0, 9);
while (ow_is_busy(&ds18));
ow_read_resp(&ds18, data, 16);
Function | Description |
---|---|
ow_init() |
Initialize one-wire handle |
ow_callback() |
Timer callback (must be called in IRQ) |
ow_crc() |
Calculate CRC |
ow_is_busy() |
Check if bus is busy |
ow_last_error() |
Get last error |
ow_update_rom_id() |
Detect and update connected ROM IDs |
ow_xfer() |
Write command + Read/Write data to/from the bus (no specific ROM ID) |
ow_xfer_by_id() |
Write command + Read/Write data to/from the bus (selected ROM ID) |
ow_devices() |
Get number of detected devices (only if multi-device enabled) |
ow_read_resp() |
Copy response buffer to user data |
If you find this project useful, please β star the repo and consider supporting!
Licensed under the terms in the LICENSE.