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

AT89S52 + 18B20 = PROBLEM

01 Maj 2006 14:09 1602 1
  • Poziom 10  
    Witam.
    Post mniej więcej jest o tym o czym temat więc bez zbędnego tłumaczenia przejdę do rzeczy:

    Sprzęt:
    AT89S52 (8kB Flash)
    Wyświetlacz LCS 2*16
    Czujnik temperatury 18B20
    Kwarc 12MHz
    Program pisany w asemblerze

    Robię projekt którego celem jest realizacja zegara z termometrem (czego to już człowiek nie wymyśli : - ) ).
    Postanowiłem że pomiar temperatury będzie realizowany na układzie 18B20 firmy Dallas.
    Transmisja danych oparta jest na magistrali 1 wire.

    Problem mam następujący, mam dwa czujniki 18B20. Chcę jeden z nich podłączyć do AT89S52, w tym celu napisałem w asemblerze obsługę 1 – wire i zacząłem zabawę.
    Bardzo szybko jednak pojawił się problem którego nie mogę rozwiązać.

    Na początku wszystko jest super, po inicjalizacji układu, 18B20 odpowiada krótkim ujemnym (niskim) impulsem, potwierdzającym jego obecność. Następnie procek powiadamia 18B20 że jest (18B20) jedynym urządzeniem (slave) na magistrali i nie trzeba bawić się w adresowanie. Potem zapisuje do pamięci 18B20 że interesuje mnie pomiar temperatury z najmniejszą dokładnością (R0=0 R1=0 w rej. Kontrolnym). Zapisuje także graniczne wartości temperatury, jako że mnie nie interesuje ta funkcja wpisuje 01111101 jako TH i 11001001 jako TL co teoretycznie oznacza największą i najmniejszą możliwą temperaturę jaką może mierzyć układ (kolejność zapisu TH, TL, rejestr kontrolny).
    Potem sprawdzam czy wszystko poprawnie zostało wpisane do pamięci 18B20, czytając jej zawartość i okazuje się że wszystko jest OK.
    No więc zaczynam pomiar, inicjalizuje 1-wire, Ponownie sygnalizuje że jest tylko jedno urządzenie na magistrali po czym wpisuje funkcje pomiaru temperatury na 1-wire, czekam ok. 350 sek. (nadmieniam że próbowałem zastąpić opóźnienie czytaniem stanu magistrali i czekaniem na 1 co wg. dokumentacji oznacza koniec pomiaru temperatury).
    Inicjalizuje 1-wire.
    Wystawiam na magistrale informacje że będę czytał 9 bajtów z pamięci 18B20 gdzie dwa pierwsze to kolejno mniej i bardziej znaczący bajt temperatury.
    I tu pojawia się problem od początku układ bzikował. Najpierw nie chciał przestawić się abym otrzymywał 9 –bitowy pomiar, potem w ogóle siadł. Mam dwa układy 18B20 i oba robią to samo, jeden nawet wcześniej nie pokazywał temp. 12 bitowej.
    Obecnie układy „uparły się” i za każdym razem jak czytam temperaturę to otrzymuje:
    MSB 00000101
    LSB 01010000
    I tak oba układy.

    Zastanawiałem się czy problem nie tkwi z błędem w implementacji 1- wire ale przecież przy odczytywaniu zawartości pamięci wszystko przebiega prawidłowo, podobnie przy zapisie.
    Nie wiem co jest nie tak, bawię się już z tym dwa dni.

    Jedyny pomysł na jaki wpadłem to to że układy uległy uszkodzeniu, gdy pierwszy raz je podpinałem (niestety oba) zamieniłem polaryzacje, układ oczywiście nie działał i nie wiem czy nie spowodowałem tym uszkodzenia

    Niestety nie mogę dać tutaj listingu programu gdyż pisze go na innym kompie (starym) gdzie jedynym urządzeniem umożliwiającym wyprowadzenie danych z kompa jest dyskietka, a z kolei ten post pisze na laptopie gdzie oczywiście stacji dyskietek nie ma.. ani portu LPT co uniemożliwiało by mi programowanie uP : - (.

    Proszę o wszelaką pomoc i pomysły!! Może ktoś spotkał się z podobnym problemem.

    Na zakończenie mam prośbę do wszystkich chętnych doradzenia mi zmiany programatora, języka w którym pisze aby darowali sobie tego typu posty  Szanuje ich wiedze i poglądy ale teraz nie mam czasu na dyskusje „co lepsze C czy BASCOM”, a jak czytam forum to zazwyczaj jeden, góra dwa posty po pytaniu, są na temat, potem ktoś rzuca hasło w stylu „spróbuj to napisać w C…” itp. I zaczyna się kilkunasto postowa dyskusja nie na główny temat : - ) .

    Pozdrawiam!
  • Poziom 17  
    Wrzucam tu procedurki którymi
    ja odzczytuję DS18B20 w asemblerze '51
    może się przydadzą :)
    Code:

    ;    /-----\
    ;   |-------|
    ;   |       |
    ;   |DS12B20|
    ;   |_______|
    ;    |  |  |
    ;   GND   Vdd
    ;      DQ
    ;

    PIN1W   EQU    P1.0
    ;=============================================================================
    ;  procedura odczytu temperatury z DS18B20
    ;-----------------------------------------------------------------------------
    ODCZYT_DS18B20:

       LCALL   W1RESET         ;reset magistrali
       MOV   A,#0CCH      ;polecenie pominięcia rozpoznawania adresu
       LCALL   W1RWBYTE
       
       MOV   A,#44H      ;start konwersji
       LCALL   W1RWBYTE

       MOV   A,#255       ;opóźnienie niezbędne dla wykonania konwersji
       LCALL   WAITMS          ;750ms
       MOV   A,#255
       LCALL   WAITMS
       MOV   A,#255
       LCALL   WAITMS
       
       LCALL   W1RESET         ;reset magistrali
       MOV   A,#0CCH      ;polecenie pominięcia rozpoznawania adresu
       LCALL   W1RWBYTE

       MOV   A,#0BEH      ;polecenie odczytu wyniku konwersji temperatury
       LCALL   W1RWBYTE

       
       ;odczyt bajtów z DS18B20  (tylko 2 pierwsze zawierają wynik pomiaru)
       MOV   A,#0FFH     
       LCALL   W1RWBYTE    ;odczyt pierwszego bajtu zawierającego wynik pomiaru
       MOV   BAJT1_LO,A  ;zmienna do przechowania odczytanego bajtu
       MOV   A,#0FFH
       LCALL   W1RWBYTE    ;odczyt drugiego bajtu zawierającego wynik pomiaru
       MOV   BAJT2_HI,A  ;zmienna do przechowania odczytanego bajtu
       LCALL   W1RESET

       RET                     
    ;--------------------------------------------------------------------

    ;=============================================================================
    ;      Procedura RESET magistrali 1wire
    ; zwraca C=0 jeżeli jest przynajmniej jeden układ podłączony do magistrali
    ; zwraca C=1 jeżeli nie było odpowiedzi (brak układu)
    ;-----------------------------------------------------------------------------
    W1RESET:         
       PUSH   B
            CLR   PIN1W
            MOV   B,#0
            DJNZ   B,$   ;opóźnienie B*2 mikrosekund (około 520us)
            SETB   PIN1W
            MOV   B,#30
            DJNZ   B,$   ;opóźnienie B*2 mikrosekund (około 65us)
            MOV   C,PIN1W ;odczyt stanu magistrali
              MOV   B,#0
            DJNZ   B,$   ;opóźnienie B*2 mikrosekund (około 520us)
            POP   B
            RET

    ;=============================================================================
    ;;odczyt/zapis bajtu
    ;(wchodzi w ACC bajt do zapisu / w ACC zwraca wartość odczytaną )
    ;-----------------------------------------------------------------------------

    W1RWBYTE:      
       PUSH   B
       MOV   B,#8
    A5F:
       RRC   A       ;wysuwa bity
       ACALL   W1RWBIT
       DJNZ   B,A5F
       RRC   A       ;na ich miejsce wsuwa bity odebrane
       POP   B
       RET
    W1RWBIT:      ;READ/WRITE BIT
       CLR   PIN1W           ;zbocze opadające na linii 1wire
       NOP
       MOV   PIN1W,C         ;master wystawia stan bitu do zapisu
       PUSH   B
       MOV   B,#5    ;opóźnienie B*2 mikrosekund (około 11us)
       DJNZ   B,$
       MOV   C,PIN1W         ;master odczytuje stan linii
       NOP

       MOV   B,#42H
       DJNZ   B,$
       POP   B
       SETB   PIN1W
       NOP
       NOP
       RET

    ;=============================================================================
    ;  opóźnienie
    ;-----------------------------------------------------------------------------
    WAITMS:      ;WAIT MILISECONDS (ACC=X)
       PUSH   ACC
    WAITMSL1:
       PUSH   ACC
       MOV   A,#226   ;229 + 229 -(2+2+1) [PUSH, POP, DJNZ]
       DJNZ   ACC,$
       MOV   A,#227
       DJNZ   ACC,$
       POP   ACC
       DJNZ   ACC,WAITMSL1
       POP   ACC
       RET
    ;-----------------------------------------------------------------------------

    powodzenia :)