Created
July 6, 2012 03:24
-
-
Save cdesch/3057888 to your computer and use it in GitHub Desktop.
DS12B20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#define F_CPU 8000000UL | |
#include <util/delay.h> | |
#include <stdlib.h> | |
#include "ds18b20.h" | |
inline __attribute__((gnu_inline)) void therm_delay(uint16_t delay){ | |
while(delay--) asm volatile("nop"); | |
} | |
uint8_t therm_reset() { | |
uint8_t i; | |
// Pull line low and wait for 480uS | |
THERM_LOW(); | |
THERM_OUTPUT_MODE(); | |
//therm_delay(us(480)); | |
_delay_loop_2(960); | |
//Release line and wait for 60uS | |
THERM_INPUT_MODE(); | |
//therm_delay(us(60)); | |
_delay_loop_1(160); | |
//Store line value and wait until the completion of 480uS period | |
i=(THERM_PIN & (1<<THERM_DQ)); | |
//therm_delay(us(420)); | |
_delay_loop_2(840); | |
//Return the value read from the presence pulse (0=OK, 1=WRONG) | |
return i; | |
} | |
void therm_write_bit(uint8_t bit){ | |
//Pull line low for 1uS | |
THERM_LOW(); | |
THERM_OUTPUT_MODE(); | |
//therm_delay(us(1)); | |
_delay_loop_1(3); | |
//If we want to write 1, release the line (if not will keep low) | |
if(bit) THERM_INPUT_MODE(); | |
//Wait for 60uS and release the line | |
//therm_delay(us(60)); | |
_delay_loop_1(160); | |
THERM_INPUT_MODE(); | |
} | |
uint8_t therm_read_bit(void){ | |
uint8_t bit=0; | |
//Pull line low for 1uS | |
THERM_LOW(); | |
THERM_OUTPUT_MODE(); | |
//therm_delay(us(1)); | |
_delay_loop_1(3); | |
//Release line and wait for 14uS | |
THERM_INPUT_MODE(); | |
//therm_delay(us(14)); | |
_delay_loop_1(37); | |
//Read line value | |
if(THERM_PIN&(1<<THERM_DQ)) bit=1; | |
//Wait for 45uS to end and return read value | |
//therm_delay(us(45)); | |
_delay_loop_1(120); | |
return bit; | |
} | |
uint8_t therm_read_byte(void){ | |
uint8_t i=8, n=0; | |
while(i--){ | |
//Shift one position right and store read value | |
n>>=1; | |
n|=(therm_read_bit()<<7); | |
} | |
return n; | |
} | |
void therm_write_byte(uint8_t byte){ | |
uint8_t i=8; | |
while(i--){ | |
//Write actual bit and shift one position right to make the next bit ready | |
therm_write_bit(byte&1); | |
byte>>=1; | |
} | |
} | |
#define THERM_DECIMAL_STEPS_12BIT 625 //.0625 | |
#define THERM_DECIMAL_STEPS_9BIT 500 //.500 | |
void therm_read_temperature(int8_t *digit_part, uint16_t *decimal_part){ | |
// Buffer length must be at least 12bytes long! ["+XXX.XXXX C"] | |
uint8_t temperature[2]; | |
int8_t digit; | |
uint16_t decimal; | |
//Reset, skip ROM and start temperature conversion | |
therm_reset(); | |
therm_write_byte(THERM_CMD_SKIPROM); | |
therm_write_byte(THERM_CMD_CONVERTTEMP); | |
//Wait until conversion is complete | |
while(!therm_read_bit()); | |
//Reset, skip ROM and send command to read Scratchpad | |
therm_reset(); | |
therm_write_byte(THERM_CMD_SKIPROM); | |
therm_write_byte(THERM_CMD_RSCRATCHPAD); | |
//Read Scratchpad (only 2 first bytes) | |
temperature[0]=therm_read_byte(); | |
temperature[1]=therm_read_byte(); | |
therm_reset(); | |
//Store temperature integer digits and decimal digits | |
digit=temperature[0]>>4; | |
digit|=(temperature[1]&0x7)<<4; | |
//Store decimal digits | |
decimal=temperature[0]&0xf; | |
decimal*=THERM_DECIMAL_STEPS_12BIT; | |
*digit_part = digit; | |
*decimal_part = decimal; | |
//Format temperature into a string [+XXX.XXXX C] | |
//sprintf(buffer, "%+d.%04u C", digit, decimal); | |
//sprintf(buffer, "%d.%d\n",temperature[0]/2, (temperature[0]&1)*5 ); | |
//usart_write_str(buffer); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef DS18B20_H_ | |
#define DS18B20_H_ | |
#include <avr/io.h> | |
#include <avr/interrupt.h> | |
#ifndef F_CPU | |
#define F_CPU 8000000UL | |
#endif | |
#include <util/delay.h> | |
// LCD | |
#include <stdlib.h> | |
#include <avr/pgmspace.h> | |
#define LOOP_CYCLES 10 //Number of cycles that the loop takes | |
#define us(num) (num/(LOOP_CYCLES*(1/(F_CPU/1000000.0)))) | |
/* Thermometer Connections (At your choice) */ | |
/* | |
#define THERM_PORT PORTC | |
#define THERM_DDR DDRC | |
#define THERM_PIN PINC | |
#define THERM_DQ PC0 | |
*/ | |
#define THERM_PORT PORTE | |
#define THERM_DDR DDRE | |
#define THERM_PIN PINE | |
#define THERM_DQ PE2 | |
/* Utils */ | |
#define THERM_INPUT_MODE() THERM_DDR&=~(1<<THERM_DQ) | |
#define THERM_OUTPUT_MODE() THERM_DDR|=(1<<THERM_DQ) | |
#define THERM_LOW() THERM_PORT&=~(1<<THERM_DQ) | |
#define THERM_HIGH() THERM_PORT|=(1<<THERM_DQ) | |
#define THERM_CMD_CONVERTTEMP 0x44 | |
#define THERM_CMD_RSCRATCHPAD 0xbe | |
#define THERM_CMD_WSCRATCHPAD 0x4e | |
#define THERM_CMD_CPYSCRATCHPAD 0x48 | |
#define THERM_CMD_RECEEPROM 0xb8 | |
#define THERM_CMD_RPWRSUPPLY 0xb4 | |
#define THERM_CMD_SEARCHROM 0xf0 | |
#define THERM_CMD_READROM 0x33 | |
#define THERM_CMD_MATCHROM 0x55 | |
#define THERM_CMD_SKIPROM 0xcc | |
#define THERM_CMD_ALARMSEARCH 0xec | |
void therm_read_temperature(int8_t *digit_part, uint16_t *decimal_part); | |
#endif /* */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment