diff --git a/ds18b20.c b/ds18b20.c index b3f828c..5de167c 100644 --- a/ds18b20.c +++ b/ds18b20.c @@ -102,68 +102,77 @@ bool Ds18b20_ManualConvert(void) #if (_DS18B20_USE_FREERTOS==1) void Task_Ds18b20(void const * argument) { - uint8_t Ds18b20TryToFind=5; - do + uint8_t Ds18b20TryToFind=5; + do + { + OneWire_Init(&OneWire,_DS18B20_GPIO ,_DS18B20_PIN); + TempSensorCount = 0; + while(HAL_GetTick() < 3000) + Ds18b20Delay(100); + OneWireDevices = OneWire_First(&OneWire); + while (OneWireDevices) { - OneWire_Init(&OneWire,_DS18B20_GPIO ,_DS18B20_PIN); - TempSensorCount = 0; - while(HAL_GetTick() < 3000) - Ds18b20Delay(100); - OneWireDevices = OneWire_First(&OneWire); - while (OneWireDevices) - { - Ds18b20Delay(100); - TempSensorCount++; - OneWire_GetFullROM(&OneWire, ds18b20[TempSensorCount-1].Address); - OneWireDevices = OneWire_Next(&OneWire); - } - if(TempSensorCount>0) - break; - Ds18b20TryToFind--; - }while(Ds18b20TryToFind>0); - if(Ds18b20TryToFind==0) - vTaskDelete(Ds18b20Handle); - for (uint8_t i = 0; i < TempSensorCount; i++) + Ds18b20Delay(100); + TempSensorCount++; + OneWire_GetFullROM(&OneWire, ds18b20[TempSensorCount-1].Address); + OneWireDevices = OneWire_Next(&OneWire); + } + if(TempSensorCount>0) + break; + Ds18b20TryToFind--; + } while(Ds18b20TryToFind>0); + if(Ds18b20TryToFind==0) + vTaskDelete(Ds18b20Handle); + for (uint8_t i = 0; i < TempSensorCount; i++) + { + Ds18b20Delay(50); + DS18B20_SetResolution(&OneWire, ds18b20[i].Address, DS18B20_Resolution_12bits); + Ds18b20Delay(50); + DS18B20_DisableAlarmTemperature(&OneWire, ds18b20[i].Address); + } + for(;;) + { + while(_DS18B20_UPDATE_INTERVAL_MS==0) { - Ds18b20Delay(50); - DS18B20_SetResolution(&OneWire, ds18b20[i].Address, DS18B20_Resolution_12bits); - Ds18b20Delay(50); - DS18B20_DisableAlarmTemperature(&OneWire, ds18b20[i].Address); - } - for(;;) + if(Ds18b20StartConvert==1) + break; + Ds18b20Delay(10); + } + DS18B20_StartAll(&OneWire); + Ds18b20Timeout=_DS18B20_CONVERT_TIMEOUT_MS/10; +#if _DS18B20_USE_PULLPWR + ONEWIRE_HIGH(&OneWire); /// set high level + ONEWIRE_OUTPUT_PP(&OneWire); /// and set push-pull for powering the conversion + osDelay(750); +#else + osDelay(100); + while (!DS18B20_AllDone(&OneWire)) { - while(_DS18B20_UPDATE_INTERVAL_MS==0) - { - if(Ds18b20StartConvert==1) - break; - Ds18b20Delay(10); - } - Ds18b20Timeout=_DS18B20_CONVERT_TIMEOUT_MS/10; - DS18B20_StartAll(&OneWire); - osDelay(100); - while (!DS18B20_AllDone(&OneWire)) - { - osDelay(10); - Ds18b20Timeout-=1; - if(Ds18b20Timeout==0) - break; - } - if(Ds18b20Timeout>0) - { - for (uint8_t i = 0; i < TempSensorCount; i++) - { - Ds18b20Delay(1000); - ds18b20[i].DataIsValid = DS18B20_Read(&OneWire, ds18b20[i].Address, &ds18b20[i].Temperature); - } - } - else + osDelay(10); + Ds18b20Timeout-=1; + if(Ds18b20Timeout==0) + break; + } +#endif + if(Ds18b20Timeout>0) + { +#if _DS18B20_USE_PULLPWR + ONEWIRE_OUTPUT(&OneWire); //// return pull-up for reading data instead of push-pull for powering conversion +#endif + for (uint8_t i = 0; i < TempSensorCount; i++) { - for (uint8_t i = 0; i < TempSensorCount; i++) - ds18b20[i].DataIsValid = false; + //Ds18b20Delay(1000); + ds18b20[i].DataIsValid = DS18B20_Read(&OneWire, ds18b20[i].Address, &ds18b20[i].Temperature); } - Ds18b20StartConvert=0; - osDelay(_DS18B20_UPDATE_INTERVAL_MS); } + else + { + for (uint8_t i = 0; i < TempSensorCount; i++) + ds18b20[i].DataIsValid = false; + } + Ds18b20StartConvert=0; + osDelay(_DS18B20_UPDATE_INTERVAL_MS); + } } #endif //########################################################################################### @@ -184,17 +193,19 @@ uint8_t DS18B20_Start(OneWire_t* OneWire, uint8_t *ROM) return 1; } -void DS18B20_StartAll(OneWire_t* OneWire) +bool DS18B20_StartAll(OneWire_t* OneWire) { + bool ret_val = 0; /* Reset pulse */ - OneWire_Reset(OneWire); + ret_val = !OneWire_Reset(OneWire); /* Skip rom */ OneWire_WriteByte(OneWire, ONEWIRE_CMD_SKIPROM); /* Start conversion on all connected devices */ OneWire_WriteByte(OneWire, DS18B20_CMD_CONVERTTEMP); + return ret_val; } -bool DS18B20_Read(OneWire_t* OneWire, uint8_t *ROM, float *destination) +bool DS18B20_Read(OneWire_t* OneWire, uint8_t *ROM, float *destination) { uint16_t temperature; uint8_t resolution; @@ -204,11 +215,13 @@ bool DS18B20_Read(OneWire_t* OneWire, uint8_t *ROM, float *destination) uint8_t data[9]; uint8_t crc; - /* Check if device is DS18B20 */ - if (!DS18B20_Is(ROM)) { - return false; + if (ROM) /// if reading with pointer used then check if it is the address of a DS18B20 + { + /* Check if device is DS18B20 */ + if (!DS18B20_Is(ROM)) { + return false; + } } - /* Check if line is released, if it is, then conversion is complete */ if (!OneWire_ReadBit(OneWire)) { @@ -218,8 +231,13 @@ bool DS18B20_Read(OneWire_t* OneWire, uint8_t *ROM, float *destination) /* Reset line */ OneWire_Reset(OneWire); - /* Select ROM number */ - OneWire_SelectWithPointer(OneWire, ROM); + if (ROM) { /// if reading with pointer used then select device + /* Select ROM number */ + OneWire_SelectWithPointer(OneWire, ROM); + } + if (!ROM) { /// if reading without selecting device used then send Skip ROM command + OneWire_WriteByte(OneWire, ONEWIRE_CMD_SKIPROM); + } /* Read scratchpad command by onewire protocol */ OneWire_WriteByte(OneWire, ONEWIRE_CMD_RSCRATCHPAD); @@ -326,7 +344,7 @@ uint8_t DS18B20_GetResolution(OneWire_t* OneWire, uint8_t *ROM) return ((conf & 0x60) >> 5) + 9; } -uint8_t DS18B20_SetResolution(OneWire_t* OneWire, uint8_t *ROM, DS18B20_Resolution_t resolution) +uint8_t DS18B20_SetResolution(OneWire_t* OneWire, uint8_t *ROM, DS18B20_Resolution_t resolution) { uint8_t th, tl, conf; if (!DS18B20_Is(ROM)) @@ -400,7 +418,7 @@ uint8_t DS18B20_Is(uint8_t *ROM) return 0; } -uint8_t DS18B20_SetAlarmLowTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t temp) +uint8_t DS18B20_SetAlarmLowTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { uint8_t tl, th, conf; if (!DS18B20_Is(ROM)) @@ -451,7 +469,7 @@ uint8_t DS18B20_SetAlarmLowTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t return 1; } -uint8_t DS18B20_SetAlarmHighTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t temp) +uint8_t DS18B20_SetAlarmHighTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t temp) { uint8_t tl, th, conf; if (!DS18B20_Is(ROM)) @@ -502,7 +520,7 @@ uint8_t DS18B20_SetAlarmHighTemperature(OneWire_t* OneWire, uint8_t *ROM, int8_t return 1; } -uint8_t DS18B20_DisableAlarmTemperature(OneWire_t* OneWire, uint8_t *ROM) +uint8_t DS18B20_DisableAlarmTemperature(OneWire_t* OneWire, uint8_t *ROM) { uint8_t tl, th, conf; if (!DS18B20_Is(ROM)) diff --git a/ds18b20.h b/ds18b20.h index 77742e7..0e10fef 100644 --- a/ds18b20.h +++ b/ds18b20.h @@ -4,8 +4,8 @@ // 2018/09/08 -#include "onewire.h" #include "ds18b20Config.h" +#include "onewire.h" #include #if (_DS18B20_USE_FREERTOS==1) @@ -51,6 +51,8 @@ extern Ds18b20Sensor_t ds18b20[_DS18B20_MAX_SENSORS]; #define DS18B20_DATA_LEN 2 #endif +//extern OneWire_t; + //################################################################################### typedef enum { DS18B20_Resolution_9bits = 9, /*!< DS18B20 9 bits resolution */ @@ -66,10 +68,20 @@ void Ds18b20_Init(osPriority Priority); bool Ds18b20_Init(void); #endif bool Ds18b20_ManualConvert(void); +//struct OneWire_t; //################################################################################### uint8_t DS18B20_Start(OneWire_t* OneWireStruct, uint8_t* ROM); -void DS18B20_StartAll(OneWire_t* OneWireStruct); -bool DS18B20_Read(OneWire_t* OneWireStruct, uint8_t* ROM, float* destination); +/** + * \brief send start temperature conversion command to all devices on the bus + * \return false if no devices on the bus, otherwise true + */ +bool DS18B20_StartAll(OneWire_t* OneWireStruct); +/** + * \brief read temperature from device with address ROM or the single device + * \param [in] ROM address of the selected device or 0 if the only one device on the bus + * \return true if reading OK + */ +bool DS18B20_Read(OneWire_t* OneWireStruct, uint8_t* ROM, float* destination); uint8_t DS18B20_GetResolution(OneWire_t* OneWireStruct, uint8_t* ROM); uint8_t DS18B20_SetResolution(OneWire_t* OneWireStruct, uint8_t* ROM, DS18B20_Resolution_t resolution); uint8_t DS18B20_Is(uint8_t* ROM); diff --git a/ds18b20Config.h b/ds18b20Config.h index 2bdd85b..f771715 100644 --- a/ds18b20Config.h +++ b/ds18b20Config.h @@ -9,13 +9,20 @@ #define _DS18B20_GPIO DS18B20_GPIO_Port #define _DS18B20_PIN DS18B20_Pin -#define _DS18B20_CONVERT_TIMEOUT_MS 5000 +#define _DS18B20_CONVERT_TIMEOUT_MS 5000 #if (_DS18B20_USE_FREERTOS==1) -#define _DS18B20_UPDATE_INTERVAL_MS 10000 // ((( if==0 >> Ds18b20_ManualConvert() ))) ((( if>0 >>>> Auto refresh ))) +#define _DS18B20_UPDATE_INTERVAL_MS 10000 // ((( if==0 >> Ds18b20_ManualConvert() ))) ((( if>0 >>>> Auto refresh ))) #endif +#define _DS18B20_TIMER htim13 +#define _DS18B20_NO_NOT_USE_TIMER 1 /// use NOPs instead of hardware timer + +#ifdef DEBUG +#define _DS18B20_CYCS_PER_NS 250 /// for(){NOP} cycles per nanosecond for 72 MHz core clock +#else +#define _DS18B20_CYCS_PER_NS 150 /// for(){NOP} cycles per nanosecond for 72 MHz core clock +#endif -#define _DS18B20_TIMER htim13 //################################################################################### #endif diff --git a/onewire.c b/onewire.c index 75f7d93..1b75aaf 100644 --- a/onewire.c +++ b/onewire.c @@ -16,14 +16,23 @@ * | along with this program. If not, see . * |---------------------------------------------------------------------- */ -#include "onewire.h" #include "ds18b20Config.h" +#include "onewire.h" +#if (_DS18B20_NO_NOT_USE_TIMER) +#else #include "tim.h" +#endif void ONEWIRE_DELAY(uint16_t time_us) { - _DS18B20_TIMER.Instance->CNT = 0; - while(_DS18B20_TIMER.Instance->CNT <= time_us); +#if (_DS18B20_NO_NOT_USE_TIMER==1) /// use NOPs for delay + for (int i1 = 0; i1 < time_us*1000; i1 += _DS18B20_CYCS_PER_NS) {__ASM volatile ("nop");} +#else /// use 1 us timer for delay + __HAL_TIM_SET_COUNTER(&_DS18B20_TIMER,0); // set the counter value a 0 + while (__HAL_TIM_GET_COUNTER(&_DS18B20_TIMER) <= time_us); // wait for the counter to reach the us input in the parameter + //_DS18B20_TIMER.Instance->CNT = 0; + //while(_DS18B20_TIMER.Instance->CNT <= time_us); +#endif } void ONEWIRE_LOW(OneWire_t *gp) { @@ -52,19 +61,33 @@ void ONEWIRE_OUTPUT(OneWire_t *gp) HAL_GPIO_Init(gp->GPIOx,&gpinit); } +void ONEWIRE_OUTPUT_PP(OneWire_t *gp) +{ + GPIO_InitTypeDef gpinit; + gpinit.Mode = GPIO_MODE_OUTPUT_PP; + gpinit.Pull = GPIO_NOPULL; + gpinit.Speed = GPIO_SPEED_FREQ_HIGH; + gpinit.Pin = gp->GPIO_Pin; + HAL_GPIO_Init(gp->GPIOx,&gpinit); + +} + void OneWire_Init(OneWire_t* OneWireStruct, GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { +#if (_DS18B20_NO_NOT_USE_TIMER) +#else HAL_TIM_Base_Start(&_DS18B20_TIMER); +#endif OneWireStruct->GPIOx = GPIOx; OneWireStruct->GPIO_Pin = GPIO_Pin; - ONEWIRE_OUTPUT(OneWireStruct); + /*ONEWIRE_OUTPUT(OneWireStruct); ONEWIRE_HIGH(OneWireStruct); - OneWireDelay(1000); + OneWireDelay(500); ONEWIRE_LOW(OneWireStruct); - OneWireDelay(1000); + OneWireDelay(500); ONEWIRE_HIGH(OneWireStruct); - OneWireDelay(2000); + OneWireDelay(500);*/ } inline uint8_t OneWire_Reset(OneWire_t* OneWireStruct) @@ -77,11 +100,16 @@ inline uint8_t OneWire_Reset(OneWire_t* OneWireStruct) ONEWIRE_DELAY(480); ONEWIRE_DELAY(20); /* Release line and wait for 70us */ - ONEWIRE_INPUT(OneWireStruct); +#if (_DS18B20_USE_FREERTOS == 1) + taskENTER_CRITICAL(); +#endif + ONEWIRE_HIGH(OneWireStruct); ONEWIRE_DELAY(70); /* Check bit value */ i = HAL_GPIO_ReadPin(OneWireStruct->GPIOx, OneWireStruct->GPIO_Pin); - +#if (_DS18B20_USE_FREERTOS == 1) + taskEXIT_CRITICAL(); +#endif /* Delay for 410 us */ ONEWIRE_DELAY(410); /* Return value of presence pulse, 0 = OK, 1 = ERROR */ @@ -93,30 +121,38 @@ inline void OneWire_WriteBit(OneWire_t* OneWireStruct, uint8_t bit) if (bit) { /* Set line low */ +#if (_DS18B20_USE_FREERTOS == 1) + taskENTER_CRITICAL(); +#endif ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); ONEWIRE_DELAY(10); /* Bit high */ - ONEWIRE_INPUT(OneWireStruct); + ONEWIRE_HIGH(OneWireStruct); /* Wait for 55 us and release the line */ ONEWIRE_DELAY(55); - ONEWIRE_INPUT(OneWireStruct); +#if (_DS18B20_USE_FREERTOS == 1) + taskEXIT_CRITICAL(); +#endif } else { /* Set line low */ +#if (_DS18B20_USE_FREERTOS == 1) + taskENTER_CRITICAL(); +#endif ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); ONEWIRE_DELAY(65); /* Bit high */ - ONEWIRE_INPUT(OneWireStruct); + ONEWIRE_HIGH(OneWireStruct); /* Wait for 5 us and release the line */ ONEWIRE_DELAY(5); - ONEWIRE_INPUT(OneWireStruct); +#if (_DS18B20_USE_FREERTOS == 1) + taskEXIT_CRITICAL(); +#endif } } @@ -126,12 +162,14 @@ inline uint8_t OneWire_ReadBit(OneWire_t* OneWireStruct) uint8_t bit = 0; /* Line low */ +#if (_DS18B20_USE_FREERTOS == 1) + taskENTER_CRITICAL(); +#endif ONEWIRE_LOW(OneWireStruct); - ONEWIRE_OUTPUT(OneWireStruct); ONEWIRE_DELAY(2); /* Release line */ - ONEWIRE_INPUT(OneWireStruct); + ONEWIRE_HIGH(OneWireStruct); ONEWIRE_DELAY(10); /* Read line value */ @@ -142,6 +180,9 @@ inline uint8_t OneWire_ReadBit(OneWire_t* OneWireStruct) /* Wait 50us to complete 60us period */ ONEWIRE_DELAY(50); +#if (_DS18B20_USE_FREERTOS == 1) + taskEXIT_CRITICAL(); +#endif /* Return bit value */ return bit; diff --git a/onewire.h b/onewire.h index 8d3b185..cde7009 100644 --- a/onewire.h +++ b/onewire.h @@ -30,9 +30,10 @@ void ONEWIRE_DELAY(uint16_t time_us); /* Pin settings */ void ONEWIRE_LOW(OneWire_t *gp); -void ONEWIRE_HIGH(OneWire_t *gp); +void ONEWIRE_HIGH(OneWire_t *gp); void ONEWIRE_INPUT(OneWire_t *gp); void ONEWIRE_OUTPUT(OneWire_t *gp); +void ONEWIRE_OUTPUT_PP(OneWire_t *gp); ///< set OneWire pin to the output push-pull mode, use this for powering for conversion /* OneWire commands */ #define ONEWIRE_CMD_RSCRATCHPAD 0xBE