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

[ATMEGa128][C] DS18B20 - ROM czyta, ale LSB i MSB juz nie

rafaloos 09 Lis 2010 04:20 1969 8
  • #1 8720610
    rafaloos
    Poziom 11  
    Witam,

    Mam problem z czujnikiem temperatury DS18B20.
    Tak przeszukałem forum, przeczytałem kilkanaście tematów, nic nie pomogło.
    Sprawdzałem parę bibliotek, efekty podobne.
    Wspomnę tylko, że czujnik jest sprawny na 100%, w Bascomie odczytuję temperaturę bez problemu.
    Do rzeczy. W chwili obecnej mogę odczytać ROM code a nawet sam Scratch.
    Przy konwersji temperatury (fragment kodu):

    while(1){								//16MHz
    	owire_reset();               // sekwencja inicjalizująca
       owire_write_byte(0xCC);         // rozkaz pomiń ROM
       owire_write_byte(0x44);         // rozkaz konwertuj temperaturę
       for(i=0; i<28;i++)                  // Cala petla daje 470ms dla 16MHZ zewn. kwarc
       {
    	owire_delay(65535);       
    	}
    
    	owire_delay(45020);      //jest to wartsc 470 ms(28*65535+45020) !? 1us = 4;
       //_delay_ms(250);
       //_delay_ms(250);
       //_delay_ms(250);
    
       owire_reset();
       owire_write_byte(0xCC);         // rozkaz pomiń ROM
       owire_write_byte(0xBE);         // rozkaz umożliwiający odczytanie temperatury
       
    //_delay_ms(250);
       lsb = owire_read_byte();      // odczytanie młodszych bitów temperatury
       msb = owire_read_byte();      // odczytanie starszych bitów temperatury 
    	
    	
    	//_delay_ms(250);
    	//_delay_ms(250);
    	//_delay_ms(250);
    


    dostaję wartości standardowe 50h(LSB) 05h(MSB) czyli temp = 85 st. C.
    Metodą prób i błędów w pewnych momentach dostaję wartości FFh (LSB) i 07h (MSB) czyli de facto nic nie dostaję. Wygląda to tak jakby konwersja w ogóle nie występowała?
    Proszę o jakieś wskazówki. Pół nocy zmarnowane :(
  • #2 8720639
    CDMaster
    Poziom 14  
    Pewien nie jestem ale wydaje mi się, że trzeba było dodatkowo ustawić stan wysoki na szynę podczas przetwarzania. Przynajmniej w trybie "pasożytniczym" :D
  • Pomocny post
    #3 8721242
    hotdog
    Poziom 26  
    Tak się objawiają uszkodzone czujniki. Sprawdź go jeszcze raz w bascomie.

    Pozatym masz jakieś dziwne te delay'e czemu używasz funkcji owire_delay przecież masz _delay_ms?
    Trochę wróżąc z kodu wnioskuje że funkcja delay odmierza 0,25us * przekazany argument.
    Piszesz w komenarzach że niby ta pętla for + funkcja poniżej jej trwa 470ms. Jak nie przestawiałeś rozdzielczości to powinieneś odczekać 750ms.
  • #4 8721330
    rafaloos
    Poziom 11  
    hotdog napisał:
    Tak się objawiają uszkodzone czujniki. Sprawdź go jeszcze raz w bascomie.

    Pozatym masz jakieś dziwne te delay'e czemu używasz funkcji owire_delay przecież masz _delay_ms?
    Trochę wróżąc z kodu wnioskuje że funkcja delay odmierza 0,25us * przekazany argument.
    Piszesz w komenarzach że niby ta pętla for + funkcja poniżej jej trwa 470ms. Jak nie przestawiałeś rozdzielczości to powinieneś odczekać 750ms.


    Nie przestawiałem rozdzielczości.
    Dalej nie działa mimo, iż zwiększyłem czas oczekiwania do 750ms.

    while(1){								//16MHz
    	owire_reset();               // sekwencja inicjalizująca
       owire_write_byte(0xCC);         // rozkaz pomiń ROM
       owire_write_byte(0x44);         // rozkaz konwertuj temperaturę
       
       PORTB |= (1<<DQ);       //podciągniecie linii DQ i odczekanie na konwersje.
    	
    	
       for(i=0; i<46;i++)                    ////jest to wartsc >=750 ms || 1us = 4;
        {
    		owire_delay(65535);
    	}
    
    	//owire_delay(45020);      
       //_delay_ms(250);
       //_delay_ms(250);
      
       //_delay_ms(760);
       owire_reset();
       owire_write_byte(0xCC);         // rozkaz pomiń ROM
       owire_write_byte(0xBE);         // rozkaz umożliwiający odczytanie temperatury
       //_delay_ms(250);
       lsb = owire_read_byte();      // odczytanie młodszych bitów temperatury
       msb = owire_read_byte();      // odczytanie starszych bitów temperatury 
    	
    	
    	//_delay_ms(250);
    	//_delay_ms(250);
    	//_delay_ms(250);
    


    Próbowałem też z
       //_delay_ms(760);


    ale niestety nie pomogło.
    Mimo, iż mam zewnętrzne zasilanie( nie pasożytnicze) to podciągnąłem linie DQ czyli PORTB.5 do "1". Po takiej operacji wartość LSB i MSB = FFh każdy.
    Tak w Bascomie dalej działa, pokazuje temperature pokojową ~23 st. C
    Jak go lekko podgrzeje temperatura idzie w góre o kilka stopni.
    Jak ostygnie to wraca do temp. pokojowej czyli na bank jest dobry.
    Coś z procedurami w C jest nie tak, tylko co?
    W załączniku przesyłam kod programu i bibliotekę której używam(#include "1-Wire.h")
    Dla mnie dziwny jest fakt, że ROM mogę odczytać bez problemu i na pewno wartości są dobre bo zgadza się m.in. Family Code = 28h.
    Macie jakie pomysły?
  • #5 8721495
    gdL
    Poziom 27  
    Tak jak pisałem Koledze na priv:

    Parasite power supply ? Sprawdz, czy rezystor nie ma za duzej wartosci, mozesz do tego ustawic wyjscie jako out w stanie wysokim, zeby zapewnic czujnikowi odpowiednie warunki do konwersji. "Strong pullup", tak to opisano w datasheet.

    Jesli nie, to kontrolnie przedluz delay podczas konwersji.

    Mozesz tez pokombinowac ze stalymi czasowymi w bibliotece, ale jesli podaje swoj ID dobrze, to prawdopodobnie nie tu problem lezy.

    Oprócz tego upewniłbym się co do stosowanych bibliotek. Moje są na elektrodzie, można sobie z nich skorzystać. Co do tych, to nic nie powiem, bo nie wiem czy działają i na ile.

    To co opisujesz wskazuje na 1) problem z zasilaniem 2) problem z podłączeniem.

    Czujnik proponuję na początek podpiąć na krótkim kablu/płytce, żeby wyeliminować punkt 2)
  • #6 8722071
    michalko12
    Specjalista - Mikrokontrolery
    //---------------------------------------------
    //	waitus() Dla zegara 4MHz, funkcja odmierza
    //	tyle mikrosekund, co podany parametr tau
    //---------------------------------------------
    void waitus(unsigned char tau)
    {    
    	do
    	{
    		asm("nop");           //NOP
    	}while(--tau!=0);
    }


    Bardzo precyzyjna funkcja. Powstawiaj więcej NOPów.
  • #7 8722105
    gaskoin
    Poziom 38  
    wydaje mi się, że przy włączonej optymalizacji kompilator zeżre taką funkcję
  • Pomocny post
    #8 8722145
    gdL
    Poziom 27  
    Z tego co kolarzę, Kolega używał też mojej biblioteczki wcześniej i również to nie działało. Wydaje się, że nie w tym problem.
  • #9 8722372
    rafaloos
    Poziom 11  
    hotdog napisał:
    Tak się objawiają uszkodzone czujniki. Sprawdź go jeszcze raz w bascomie.

    Pozatym masz jakieś dziwne te delay'e czemu używasz funkcji owire_delay przecież masz _delay_ms?
    Trochę wróżąc z kodu wnioskuje że funkcja delay odmierza 0,25us * przekazany argument.
    Piszesz w komenarzach że niby ta pętla for + funkcja poniżej jej trwa 470ms. Jak nie przestawiałeś rozdzielczości to powinieneś odczekać 750ms.


    Właśnie wróciłem z elektronika z nowym DS'em. Teraz wszystko gra.
    Jak kolega wspomniał czujnik jest raczej uszkodzony.
    Dziwne, że w Bascomie wszystko gra :D
    Dziękuje wszystkim za pomoc.
    Pozdrawiam

    // edit: temat można zamknąć.
REKLAMA