608 lines
14 KiB
C
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;
|
|
}
|