logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Atmega8 + DS18B20 ->problem z pomiarem

m_misek 27 Sty 2009 17:04 2427 7
REKLAMA
  • #1 6062394
    m_misek
    Poziom 11  
    Witam.
    Nie pisałbym tego postu gdyby wszystko było w porządku ale niestety nie jest. W czym problem : A wiec, posiadam ATmega8 na 8Mhz wewnętrznym oscylatorze
    uisp -dprog=stk200 --erase --upload if=program.hex --verify --wr_fuse_l=0xe4

    oraz czujnik DS18B20 podpięty pod PC2, linia danych podpięta przez rezystor 4.7k do Vcc, zasilanie pasożytnicze, ( o dziwo przy zasilaniu Vcc jako osobna linia czujnik strasznie sie grzeje) , generalnie, podlączono tak jak w nocie katalogowej, i w innych znalezionych schematach przy zasilaniu pasożytniczym. Przejdę do puenty czyli przedstawię kod
    Funkcje opózniajace ( sprawdzane pod AVR Studio, i np dla 100us jest te około 100,5us)
    void delay_us(unsigned char t) //parametr t od 0 do 255.
    {
    do{
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      asm("nop");
      }while(--t);
    }
    void delay_ms(unsigned char t)
    {
     do{
     delay_us(255);
     delay_us(255);
     delay_us(255);
     delay_us(255);
     } while(--t);
    }

    Nastepnie ,makra i definicje (te podstawowe ):
    #ifndef F_CPU
    #define F_CPU 8000000UL
    #endif
    
    #define OW_PIN 2 //pin na ktorym jest termometr
    #define OW_PORT PORTC // port na ktorym jest termometr
    #define SET_1Wire DDRC&=~_BV(OW_PIN)
    #define CLEAR_1Wire DDRD|=_BV(OW_PIN)
    

    Następnie funkcje obsługujące magistral :
    unsigned char OW_reset()	//reset OW
    
    {
     unsigned char stan=0;
     CLEAR_1Wire;
     delay_us(240); //opoznienie 480 us
     delay_us(240); //opoznienie 480 us
     SET_1Wire;
     delay_us(60); //opoznienie 60 us
     if (bit_is_set(PINC,OW_PIN)) stan =1; //jesli 0 na lini czujnik obecny
     delay_us(210);//opoznienie 410
     delay_us(200);//opoznienie 410
     return stan;
    }
    unsigned char OW_read_bit()	// odczyt bitu z lini OW
    {
     CLEAR_1Wire;
     delay_us(5);
     SET_1Wire;
     delay_us(15);//podtrzymanie 0 na lini
     if (bit_is_set(PINC,OW_PIN)) return 1;else return 0;
    }
    void OW_write_bit(char bit)
    {
     CLEAR_1Wire;
     delay_us(5);
     if (bit == 1) SET_1Wire;
     delay_us(80);
     SET_1Wire;
    }
    unsigned char OW_read_byte(void) //odczyt bajtu z lini OW
    
    {
    	unsigned char output=0;
    	unsigned char i;
    	for (i=0;i<8;i++)
    		{
    		if(OW_read_bit()) output|= 0x01<<i;
    		delay_us(15);
    		}
    	return  output;
    }
    
    void OW_write_byte(char byte) // zapis bajtu do lini OW
    
    {
    
    	unsigned char i,pom;
    
    	for (i=0;i<8;i++)
    
    		{
    
    		pom = byte>>i;
    
    		pom &= 0x01;
    
    		OW_write_bit(pom);
    
    		}
    	delay_us(100);
    
    }

    a także na koncu main();funcke obslugujące wyświetlacz ,pominięete, one są dobre i wyświetlacz działa prawidłowo.
    int main(void) {
    	char buf[8];
    	int t,i;
    	unsigned char test;
    	char temp1=0,temp2=0;
    	float temp=0;
    	PORTC &=~_BV(2);
    	init(MYUBRR);
    	LCD_Initalize();
    	for(;;)
    	{
    	 delay_ms(250);
    	 test=OW_reset();
    	if(OW_reset())
    	    {
    	     LCD_Clear();
    	     LCD_WriteText("Trwa pomiar...");
    	     OW_reset();
    	     OW_write_byte(0xCC);
    	     OW_write_byte(0x44);
    	     delay_ms(250);
    	     delay_ms(250);
    	     delay_ms(250);
    	     OW_reset();
    	     OW_write_byte(0xCC);
    	     OW_write_byte(0xBE);
    	     temp1=OW_read_byte();
    	     temp2=OW_read_byte();
    	     OW_reset();
    	     temp=(float)(temp1+(temp2*256))/16;
    	     dtostrf(temp,1,1,buf);
    	     LCD_GoTo(2,1);
    	     LCD_WriteText(buf);
    	     LCD_Home();
    	     delay_ms(250);//pomiar co 250ms
    	     }
    	     else {LCD_Clear();LCD_WriteText("Brak DS18B20");}
    	    }
    }


    Dodam jeszcze ze przy braku czujnika dostaje 2 razy komunikat o jego braku następnie jakimś cudem go wykrywa i dokonuje pomiaru, pomiaru który zawsze wynosi -16.1 stopnia. wiec domyślam się że to żaden pomiar. A teraz prośba do Was : czy ktoś mógłby mnie naprowadzić na błąd (wskazał błąd)? nie wiem, może coś z opóźnieniami ,albo obsługa magistrali ?
    Z góry dzięki wam za każdą podpowiedz która doprowadzi mnie do celu.
    Oraz przepraszam ,jeśli post jest nie tak zredagowany, w złym dziale, lub cokolwiek innego (za pierwszym razem zawsze jest nie do końca poprawnie :) )
  • REKLAMA
  • #2 6062473
    dawid512
    Poziom 32  
    Jak myślisz co tu jest nie tak:
    #define OW_PORT PORTC // port na ktorym jest termometr
    #define SET_1Wire DDRC&=~_BV(OW_PIN)
    #define CLEAR_1Wire DDRD|=_BV(OW_PIN) 
  • REKLAMA
  • #3 6062503
    m_misek
    Poziom 11  
    dawid512 napisał:
    Jak myślisz co tu jest nie tak:
    #define OW_PORT PORTC // port na ktorym jest termometr
    #define SET_1Wire DDRC&=~_BV(OW_PIN)
    #define CLEAR_1Wire DDRD|=_BV(OW_PIN) 


    DDRD zamiast DDRC, fakt, drobna pomylka, no to teraz ciagle mi pokazuje ze brak DS18B20...
  • REKLAMA
  • REKLAMA
  • #5 6063304
    m_misek
    Poziom 11  
    dobra.. wykrywa juz czujnik, teraz kolejny problem ktory tez juz sie tutaj wielokrotnie pojawial, mianowicie odczytuje 85 stopni.
    Poczytalem, i : sprawdzilem zasilanie, jest OK, sprawdzilem na inym czujniku tez to samo, wiec sadze ze problem z czasami, teraz tylkoo pytanie.. ktorymi ?
  • #6 6063803
    dawid512
    Poziom 32  
    Poczytaj o trybie pasożytniczym w datasheecie. Po za tym coś masz nie tak skoro przy normalnym zasilaniu czujnik się grzeje.
  • #7 6064800
    m_misek
    Poziom 11  
    poczytalem o trybie pasozytniczym, probowalem ustawiac podczas pomiaru pin na ktorym jest termometr jako wyjscie i w stan wysoki, jednak to nie dawalo rezultatu. W jakims watku tu na forum wyczytalem takze ze mozna zmniejszyc wartosc rezystora podciagajacego. Tak zrobilem i jest, mam zmierzoną temperature, tylko ze oszukuje, jakies 4 stopnie. po przytrzymaniu go palcami dostaje odczyt okolo 32.6 stopnia, cialo ludzkie ma okolo 36.6.
    Dodam ze ROM odczytuje poprawnie.
    co do podlaczenia "normalnego" to nie mam pojecia czemu tak jest, zadnego zwarcia nie zauwazylem, a mimo tego ciagle sie grzeje, i to znacznie;/
  • #8 6066321
    dawid512
    Poziom 32  
    Skoro się grzeje to albo jest uszkodzony albo źle go podłączasz.
REKLAMA