чуть структурирована, добавлено описение по подключению в шапке
добавлен пример для stm32
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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; ///< Младший байт (бит 0–7)
|
||||
uint8_t UserByte2; ///< Следующий байт (бит 8–15)
|
||||
uint8_t UserByte3; ///< Байт (бит 16–23)
|
||||
uint8_t UserByte4; ///< Байт (бит 24–31)
|
||||
uint8_t Reserved[4]; ///< Остальные байты (бит 32–63, если нужно)
|
||||
} 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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user