From 4a0ef9515cb9c53289848c986017c0d67f65e1bc Mon Sep 17 00:00:00 2001 From: Rihards Skuja Date: Fri, 24 Nov 2017 13:40:29 +0200 Subject: [PATCH] Read temperature from DS18B20+ --- include/ds18b20.h | 53 +++++++++++++++++ main.c | 14 +++++ src/ds18b20.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 include/ds18b20.h create mode 100644 src/ds18b20.c diff --git a/include/ds18b20.h b/include/ds18b20.h new file mode 100644 index 0000000..7df1ca4 --- /dev/null +++ b/include/ds18b20.h @@ -0,0 +1,53 @@ +/* +ds18b20 lib 0x02 + +copyright (c) Davide Gironi, 2012 + +Released under GPLv3. +Please refer to LICENSE file for licensing information. + +References: + + Using DS18B20 digital temperature sensor on AVR microcontrollers + by Gerard Marull Paretas, 2007 + http://teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf +*/ + + +#ifndef DS18B20_H_ +#define DS18B20_H_ + +#include + +//setup connection + +#define DS18B20_PORT PORTD +#define DS18B20_DDR DDRD +#define DS18B20_PIN PIND +#define DS18B20_DQ PD7 + +//commands +#define DS18B20_CMD_CONVERTTEMP 0x44 +#define DS18B20_CMD_RSCRATCHPAD 0xbe +#define DS18B20_CMD_WSCRATCHPAD 0x4e +#define DS18B20_CMD_CPYSCRATCHPAD 0x48 +#define DS18B20_CMD_RECEEPROM 0xb8 +#define DS18B20_CMD_RPWRSUPPLY 0xb4 +#define DS18B20_CMD_SEARCHROM 0xf0 +#define DS18B20_CMD_READROM 0x33 +#define DS18B20_CMD_MATCHROM 0x55 +#define DS18B20_CMD_SKIPROM 0xcc +#define DS18B20_CMD_ALARMSEARCH 0xec + +//stop any interrupt on read +#define DS18B20_STOPINTERRUPTONREAD 1 + +//functions +uint8_t ds18b20_reset(void); +void ds18b20_writebit(uint8_t bit); +uint8_t ds18b20_readbit(void); +void ds18b20_writebyte(uint8_t byte); +uint8_t ds18b20_readbyte(void); + +extern double ds18b20_gettemp(void); + +#endif diff --git a/main.c b/main.c index 8919a74..fd1f002 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,7 @@ #include #include #include +#include "ds18b20.h" #include "main.h" #include "io.h" @@ -9,9 +10,22 @@ void initIO() DDRD |= (1 << LED_1); } +void readTemp() +{ + double d; + + sei(); + d = ds18b20_gettemp(); + if (d >= 21) + PORTD |= (1 << LED_1); + else + PORTD &= ~(1 << LED_1); +} + int main(void) { initIO(); + readTemp(); return 0; } diff --git a/src/ds18b20.c b/src/ds18b20.c new file mode 100644 index 0000000..4ba3c77 --- /dev/null +++ b/src/ds18b20.c @@ -0,0 +1,144 @@ +/* +ds18b20 lib 0x02 + +copyright (c) Davide Gironi, 2012 + +Released under GPLv3. +Please refer to LICENSE file for licensing information. +*/ + +#include +#include +#include + +#include "ds18b20.h" + +/* + * ds18b20 init + */ +uint8_t ds18b20_reset() +{ + uint8_t i; + + //low for 480us + DS18B20_PORT &= ~(1 << DS18B20_DQ); //low + DS18B20_DDR |= (1 << DS18B20_DQ); //output + _delay_us(480); + + //release line and wait for 60uS + DS18B20_DDR &= ~(1 << DS18B20_DQ); //input + _delay_us(60); + + //get value and wait 420us + i = (DS18B20_PIN & (1 << DS18B20_DQ)); + _delay_us(420); + + //return the read value, 0=ok, 1=error + return i; +} + +/* + * write one bit + */ +void ds18b20_writebit(uint8_t bit) +{ + //low for 1uS + DS18B20_PORT &= ~(1 << DS18B20_DQ); //low + DS18B20_DDR |= (1 << DS18B20_DQ); //output + _delay_us(1); + + //if we want to write 1, release the line (if not will keep low) + if (bit) + DS18B20_DDR &= ~(1 << DS18B20_DQ); //input + + //wait 60uS and release the line + _delay_us(60); + DS18B20_DDR &= ~(1 << DS18B20_DQ); //input +} + +/* + * read one bit + */ +uint8_t ds18b20_readbit(void) +{ + uint8_t bit = 0; + + //low for 1uS + DS18B20_PORT &= ~(1 << DS18B20_DQ); //low + DS18B20_DDR |= (1 << DS18B20_DQ); //output + _delay_us(1); + + //release line and wait for 14uS + DS18B20_DDR &= ~(1 << DS18B20_DQ); //input + _delay_us(14); + + //read the value + if (DS18B20_PIN & (1 << DS18B20_DQ)) + bit = 1; + + //wait 45uS and return read value + _delay_us(45); + return bit; +} + +/* + * write one byte + */ +void ds18b20_writebyte(uint8_t byte) +{ + uint8_t i = 8; + while (i--) { + ds18b20_writebit(byte & 1); + byte >>= 1; + } +} + +/* + * read one byte + */ +uint8_t ds18b20_readbyte(void) +{ + uint8_t i = 8, n = 0; + while (i--) { + n >>= 1; + n |= (ds18b20_readbit() << 7); + } + return n; +} + +/* + * get temperature + */ +double ds18b20_gettemp() +{ + uint8_t temperature_l; + uint8_t temperature_h; + double retd = 0; + +#if DS18B20_STOPINTERRUPTONREAD == 1 + cli(); +#endif + + ds18b20_reset(); //reset + ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM + ds18b20_writebyte(DS18B20_CMD_CONVERTTEMP); //start temperature conversion + + while (!ds18b20_readbit()); //wait until conversion is complete + + ds18b20_reset(); //reset + ds18b20_writebyte(DS18B20_CMD_SKIPROM); //skip ROM + ds18b20_writebyte(DS18B20_CMD_RSCRATCHPAD); //read scratchpad + + //read 2 byte from scratchpad + temperature_l = ds18b20_readbyte(); + temperature_h = ds18b20_readbyte(); + +#if DS18B20_STOPINTERRUPTONREAD == 1 + sei(); +#endif + + //convert the 12 bit value obtained + retd = ((temperature_h << 8) + temperature_l) * 0.0625; + + return retd; +}