DS18B20 na AVR

Sep 23, 2004 6 Replies

Witam. Od 2 dni mêczê siê z obs³ug± czujnika DS18B20 na procesorze ATMega8. Czujnik jest podpiêty do portu PB0 (równie¿ jest z niego zasilany - DQ przez rezystor 4,7k podpiêty do Vcc, a VDD zwarty z mas±). Próbowa³em skorzystaæ z kodu z w±tku

formatting link
, ale po konwersji ci±gle dostajê warto¶æ 5 (bez konwersji 0, czyli nic nie odczytuje). Czy kto¶ mog³by mnie wspomóc dzia³aj±cym kodem w C dla AVR? By³bym zobowi±zany. Z góry dziêkujê za pomoc! Pozdrawiam


#include <avr/io.h>

#include <avr/delay.h>

#include "lcd.h"

#define OWPORT PORTB #define OWPIN 0 #define OWPININ PINB #define OWDDR DDRB #define OWIN 1 // 2^OWPIN

#define delay_us(x) _delay_loop_2(x*2) #define ow_lo() sbi(OWDDR, OWPIN) #define ow_hi() cbi(OWDDR, OWPIN)

uint8_t ow_reset(void){ uint8_t a; ow_lo(); delay_us(480); ow_hi(); delay_us(70); a = inp(OWPININ) & OWIN; // 0 - obecny, else - nieobecny delay_us(410); return a; }

void ow_wrbit(uint8_t bit){ ow_lo(); if(bit == 0){ delay_us(60); ow_hi(); delay_us(10); } else { delay_us(6); ow_hi(); delay_us(64); } }

uint8_t ow_rdbit(void){ uint8_t a; ow_lo(); delay_us(6); ow_hi(); delay_us(9); a = inp(OWPININ) & OWIN; //0 - 0, else -1 delay_us(55); return a; }

uint8_t ow_rdbyte(void){ uint8_t a, b; a = 0; for(b = 0; b <8; b++){ a >>= 1; if (ow_rdbit()) a += 128; } return a; }

void ow_wrbyte(uint8_t data){ uint8_t a; for(a = 0; a < 8; a++){ ow_wrbit(data & 1); data >>= 1; } }

void lcd_putuint8(uint8_t a){ uint8_t b; b = a / 100; if (b) lcd_putc(b + 0x30); a -= b * 100; b = a / 10; lcd_putc(b + 0x30); a -= b * 10; lcd_putc(a + 0x30); }

void lcd_putuint16(uint16_t a){ uint8_t b; b = a / 10000; // lcd_putc(b + 0x30); a -= b * 10000; b = a / 1000; lcd_putc(b + 0x30); a -= b * 1000; b = a / 100; lcd_putc(b + 0x30); a -= b * 100; b = a; lcd_putuint8(b); }

int main(void){ uint8_t a, b, c; uint16_t e; lcd_init( LCD_DISP_ON); cbi(OWPORT, OWPIN); ow_hi(); for(;;){ ow_reset(); ow_wrbyte(0xCC); //SKIP ROM ow_wrbyte(0x44); //CONVERT T for(a = 1; a <100; a++){ delay_us(10000); } ow_reset(); ow_wrbyte(0xCC); //SKIP ROM ow_wrbyte(0xBE); //READ SCRATCHPAD a = ow_rdbyte(); b = ow_rdbyte(); c = a & (0x0F); // wartości dziesiętne (po przecinku) a >>= 4; b <<= 4; a = a | b; e = 625 * c; lcd_clrscr(); lcd_home(); lcd_putuint8(a); lcd_puts(","); lcd_putuint16(e); } return 0; }

kod dla avr-gcc

ustaw na 8

WJ napisał(a):

nie wiem czy to ma znaczenie, bo na razie za bardzo nie mam kiedy sprawdzic kodu, ale to jest dla 51 kod, a nie dla AVR - przeciez masz podana wersje procka... moze sie roznic czyms...

ale jak napisalem - moge byc w wielkim bledzie... nie musi miec to znaczenia...

Ju¿ jest 8MHz ;)) Dziêki za kod. Niestety dalej nie dzia³a. Stawiam na uszkodzenie czujnika (z Allegro). Wczoraj kto¶ mi powiedzia³, ¿e wystarczy pomyliæ nó¿ki przy pod³±czeniu i czujnik ju¿ jest do wymiany. Naprawdê jest taki delikatny? Mój jest oczywi¶cie z ca³± pewno¶ci± podpiêty tak jak trzeba. Mam jeszcze jedno pytanko: czujnik mam podpiêty 2-przewodowo, a jakie korzy¶ci daje pod³±czenie go trzema przewodami? To, ¿e czujnik dzia³a wtedy na d³u¿szym przewodzie, to wiem, ale s± jeszcze inne korzy¶ci z takiego pod³±czenia? Pozdrawiam

Kod w C ma to do siebie, ¿e jest "przeno¶ny" miêdzy ró¿nymi platformami sprzêtowymi, wiêc to powinno dzia³aæ. Co do procesora, to wykorzystujê bibliotekê <iom8v.h>. Pozdrawiam

Jesli podlaczysz odwrotnie zasilanie to tak.

Upraszcza sterowanie czujnikiem - nie musisz dawac strong pull-up na czas konwersji, a druga zaleta - umozliwia odczytywanie temperatur >85 stopni.

Szyna 1-wire ma dosys duze wymagania jesli chodzi o timingi. Dlatego kod '51 i AVR mimo, ze w C niekoniecznie musi byc przenoscny. Ale to zalezy w duzej mierze od tego jak napisana jest biblioteka. Dlatego ja wole assembler ;P

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required