чуть структурирована, добавлено описение по подключению в шапке

добавлен пример для stm32
This commit is contained in:
2025-06-21 09:05:50 +03:00
parent c2dca42be6
commit 7ef076e289
928 changed files with 481793 additions and 461 deletions

View File

@@ -2,12 +2,68 @@
******************************************************************************
* @file dallas_tools.c
* @brief Драйвер для работы с датчиками температуры DS18B20
* @author MicroTechnics (microtechnics.ru)
******************************************************************************
@details
Этот файл содержит реализацию функций для работы с датчиком DS18B20
через интерфейс 1-Wire. Он предоставляет функции для чтения и записи
конфигурации, выполнения измерений и обработки полученных данных.
@details
Библиотека предназначена для работы с цифровыми датчиками температуры DS18B20
по однопроводному интерфейсу 1-Wire. Реализована поддержка инициализации, поиска,
добавления и работы с несколькими датчиками.
@verbatim
==============================================================================
## Основные задачи библиотеки ##
==============================================================================
Эта библиотека предоставляет следующие основные функции:
(+) Инициализация шины 1-Wire и обнаружение подключённых датчиков
(+) Инициализация структуры датчика по:
- ROM-адресу
- пользовательским байтам (TH, TL, UserByte3, UserByte4)
- порядковому номеру в списке найденных устройств
(+) Конфигурация разрешения измерения
(+) Чтение температуры
(+) Замена «потерянного» датчика
(+) Деинициализация структуры датчика
==============================================================================
## Быстрый старт ##
==============================================================================
Пример последовательности инициализации и использования:
1. Подключение библиотеки и настройка таймеров:
#include "dallas_tools.h"
MX_TIM_Init();
2. Инициализация шины и поиск датчиков:
Dallas_BusFirstInit(&htim);
3. Инициализация датчика Dallas_SensorHandleTypeDef по одному из методов:
sens1.Init.init_func = &Dallas_SensorInitByInd; // по индексу
sens1.Init.InitParam.Ind = 0; // порядковый номер найденного датика для инициализации
sens2.Init.init_func = &Dallas_SensorInitByROM; // по ROM-адресу
sens2.Init.InitParam.ROM = 0; // ROM датика для инициализации
sens3.Init.init_func = &Dallas_SensorInitByUserBytes; // по пользовательским байтам
sens3.Init.InitParam.UserBytes.UserByte1 = 1; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte2 = 2; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte3 = 3; // UseBytes датика для инициализации
sens3.Init.InitParam.UserBytes.UserByte4 = 4; // UseBytes датика для инициализации
4. Инициализация структуруы датчика:
Dallas_AddNewSensors(&hdallas, &sens);
5. Работа с датчиком:
Dallas_StartConvertTAll(hdallas, DALLAS_WAIT_BUS, 0);
Dallas_ReadTemperature(&sens);
==============================================================================
## Требуемые зависимости ##
==============================================================================
Для работы библиотеки требуется:
- Драйвер OneWire (файлы onewire.c/h и ow_port.c/.h)
- Драйвер DS18B20 (файлы ds18b20.c/h)
@endverbatim
==============================================================================
*****************************************************************************/
@@ -28,17 +84,18 @@ DALLAS_HandleTypeDef hdallas;
*/
HAL_StatusTypeDef Dallas_BusFirstInit(TIM_HandleTypeDef *htim)
{
if(htim == NULL)
return HAL_ERROR;
HAL_StatusTypeDef result;
if(HAL_TIM_Base_Start(htim))
return HAL_ERROR;
HAL_TIM_Base_Start(htim);
hdallas.onewire = &OW;
hdallas.ds_devices = &DS;
OW.DataPin = DS_Pin;
OW.DataPort = DS_GPIO_Port;
OW.DataPin = OW_Pin;
OW.DataPort = OW_GPIO_Port;
/* Инициализация onewire и поиск датчиков*/
OneWire_Init(&OW);
@@ -71,225 +128,7 @@ HAL_StatusTypeDef Dallas_AddNewSensors(DALLAS_HandleTypeDef *hdallas, DALLAS_Sen
/**
* @brief Инициализирует структуру датчика по ROM
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t ROM[8] = {0};
ROM[0] = (sensor->Init.InitParam >> (7*8)) & 0xFF;
ROM[1] = (sensor->Init.InitParam >> (6*8)) & 0xFF;
ROM[2] = (sensor->Init.InitParam >> (5*8)) & 0xFF;
ROM[3] = (sensor->Init.InitParam >> (4*8)) & 0xFF;
ROM[4] = (sensor->Init.InitParam >> (3*8)) & 0xFF;
ROM[5] = (sensor->Init.InitParam >> (2*8)) & 0xFF;
ROM[6] = (sensor->Init.InitParam >> (1*8)) & 0xFF;
ROM[7] = (sensor->Init.InitParam >> (0*8)) & 0xFF;
if(DS18B20_IsValidAddress(ROM) != HAL_OK)
return HAL_ERROR;
uint8_t comparebytes = DALLAS_ROM_SIZE;
int ROM_ind = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
comparebytes = DALLAS_ROM_SIZE;
for(int rom_byte = 0; rom_byte < DALLAS_ROM_SIZE; rom_byte++)
{
if(hdallas->ds_devices->DevAddr[i][rom_byte] == ROM[rom_byte])
comparebytes--;
}
if(comparebytes == 0)
{
ROM_ind = i;
break;
}
}
/* Проверка присутствует ли выбранный датчик на линии */
if(comparebytes == 0)
{
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[ROM_ind]);
return result;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief Инициализирует структуру датчика по пользовательским байтам
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t UserByte1 = sensor->Init.InitParam & 0xFF;
uint8_t UserByte2 = sensor->Init.InitParam >> 8;
uint8_t UserByte3 = (sensor->Init.InitParam >> 16) & 0xFF;
uint8_t UserByte4 = (sensor->Init.InitParam >> 16) >> 8;
uint8_t UserByte12Cmp = 0;
uint8_t UserByte34Cmp = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
/* Проверка присутствует ли выбранный датчик на линии */
result = DS18B20_ReadScratchpad(hdallas->onewire, (uint8_t *)&hdallas->ds_devices->DevAddr[i], (uint8_t *)&hdallas->scratchpad);
if (result != HAL_OK)
return result;
/* Сравнение UserByte1 и UserByte2, если они не равны нулю */
if((sensor->Init.InitParam & 0xFFFF) != NULL)
{
if( (hdallas->scratchpad.tHighRegister == UserByte1) &&
(hdallas->scratchpad.tLowRegister == UserByte2))
{
UserByte12Cmp = 1;
}
}/* Если сравнение UserByte1 и UserByte2 не выбрано, то считаем что они совпадают */
else
{
UserByte12Cmp = 1;
}
/* Сравнение UserByte3 и UserByte4, если они не равны нулю */
if((sensor->Init.InitParam & 0xFFFF0000) != NULL)
{
if( (hdallas->scratchpad.UserByte3 == UserByte3) &&
(hdallas->scratchpad.UserByte4 == UserByte4))
{
UserByte34Cmp = 1;
}
}/* Если сравнение UserByte3 и UserByte4 не выбрано, то считаем что они одинаковые */
else
{
UserByte34Cmp = 1;
}
/* Если нашли нужный датчик - завершаем поиск */
if(UserByte12Cmp && UserByte34Cmp)
{
// sensor->isInitialized = 1;
// sensor->Init.init_func = (HAL_StatusTypeDef (*)())Dallas_SensorInitByUserBytes;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[i]);
return result;
}
}
sensor->sensROM = 0;
/* Возвращаем ошибку если не нашли */
return HAL_ERROR;
}
/**
* @brief Инициализирует структуру датчика по порядковому номеру
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
* @details Порядковый номер датчика в списке найденных.
* Т.е. каким по счету этот датчик был найден
*/
HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[sensor->Init.InitParam]);
return result;
}
/**
* @brief Инициализирует датчик для работы
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @param ROM ROM датчика, который надо инициализировать
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE])
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
if(hdallas == 0)
return HAL_ERROR;
sensor->hdallas = hdallas;
sensor->sensROM = 0;
sensor->sensROM = *(uint64_t *)(ROM);
// for(int i = 0; i < DALLAS_ROM_SIZE; i++)
// sensor->sensROM |= ((uint64_t)(*ROM)[i] << (56 - 8*i));
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_ReadScratchpad(sensor);
if (result == HAL_OK)
{
/* Установка разрешения */
result = DS18B20_SetResolution(hdallas->onewire, (uint8_t *)ROM, sensor->Init.Resolution);
if (result == HAL_OK)
{
sensor->isInitialized = 1;
return HAL_OK;
}
else
{
sensor->isInitialized = 0;
return result;
}
}
else
{
sensor->isInitialized = 0;
return result;
}
}
/**
* @brief Деинициализирует структуру датчика
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor)
{
if(sensor == NULL)
return HAL_ERROR;
memset(&sensor->f, 0, sizeof(sensor->f));
sensor->isConnected = 0;
sensor->isInitialized = 0;
sensor->isLost = 0;
sensor->temperature = 0;
sensor->sensROM = 0;
return HAL_OK;
}
/**
* @brief Функция для нахождения нового датчика на место потерянного
* @param sensor Указатель на структуру датчика
@@ -578,3 +417,223 @@ HAL_StatusTypeDef Dallas_ReadScratchpad(DALLAS_SensorHandleTypeDef *sensor)
return HAL_ERROR;
return DS18B20_ReadScratchpad(sensor->hdallas->onewire, (uint8_t *)&sensor->sensROM, (uint8_t *)&sensor->hdallas->scratchpad);
}
/**
* @brief Инициализирует структуру датчика по ROM
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByROM(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t ROM[8] = {0};
ROM[0] = (sensor->Init.InitParam.ROM >> (7*8)) & 0xFF;
ROM[1] = (sensor->Init.InitParam.ROM >> (6*8)) & 0xFF;
ROM[2] = (sensor->Init.InitParam.ROM >> (5*8)) & 0xFF;
ROM[3] = (sensor->Init.InitParam.ROM >> (4*8)) & 0xFF;
ROM[4] = (sensor->Init.InitParam.ROM >> (3*8)) & 0xFF;
ROM[5] = (sensor->Init.InitParam.ROM >> (2*8)) & 0xFF;
ROM[6] = (sensor->Init.InitParam.ROM >> (1*8)) & 0xFF;
ROM[7] = (sensor->Init.InitParam.ROM >> (0*8)) & 0xFF;
if(DS18B20_IsValidAddress(ROM) != HAL_OK)
return HAL_ERROR;
uint8_t comparebytes = DALLAS_ROM_SIZE;
int ROM_ind = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
comparebytes = DALLAS_ROM_SIZE;
for(int rom_byte = 0; rom_byte < DALLAS_ROM_SIZE; rom_byte++)
{
if(hdallas->ds_devices->DevAddr[i][rom_byte] == ROM[rom_byte])
comparebytes--;
}
if(comparebytes == 0)
{
ROM_ind = i;
break;
}
}
/* Проверка присутствует ли выбранный датчик на линии */
if(comparebytes == 0)
{
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[ROM_ind]);
return result;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief Инициализирует структуру датчика по пользовательским байтам
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInitByUserBytes(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
uint8_t UserByte1 = sensor->Init.InitParam.UserBytes.UserByte1;
uint8_t UserByte2 = sensor->Init.InitParam.UserBytes.UserByte2;
uint8_t UserByte3 = sensor->Init.InitParam.UserBytes.UserByte3;
uint8_t UserByte4 = sensor->Init.InitParam.UserBytes.UserByte4;
uint8_t UserByte12Cmp = 0;
uint8_t UserByte34Cmp = 0;
for(int i = 0; i < hdallas->onewire->RomCnt; i++)
{
/* Проверка присутствует ли выбранный датчик на линии */
result = DS18B20_ReadScratchpad(hdallas->onewire, (uint8_t *)&hdallas->ds_devices->DevAddr[i], (uint8_t *)&hdallas->scratchpad);
if (result != HAL_OK)
return result;
/* Сравнение UserByte1 и UserByte2, если они не равны нулю */
if(UserByte1 | UserByte2)
{
if( (hdallas->scratchpad.tHighRegister == UserByte1) &&
(hdallas->scratchpad.tLowRegister == UserByte2))
{
UserByte12Cmp = 1;
}
}/* Если сравнение UserByte1 и UserByte2 не выбрано, то считаем что они совпадают */
else
{
UserByte12Cmp = 1;
}
/* Сравнение UserByte3 и UserByte4, если они не равны нулю */
if(UserByte3 | UserByte4)
{
if( (hdallas->scratchpad.UserByte3 == UserByte3) &&
(hdallas->scratchpad.UserByte4 == UserByte4))
{
UserByte34Cmp = 1;
}
}/* Если сравнение UserByte3 и UserByte4 не выбрано, то считаем что они одинаковые */
else
{
UserByte34Cmp = 1;
}
/* Если нашли нужный датчик - завершаем поиск */
if(UserByte12Cmp && UserByte34Cmp)
{
// sensor->isInitialized = 1;
// sensor->Init.init_func = (HAL_StatusTypeDef (*)())Dallas_SensorInitByUserBytes;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[i]);
return result;
}
}
sensor->sensROM = 0;
/* Возвращаем ошибку если не нашли */
return HAL_ERROR;
}
/**
* @brief Инициализирует структуру датчика по порядковому номеру
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @retval HAL Status
* @details Порядковый номер датчика в списке найденных.
* Т.е. каким по счету этот датчик был найден
*/
HAL_StatusTypeDef Dallas_SensorInitByInd(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor)
{
HAL_StatusTypeDef result;
if(hdallas == NULL)
return HAL_ERROR;
if(sensor == NULL)
return HAL_ERROR;
result = Dallas_SensorInit(hdallas, sensor, &hdallas->ds_devices->DevAddr[sensor->Init.InitParam.Ind]);
return result;
}
/**
* @brief Инициализирует датчик для работы
* @param hdallas Указатель на хендл для общения с датчиками
* @param sensor Указатель на структуру датчика
* @param ROM ROM датчика, который надо инициализировать
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorInit(DALLAS_HandleTypeDef *hdallas, DALLAS_SensorHandleTypeDef *sensor, uint8_t (*ROM)[DALLAS_ROM_SIZE])
{
HAL_StatusTypeDef result;
if(sensor == NULL)
return HAL_ERROR;
if(hdallas == 0)
return HAL_ERROR;
sensor->hdallas = hdallas;
sensor->sensROM = 0;
sensor->sensROM = *(uint64_t *)(ROM);
// for(int i = 0; i < DALLAS_ROM_SIZE; i++)
// sensor->sensROM |= ((uint64_t)(*ROM)[i] << (56 - 8*i));
/* Проверка присутствует ли выбранный датчик на линии */
result = Dallas_ReadScratchpad(sensor);
if (result == HAL_OK)
{
/* Установка разрешения */
result = DS18B20_SetResolution(hdallas->onewire, (uint8_t *)ROM, sensor->Init.Resolution);
if (result == HAL_OK)
{
sensor->isInitialized = 1;
return HAL_OK;
}
else
{
sensor->isInitialized = 0;
return result;
}
}
else
{
sensor->isInitialized = 0;
return result;
}
}
/**
* @brief Деинициализирует структуру датчика
* @param sensor Указатель на структуру датчика
* @retval HAL Status
*/
HAL_StatusTypeDef Dallas_SensorDeInit(DALLAS_SensorHandleTypeDef *sensor)
{
if(sensor == NULL)
return HAL_ERROR;
memset(&sensor->f, 0, sizeof(sensor->f));
sensor->isConnected = 0;
sensor->isInitialized = 0;
sensor->isLost = 0;
sensor->temperature = 0;
sensor->sensROM = 0;
return HAL_OK;
}

View File

@@ -43,6 +43,9 @@
#define DALLAS_DELAY_MS_12_BITS 750
#define DALLAS_DELAY_MS_MAX DALLAS_DELAY_MS_12_BITS
typedef struct _SensorHandleStruct DALLAS_SensorHandleTypeDef;
typedef struct _DallasHandleStruct DALLAS_HandleTypeDef;
/** @brief Структура Scratchpad датчика DALLAS */
typedef struct
{
@@ -70,24 +73,36 @@ typedef struct
/** @brief Структура инициализации датчика DALLAS */
typedef struct __packed
{
uint64_t InitParam; ///< Параметр для инициализации: ROM/UserBytes/Индекс
union
{
uint64_t Ind; ///< порядковый номер датчика
uint64_t ROM; ///< ROM датчика
struct
{
uint8_t UserByte1; ///< Младший байт (бит 07)
uint8_t UserByte2; ///< Следующий байт (бит 815)
uint8_t UserByte3; ///< Байт (бит 1623)
uint8_t UserByte4; ///< Байт (бит 2431)
uint8_t Reserved[4]; ///< Остальные байты (бит 3263, если нужно)
} UserBytes; ///< UserBytes датчика
}InitParam; ///< Параметр для инициализации: ROM/UserBytes/Индекс
uint8_t Resolution; ///< Разрешение датчика
HAL_StatusTypeDef (*init_func)(); ///< Функция инициализации
HAL_StatusTypeDef (*init_func)(DALLAS_HandleTypeDef *, DALLAS_SensorHandleTypeDef *); ///< Функция инициализации
} DALLAS_InitStructTypeDef;
/** @brief Cтруктура обработчика DALLAS для общения с датчиком*/
typedef struct
struct _DallasHandleStruct
{
OneWire_t *onewire;
DS18B20_Drv_t *ds_devices;
DALLAS_ScratchpadTypeDef scratchpad;
}DALLAS_HandleTypeDef;
};
extern DALLAS_HandleTypeDef hdallas;
/** @brief Основная структура обработчика датчика DALLAS */
typedef struct
struct _SensorHandleStruct
{
unsigned isConnected:1; ///< Флаг соединения
unsigned isInitialized:1; ///< Флаг инициализации
@@ -100,7 +115,7 @@ typedef struct
DALLAS_InitStructTypeDef Init; ///< Структура инициализации
DALLAS_FlagsTypeDef f; ///< Флаги
} DALLAS_SensorHandleTypeDef;
};

View File

@@ -24,13 +24,13 @@ void OneWire_WriteBit(OneWire_t* OW, uint8_t bit)
OneWire_Pin_Mode(OW, Output);
/* Forming pulse */
OneWire_Delay_uw(ONEWIRE_WRITE_1_US);
OneWire_Delay_us(ONEWIRE_WRITE_1_US);
/* Release line (pull up line) */
OneWire_Pin_Mode(OW, Input);
/* Wait for 55 us and release the line */
OneWire_Delay_uw(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US);
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_1_US);
OneWire_Pin_Mode(OW, Input);
}else{
/* Set line low */
@@ -38,13 +38,13 @@ void OneWire_WriteBit(OneWire_t* OW, uint8_t bit)
OneWire_Pin_Mode(OW, Output);
/* Forming pulse */
OneWire_Delay_uw(ONEWIRE_WRITE_0_US);
OneWire_Delay_us(ONEWIRE_WRITE_0_US);
/* Release line (pull up line) */
OneWire_Pin_Mode(OW, Input);
/* Wait for 5 us and release the line */
OneWire_Delay_uw(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US);
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_WRITE_0_US);
OneWire_Pin_Mode(OW, Input);
}
__enable_irq();
@@ -69,17 +69,17 @@ uint8_t OneWire_ReadBit(OneWire_t* OW)
/* Line low */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
OneWire_Delay_uw(ONEWIRE_READ_CMD_US);
OneWire_Delay_us(ONEWIRE_READ_CMD_US);
/* Release line */
OneWire_Pin_Mode(OW, Input);
OneWire_Delay_uw(ONEWIRE_READ_DELAY_US);
OneWire_Delay_us(ONEWIRE_READ_DELAY_US);
/* Read line value */
bit = OneWire_Pin_Read(OW);
/* Wait 50us to complete 60us period */
OneWire_Delay_uw(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US);
OneWire_Delay_us(ONEWIRE_COMMAND_SLOT_US - ONEWIRE_READ_CMD_US - ONEWIRE_READ_DELAY_US);
__enable_irq();
#else
bit = OneWireUART_ProcessBit(onewire_uart, 1);
@@ -149,17 +149,17 @@ uint8_t OneWire_Reset(OneWire_t* OW)
/* Line low, and wait 480us */
OneWire_Pin_Level(OW, 0);
OneWire_Pin_Mode(OW, Output);
OneWire_Delay_uw(ONEWIRE_RESET_PULSE_US);
OneWire_Delay_us(ONEWIRE_RESET_PULSE_US);
/* Release line and wait for 70us */
OneWire_Pin_Mode(OW, Input);
OneWire_Delay_uw(ONEWIRE_PRESENCE_WAIT_US);
OneWire_Delay_us(ONEWIRE_PRESENCE_WAIT_US);
/* Check bit value */
uint8_t rslt = OneWire_Pin_Read(OW);
/* Delay for 410 us */
OneWire_Delay_uw(ONEWIRE_PRESENCE_DURATION_US);
OneWire_Delay_us(ONEWIRE_PRESENCE_DURATION_US);
#else
uint8_t rslt = 0;
@@ -316,11 +316,11 @@ void OneWire_Init(OneWire_t* OW)
{
OneWire_Pin_Mode(OW, Output);
OneWire_Pin_Level(OW, 1);
OneWire_Delay_uw(1000);
OneWire_Delay_us(1000);
OneWire_Pin_Level(OW, 0);
OneWire_Delay_uw(1000);
OneWire_Delay_us(1000);
OneWire_Pin_Level(OW, 1);
OneWire_Delay_uw(2000);
OneWire_Delay_us(2000);
/* Reset the search state */
OW->LastDiscrepancy = 0;

View File

@@ -7,7 +7,7 @@
#include "ow_port.h"
#include "onewire.h"
#include "tim.h"
uint32_t pin_pos = (DS_Pin_Numb < 8) ? (DS_Pin_Numb * 4) : ((DS_Pin_Numb - 8) * 4);
uint32_t pin_pos = (OW_Pin_Numb < 8) ? (OW_Pin_Numb * 4) : ((OW_Pin_Numb - 8) * 4);
/**
* @brief The internal function is used as gpio pin mode
@@ -17,20 +17,20 @@ uint32_t pin_pos = (DS_Pin_Numb < 8) ? (DS_Pin_Numb * 4) : ((DS_Pin_Numb - 8) *
void OneWire_Pin_Mode(OneWire_t* OW, PinMode Mode)
{
#ifdef CMSIS_Driver
volatile uint32_t *config_reg = (DS_Pin_Numb < 8) ? &(OW->DataPort->CRL) : &(OW->DataPort->CRH);
// Ñáðîñ òåêóùèõ 4 áèò (CNF + MODE)
volatile uint32_t *config_reg = (OW_Pin_Numb < 8) ? &(OW->DataPort->CRL) : &(OW->DataPort->CRH);
// —брос текущих 4 бит (CNF + MODE)
*config_reg &= ~(0xF << pin_pos);
if (Mode == Input)
{
// Âõîä ñ ïîäòÿæêîé èëè áåç íàïðèìåð, CNF = 0b01, MODE = 0b00
// Çäåñü óñòàíàâëèâàåì âõîä ñ ïîäòÿæêîé:
*config_reg |= (0x8 << pin_pos); // CNF=10, MODE=00 (âõîä ñ ïîäòÿæêîé)
OW->DataPort->ODR |= (1 << DS_Pin_Numb); // Âêëþ÷èòü ïîäòÿæêó ââåðõ
// ¬ход с подт¤жкой или без Ц например, CNF = 0b01, MODE = 0b00
// «десь устанавливаем вход с подт¤жкой:
*config_reg |= (0x8 << pin_pos); // CNF=10, MODE=00 (вход с подт¤жкой)
OW->DataPort->ODR |= (1 << OW_Pin_Numb); // ¬ключить подт¤жку вверх
}
else
{
// Âûõîä push-pull, 2 ÌÃö MODE = 0b10, CNF = 0b00
// ¬ыход push-pull, 2 ћ√ц Ц MODE = 0b10, CNF = 0b00
*config_reg |= (0x2 << pin_pos);
}
#else
@@ -105,7 +105,7 @@ uint8_t OneWire_Pin_Read(OneWire_t* OW)
}
uint32_t tim_1us_period = OW_TIM_1US_PERIOD;
void OneWire_Delay_uw(uint32_t us)
void OneWire_Delay_us(uint32_t us)
{
uint32_t ticks = us * tim_1us_period;
uint16_t start = OW_TIM->CNT;
@@ -115,7 +115,7 @@ void OneWire_Delay_uw(uint32_t us)
while (elapsed < ticks)
{
uint16_t curr = OW_TIM->CNT;
uint16_t delta = (uint16_t)(curr - prev); // ó÷¸ò ïåðåïîëíåíèÿ
uint16_t delta = (uint16_t)(curr - prev); // учЄт переполнени¤
elapsed += delta;
prev = curr;
}

View File

@@ -13,17 +13,48 @@
#include "stm32f1xx_hal.h"
/* I/O Port ------------------------------------------------------------------*/
//#define LL_Driver
#define CMSIS_Driver
//#define LL_Driver ///< использовать CMSIS для управления ножкой
#define CMSIS_Driver ///< использовать CMSIS для управления ножкой
// если ничего не выбрано - используется HAL
#define DS_GPIO_Port GPIOB
#define DS_Pin_Numb 0
#define DS_Pin (1<<DS_Pin_Numb)
/**
* @def OW_GPIO_Port
* @brief Порт вывода для шины 1-Wire.
* @details Указывает порт GPIO, к которому подключена линия данных 1-Wire (например, для DS18B20).
*/
#define OW_GPIO_Port GPIOB
/**
* @def OW_Pin_Numb
* @brief Номер пина в порту OW_GPIO_Port.
* @details Используется для формирования маски пина и настройки ввода/вывода.
*/
#define OW_Pin_Numb 0
/**
* @def OW_Pin
* @brief Маска пина, соответствующая номеру OW_Pin_Numb.
* @details Используется при доступе к регистрам порта для управления состоянием линии 1-Wire.
*/
#define OW_Pin (1<<OW_Pin_Numb)
/**
* @def OW_TIM
* @brief Аппаратный таймер для формирования временных интервалов протокола 1-Wire.
* @details Применяется для создания точных задержек при обмене данными по шине 1-Wire.
*/
#define OW_TIM TIM3
/**
* @def OW_TIM_1US_PERIOD
* @brief Количество тактов таймера OW_TIM, соответствующее 1 микросекунде.
* @details Вычисляется на основе частоты таймера. Например, для таймера с частотой 24 МГц значение будет равно 24.
*/
#define OW_TIM_1US_PERIOD 24
/* OneWire Timings -----------------------------------------------------------*/
void OneWire_Delay_uw(uint32_t us);
void OneWire_Delay_us(uint32_t us);
/* Common Register -----------------------------------------------------------*/
#endif /* ONEWIRE_PORT_H */