Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

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

rafaloos 09 Lis 2010 04:20 1642 8
  • #1 09 Lis 2010 04:20
    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):

    Code:
    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 :(

    0 8
  • #2 09 Lis 2010 06:36
    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

    0
  • Pomocny post
    #3 09 Lis 2010 12:16
    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.

    0
  • #4 09 Lis 2010 12:55
    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.

    Code:
    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
    Code:
       //_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?

    0
  • #5 09 Lis 2010 14:01
    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)

    0
  • #6 09 Lis 2010 16:37
    michalko12
    Specjalista - Mikrokontrolery

    Code:
    //---------------------------------------------
    
    //   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.

    0
  • #7 09 Lis 2010 16:46
    gaskoin
    Poziom 38  

    wydaje mi się, że przy włączonej optymalizacji kompilator zeżre taką funkcję

    0
  • Pomocny post
    #8 09 Lis 2010 16:56
    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.

    0
  • #9 09 Lis 2010 17:48
    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ąć.

    0
  Szukaj w 5mln produktów