Read temperature from DS18B20+

This commit is contained in:
Rihards Skuja 2017-11-24 13:40:29 +02:00
parent f29a72ac6e
commit 4a0ef9515c
No known key found for this signature in database
GPG Key ID: 53FA13A3F7F8571B
3 changed files with 211 additions and 0 deletions

53
include/ds18b20.h Normal file
View File

@ -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 <avr/io.h>
//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

14
main.c
View File

@ -1,6 +1,7 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#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;
}

144
src/ds18b20.c Normal file
View File

@ -0,0 +1,144 @@
/*
ds18b20 lib 0x02
copyright (c) Davide Gironi, 2012
Released under GPLv3.
Please refer to LICENSE file for licensing information.
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#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;
}