ds18b20-MODBUS/john103C6T6/Core/Src/ds18b20_driver.c
2025-06-24 19:06:17 +03:00

608 lines
14 KiB
C

/**
******************************************************************************
* @file ds18b20_driver.c
* @brief This file includes the HAL/LL driver for DS18B20 1-Wire Digital
* Thermometer
******************************************************************************
*/
#include "ds18b20_driver.h"
DS18B20_Drv_t DS;
OneWire_t OW;
/**
* @brief The function is used to check valid DS18B20 ROM
* @retval Return in OK = 1, Failed = 0
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_IsValidAddress(uint8_t *ROM)
{
if(ROM == NULL)
return HAL_ERROR;
uint8_t check_family = (*ROM == DS18B20_FAMILY_CODE);
/* Calculate CRC */
uint8_t crc = OneWire_CRC8(ROM, 7);
uint8_t check_crc = (crc == ROM[7]);
/* Checks if first byte is equal to DS18B20's family code */
if(check_family && check_crc)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief The function is used to check valid DS18B20 ROM
* @retval Return in OK = 1, Failed = 0
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_IsValid(uint8_t *ROM)
{
if(ROM == NULL)
return HAL_ERROR;
if(*ROM == DS18B20_FAMILY_CODE)
return HAL_OK;
else
return HAL_ERROR;
}
/**
* @brief The function is used to get resolution
* @retval Return value in 9 - 12
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
*/
uint8_t DS18B20_GetResolution(OneWire_t* OW, uint8_t *ROM) {
uint8_t conf;
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
/* Check valid ROM */
if (DS18B20_IsValid(ROM) != HAL_OK)
return 0;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 4 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
/* 5th byte of scratchpad is configuration register */
conf = OneWire_ReadByte(OW);
/* Return 9 - 12 value according to number of bits */
return ((conf & 0x60) >> 5) + 9;
}
/**
* @brief The function is used as set resolution
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Resolution Resolution in 9 - 12
*/
HAL_StatusTypeDef DS18B20_SetResolution(OneWire_t* OW, uint8_t *ROM,
DS18B20_Res_t Resolution)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t th, tl, conf;
/* Check valid ROM */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
th = OneWire_ReadByte(OW);
tl = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
/* Set choosed resolution */
conf = Resolution;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, th);
OneWire_WriteByte(OW, tl);
OneWire_WriteByte(OW, conf);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
/**
* @brief The function is used as start selected ROM device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
*/
HAL_StatusTypeDef DS18B20_StartConvT(OneWire_t* OW, uint8_t *ROM)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
/* Check if device is DS18B20 */
if(DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Start temperature conversion */
OneWire_WriteByte(OW, DS18B20_CMD_CONVERT);
return HAL_OK;
}
/**
* @brief The function is used as start all ROM device
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_StartConvTAll(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
/* Reset pulse */
OneWire_Reset(OW);
/* Skip rom */
OneWire_WriteByte(OW, ONEWIRE_CMD_SKIPROM);
/* Start conversion on all connected devices */
OneWire_WriteByte(OW, DS18B20_CMD_CONVERT);
return HAL_OK;
}
/**
* @brief The function is used as read temreature from device and store in selected
* destination
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Destination Pointer to return value
*/
HAL_StatusTypeDef DS18B20_CalcTemperature(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad, float *Destination)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
if(Scratchpad == NULL)
return HAL_ERROR;
if(Destination == NULL)
return HAL_ERROR;
uint16_t temperature;
uint8_t resolution;
int8_t digit, minus = 0;
float decimal;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* First two bytes of scratchpad are temperature values */
temperature = Scratchpad[0] | (Scratchpad[1] << 8);
/* Reset line */
OneWire_Reset(OW);
/* Check if temperature is negative */
if (temperature & 0x8000) {
/* Two's complement, temperature is negative */
temperature = ~temperature + 1;
minus = 1;
}
/* Get sensor resolution */
resolution = Scratchpad[4];
/* Store temperature integer digits and decimal digits */
digit = temperature >> 4;
digit |= ((temperature >> 8) & 0x7) << 4;
/* Store decimal digits */
switch (resolution) {
case DS18B20_RESOLUTION_9BITS: {
decimal = (temperature >> 3) & 0x01;
decimal *= (float)DS18B20_DECIMAL_STEP_9BIT;
} break;
case DS18B20_RESOLUTION_10BITS: {
decimal = (temperature >> 2) & 0x03;
decimal *= (float)DS18B20_DECIMAL_STEP_10BIT;
} break;
case DS18B20_RESOLUTION_11BITS: {
decimal = (temperature >> 1) & 0x07;
decimal *= (float)DS18B20_DECIMAL_STEP_11BIT;
} break;
case DS18B20_RESOLUTION_12BITS: {
decimal = temperature & 0x0F;
decimal *= (float)DS18B20_DECIMAL_STEP_12BIT;
} break;
default: {
*Destination = 0;
return HAL_ERROR;
}
}
/* Check for negative part */
decimal = digit + decimal;
if (minus) {
decimal = 0 - decimal;
}
/* Set to pointer */
*Destination = decimal;
/* Return HAL_OK, temperature valid */
return HAL_OK;
}
/**
* @brief The function is used as read scratchpad from device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Destination Pointer to Scratchpad array
*/
HAL_StatusTypeDef DS18B20_ReadScratchpad(OneWire_t* OW, uint8_t *ROM, uint8_t *Scratchpad)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
if(Scratchpad == NULL)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Get data */
for (int i = 0; i < 9; i++) {
/* Read byte by byte */
Scratchpad[i] = OneWire_ReadByte(OW);
}
/* Calculate CRC */
uint8_t crc = OneWire_CRC8(Scratchpad, 8);
/* Check if CRC is ok */
if (crc != Scratchpad[8]) {
/* CRC invalid */
return HAL_ERROR;
}
return HAL_OK;
}
/**
* @brief The function is used to wait for end of convertion
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_WaitForEndConvertion(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
uint32_t tickstart = HAL_GetTick();
/* Wait until line is released, then coversion is completed */
while(OneWire_ReadBit(OW) == 0)
{
if(HAL_GetTick() - tickstart > DS18B20_DELAY_MS_MAX)
return HAL_TIMEOUT; // end of convertion has not come
}
return HAL_OK; // convertion done
}
/**
* @brief The function is used to wait for end of convertion without blocking
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_WaitForEndConvertion_NonBlocking(OneWire_t* OW)
{
if(OW == NULL)
return HAL_ERROR;
/* If line is pull down - conversion is ongoing */
if(OneWire_ReadBit(OW) == 0)
return HAL_BUSY;
else
return HAL_OK; // convertion done
}
/**
* @brief The function is used as set temperature alarm range on
* selected device
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param Low Low temperature alarm, value > -55, 0 = reset
* @param High High temperature alarm,, value < 125, 0 = reset
*/
HAL_StatusTypeDef DS18B20_SetTempAlarm(OneWire_t* OW, uint8_t *ROM, int8_t Low,
int8_t High)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t tl, th, conf;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
Low = ((Low < -55) || (Low == 0)) ? -55 : Low;
High = ((High > 125) || (High == 0)) ? 125 : High;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
th = OneWire_ReadByte(OW);
tl = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
th = (uint8_t)High;
tl = (uint8_t)Low;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, th);
OneWire_WriteByte(OW, tl);
OneWire_WriteByte(OW, conf);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
/**
* @brief The function is used as set user bytes with mask
* @retval status in OK = 1, Failed = 0
* @param OW OneWire HandleTypedef
* @param ROM Pointer to ROM number
* @param UserBytes12 First 2 User Bytes (tHigh and tLow)
* @param UserBytes34 Second 2 User Bytes
* @param UserBytesMask Which User Bytes write, and which ignore
*/
HAL_StatusTypeDef DS18B20_WriteUserBytes(OneWire_t* OW, uint8_t *ROM, int16_t UserBytes12,
int16_t UserBytes34, uint8_t UserBytesMask)
{
if(OW == NULL)
return HAL_ERROR;
if(ROM == NULL)
return HAL_ERROR;
uint8_t ub1, ub2, conf, ub3, ub4;
uint8_t UserByte1 = UserBytes12 & 0xFF;
uint8_t UserByte2 = UserBytes12 >> 8;
uint8_t UserByte3 = UserBytes34 & 0xFF;
uint8_t UserByte4 = UserBytes34 >> 8;
/* Check if device is DS18B20 */
if (DS18B20_IsValid(ROM) != HAL_OK)
return HAL_ERROR;
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Read scratchpad command by onewire protocol */
OneWire_WriteByte(OW, DS18B20_CMD_READSCRATCHPAD);
/* Ignore first 2 bytes */
OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
ub1 = OneWire_ReadByte(OW);
ub2 = OneWire_ReadByte(OW);
conf = OneWire_ReadByte(OW);
OneWire_ReadByte(OW);
ub3 = OneWire_ReadByte(OW);
ub4 = OneWire_ReadByte(OW);
/* If user bytes in mask */
if(UserBytesMask & (1<<0))
{
ub1 = UserByte1;
}
if(UserBytesMask & (1<<1))
{
ub2 = UserByte2;
}
if(UserBytesMask & (1<<2))
{
ub3 = UserByte3;
}
if(UserBytesMask & (1<<3))
{
ub4 = UserByte4;
}
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Write scratchpad command by onewire protocol, only th, tl and conf
* register can be written */
OneWire_WriteByte(OW, DS18B20_CMD_WRITESCRATCHPAD);
/* Write bytes */
OneWire_WriteByte(OW, ub1);
OneWire_WriteByte(OW, ub2);
OneWire_WriteByte(OW, conf);
OneWire_WriteByte(OW, ub3);
OneWire_WriteByte(OW, ub4);
/* Reset line */
OneWire_Reset(OW);
/* Select ROM number */
OneWire_MatchROM(OW, ROM);
/* Copy scratchpad to EEPROM of DS18B20 */
OneWire_WriteByte(OW, DS18B20_CMD_COPYSCRATCHPAD);
return HAL_OK;
}
///**
// * @brief The function is used as search device that had temperature alarm
// * triggered and store it in DS18B20 alarm data structure
// * @retval status of search, OK = 1, Failed = 0
// * @param DS DS18B20 HandleTypedef
// * @param OW OneWire HandleTypedef
// */
//uint8_t DS18B20_AlarmSearch(DS18B20_Drv_t *DS, OneWire_t* OW)
//{
// uint8_t t = 0;
// /* Reset Alarm in DS */
// for(uint8_t i = 0; i < OW->RomCnt; i++)
// {
// for(uint8_t j = 0; j < 8; j++)
// {
// DS->AlmAddr[i][j] = 0;
// }
// }
// /* Start alarm search */
// while (OneWire_Search(OW, DS18B20_CMD_ALARM_SEARCH))
// {
// /* Store ROM of device which has alarm flag set */
// OneWire_GetDevRom(OW, DS->AlmAddr[t]);
// t++;
// }
// return (t > 0) ? 1 : 0;
//}
/**
* @brief The function is used to initialize the DS18B20 sensor, and search
* for all ROM along the line. Store in DS18B20 data structure
* @retval Rom detect status, OK = 1, No Rom detected = 0
* @param DS DS18B20 HandleTypedef
* @param OW OneWire HandleTypedef
*/
HAL_StatusTypeDef DS18B20_Search(DS18B20_Drv_t *DS, OneWire_t *OW)
{
if(OW == NULL)
return HAL_ERROR;
OW->RomCnt = 0;
/* Search all OneWire devices ROM */
while(1)
{
/* Start searching for OneWire devices along the line */
if(OneWire_Search(OW, ONEWIRE_CMD_SEARCHROM) != 1) break;
/* Get device ROM */
OneWire_GetDevRom(OW, DS->DevAddr[OW->RomCnt]);
OW->RomCnt++;
}
for(int i = OW->RomCnt; i < DS18B20_DEVICE_AMOUNT; i++)
{
for(int j = 0; j < 8; j++)
DS->DevAddr[i][j] = 0;
}
if(OW->RomCnt > 0)
return HAL_OK;
else
return HAL_BUSY;
}