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

Atmega32 i PCF8583 - błędny odczyt czasu, wyświetla 165:165:165. Co poprawić?

sliver1 25 Gru 2006 12:53 3536 13
REKLAMA
  • #1 3368087
    sliver1
    Poziom 22  
    Posty: 870
    Pomógł: 2
    Ocena: 122
    Zrobilem ukladzik na atmedze32 i Pcf8583 Philipsa i mam problem z odczytem zegarka - zamiast godzin, minut i sekund widze na wyswietlaczu cyfry 165 - 165:165:165. Czy cos mam nie tak w kodzie??

    Kod odpowiedzialny za wyswietlanie godziny:
    
        If Item = 8 Then
                Gosub Clock
                Cls
                Lcd G_str ; ":" ; M_str ; ":" ; S_str
         End If
    


    Procedura odczytu daty i czasu:
    
    Clock:
      I2cstart
      I2cwbyte &HD0
      I2cwbyte 0
      I2cstart
      I2cwbyte &HD1
      I2crbyte S , Ack
      I2crbyte M , Ack
      I2crbyte G , Ack
      I2crbyte Weekday , Ack
      I2crbyte Dni , Ack
      I2crbyte Miesiace , Ack
      I2crbyte Rok , Nack
      I2cstop
      S = Makedec(s) : M = Makedec(m) : G = Makedec(g)
      Dni = Makedec(dni) : Miesiace = Makedec(miesiace) : Rok = Makedec(rok)
      S_str = Str(s) : M_str = Str(m) : G_str = Str(g)
      Dni_str = Str(dni) : Miesiace_str = Str(miesiace) : Rok_str = Str(rok)
      S_str = Format(s_str , "00") : M_str = Format(m_str , "00") : G_str = Format(g_str , "00")
      Dni_str = Format(dni_str , "00") : Miesiace_str = Format(miesiace_str , "00") : Rok_str = Format(rok_str , "00")
    
    Return
    


    Druga opcja jest jeszcze taka, ze w elektroniku dali mi zly kwarc - prosilem zegarkowy 32768Hz a dostalem taki z oznaczeniem "KDS7B" - sprzedawca twierdzil, ze to ten...
  • REKLAMA
  • #2 3368107
    karlos79
    Poziom 33  
    Posty: 1768
    Pomógł: 254
    Ocena: 76
    Witam
    Doczytaj w nocie o adresowaniu tego układu, bo coś mi się wydaje że masz adres nie taki.
    Pozdrawiam
  • REKLAMA
  • #3 3368380
    Andy74
    Poziom 25  
    Posty: 525
    Pomógł: 103
    Ocena: 24
    Witam
    Twój program z całą pewnością nie zadziała z PCF8583, bo nie dla niego został napisany. Po pierwsze (jak słusznie zauważył Kolega karlos79) zły adres układu - PCF ma &HA0 do zapisu i &HA1 do odczytu. Po drugie jego rejestry daty i czasu nie zgadzają się z tymi które Ty odczytujesz.

    Natomiast sądząc po adresie układu i rozkładzie rejestrów, program pasuje mi do zegara DS1307 od MAXIM-a.

    Co do kwarcu, to trudno wyrokować na 100% według oznaczenia, ale z tego co znalazłem, to jest on na 38.2294 KHz :(

    Wesołego świętowania :x-mas:
    Andy
  • #4 3368407
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    czasem na tych kwarcach zegarkowych nie ma oznaczeń w postaci częstotliwości ;) tylko własnie takie jakie masz na swoim zakupionym, wątpię żeby kwarc był zły ;) - i napewno do tego scalaka jest kwarc 32.768kHz (dokładnie wg noty) a nie żaden inny

    jak słusznie zauważyli koledzy wyżej napewno źle adresujesz ten układ bo on może mieć adres albo A0 albo A1 w zależności od tego czy wejście A0-nóżka 3 scalaka będzie podłączona do masy czy do +5V

    ... więc tu troszeczkę się chyba kolega Andy74 pomylił niechcąco - bo odczyt i zapis do tego układu realizujemy przez jeden i ten sam adres w zależności jaki ustawimy (ale zapewne miał rację co do tego że może to program dla DS'a )
  • #5 3368487
    Andy74
    Poziom 25  
    Posty: 525
    Pomógł: 103
    Ocena: 24
    Co do kwarcu to oczywiście nie będę polemizował - tym bardziej że trudno znaleźć jakieś konkrety nt. tego oznaczenia. Sprawa się wyjaśni gdy kolega sliver1 uruchomi zegar... :)

    Nie zgodzę się jednak jakoby:
    Cytat:
    ...odczyt i zapis do tego układu realizujemy przez jeden i ten sam adres w zależności jaki ustawimy...

    Oto rejestr adresu PCF-a:
    Atmega32 i PCF8583 - błędny odczyt czasu, wyświetla 165:165:165. Co poprawić?

    Układ ma oddzielne adresy do zapisu i do odczytu. Jeśli pin oznaczony A0 jest podłączony do masy to adresujemy A0 (160) do zapisu; A1 (161) do odczytu. Jeśli podłączymy go do Vcc to mamy analogicznie adresy A2 (162) i A3 (163).

    Korzystałem z tego układu nie raz, więc wiem co piszę ;)

    Pozdrawiam
    Andy
  • REKLAMA
  • #6 3368527
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    ... kolego Andy64 - ja nie żebym chciał się kłócić czy też żeby ci zarzucać niewiedzę, ale właśnie wczoraj pierwszy raz uruchomiłem sobie ten zegarek (Atmega8 i PCF8583) - program piszę w asemblerze, zrobiłem sobie programowy I2C, nóżkę A0 mam podłączoną do masy i .... gdy chcę coś zapisać czy też odczytać z układu to ustawiam adres SLAVE układu na A0 właśnie ;)

    Dodano po 2 [minuty]:

    aaaaa już rozumiem nasze nieporozumienie ;) .... oczywiście ty też masz rację, po prostu do adresu zaliczyłeś bit nr0 mówiący o tym czy robimy operację zapisu W\ lub odczytu R - wtedy tak jak piszesz będzie taki efekt... ja po prostu rozdzielam w swoich przemyśleniach ten bit 0 ;) od adresu SLAVE całego układu
  • REKLAMA
  • #7 3368621
    Andy74
    Poziom 25  
    Posty: 525
    Pomógł: 103
    Ocena: 24
    No to cieszę się, że sprawa się wyjaśniła :)
    Ja traktuję adres jako całość z bitem kierunku, bo jest to zawarte w jednym rejestrze PCF-a. W tej chwili też mam na warsztacie dość rozbudowany projekt z M32 i między innymi PCF-em.

    Ja też nie miałem najmniejszego zamiaru się kłócić, czy też obrażać kogokolwiek :) Jeśli odebrałeś moją wypowiedź inaczej - to przepraszam.

    Swoją drogą, ciekawe co na to kolega sliver1, bo my tu sobie gadu-gadu, a on nam zamilkł... Czyżby zmęczony świętowaniem? ;)

    Pozdrawiam
    Andy
  • #8 3368672
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    ... nie, spokojnie ja nie poczułem się urażony ;) dopiero uczę się tego co ty jak widzę już "trzskasz" na codzień ... zawsze czegoś nowego się człowiek dowie tu na forum .... mam też nadzieję, że przez tę dogłębną naszą analizę też i koledze silver1 powinno się rozjaśnić juz na maxa

    pozdrówka
  • #9 3369672
    sliver1
    Poziom 22  
    Posty: 870
    Pomógł: 2
    Ocena: 122
    hej koledzy!!! juz jestem:)
    wielkie dzieki za pomoc - czesciowo juz zegar dziala, mieliscie racje!! zmienilem w kodzie odczytu HD na HA i dziala odczyt
    
    ' -------------------- Procedura odczytu czasu i daty --------------------
    Clock:
      I2cstart
      I2cwbyte &HA0                             ' zmienilem z HD0 na HA0
      I2cwbyte 2
      I2cstart
      I2cwbyte &HA1                             ' zmienilem z HD0 na HA1
      I2crbyte S , Ack
      I2crbyte M , Ack
      I2crbyte G , Ack
      I2crbyte Weekday , Ack
      I2crbyte Dni , Ack
      I2crbyte Miesiace , Ack
      I2crbyte Rok , Nack
      I2cstop
      S = Makedec(s) : M = Makedec(m) : G = Makedec(g)
      Dni = Makedec(dni) : Miesiace = Makedec(miesiace) : Rok = Makedec(rok)
      S_str = Str(s) : M_str = Str(m) : G_str = Str(g)
      Dni_str = Str(dni) : Miesiace_str = Str(miesiace) : Rok_str = Str(rok)
      S_str = Format(s_str , "00") : M_str = Format(m_str , "00") : G_str = Format(g_str , "00")
      Dni_str = Format(dni_str , "00") : Miesiace_str = Format(miesiace_str , "00") : Rok_str = Format(rok_str , "00")
    
    Return
    


    godzina i data wyswietla sie z tym, ze nie moge jej ustawiac, data caly czas jest taka: 01-00-00 a z godziny robia sie jakies krzaki typu 83:12'22.

    mam problemy z jej ustawieniem, zapewne znowu jest cos nie tak z adresowaniem zapisu i odczytu.
    koncowka kodu ustawiania daty i godz wyglada tak:(patrz ponizej) co musze w niej zmienic aby wszystko dzialalo??

    
    
      Dni = Makebcd(dni) : Miesiace = Makebcd(miesiace) : Rok = Makebcd(rok)
      I2cstart
      I2cwbyte &HA0
      I2cwbyte 4                                                'bylo 4
      I2cwbyte Dni
      I2cwbyte Miesiace
      I2cwbyte Rok
      I2cstop
    
    
      S = Makebcd(s) : M = Makebcd(m) : G = Makebcd(g)
      I2cstart
      I2cwbyte &HA0
      I2cwbyte 0                                                ' bylo 0
      I2cwbyte S
      I2cwbyte M
      I2cwbyte G
      I2cstop
    
      Cls
      Return
    


    na pocztaku kodu jest taka linijka:
    $lib "ds1307clock.lib" ' modified lib
    jak zapewne powinna byc chyba inna jesli jest zastosowany pcf8583. tylko jaka??
  • #10 3370053
    Andy74
    Poziom 25  
    Posty: 525
    Pomógł: 103
    Ocena: 24
    Witam ponownie!

    Tak na pierwszy rzut oka widać kilka błędów, ale nie mam już dziś siły się rozpisywać... ;)

    Dam Ci za to coś takiego: >KLIKNIJ< I jeszcze to: >KLIKNIJ< Pliki zawierają opis PCF-a po polsku. Poszukaj też na forum - na temat tego scalaka było tu już bardzo dużo.

    DS1307 jest prostszy w obsłudze od PCF8583 (co nie znaczy, że ten drugi jest trudny :) ) i ma trochę inaczej rozmieszczone rejestry czasu. Nie możesz się więc bezpośrednio wzorować na tym programie który masz.
    W PCF-ie nie ma na przykład osobnych rejestrów roku i dnia tygodnia. Rok zapisuje/odczytuje się w jednym bajcie razem z dniem miesiąca, a dzień tygodnia z miesiącem.
    W komórce o numerze 0 znajduje się w PCF-ie rejestr kontrolny sterujący pracą układu (zwróć uwagę gdzie rozpoczynasz zapis podczas ustawiania zegara - sekundy są pod numerem 2...).

    Uff... a jednak się rozpisałem :)
    Więcej informacji (a właściwie wszystkie potrzebne) znajdziesz w załączonych plikach. Gdybyś miał jednak pytania - pisz.
    Postaram się odezwać jutro (znaczy dzisiaj...).

    A! Tą linijkę: >$lib "ds1307clock.lib" ' modified lib< możesz zwyczajnie usunąć.

    Pozdrawiam i powodzenia!
    Andy
  • #11 3370772
    sliver1
    Poziom 22  
    Posty: 870
    Pomógł: 2
    Ocena: 122
    Andy74 napisał:

    Tak na pierwszy rzut oka widać kilka błędów, ale nie mam już dziś siły się rozpisywać... ;)


    probowalem sam poradzic sobie z tym problemem ale jednak moja wiedza jest jeszcze zbyt uboga w tej materii - bascomem bawie sie od tygodnia dopiero:P
    moglbys mi konkretnie napisac co nalezy zmienic??

    w kodzie odpowiadajacym za zapis zmienilem dwie linijki ale nadal jest cos nie tak, tzn. zegar dzial poprawnie i mozna go ustawiac ale data zawsze jest taka sama - nie mozna jej zmienic.
    
     Dni = Makebcd(dni) : Miesiace = Makebcd(miesiace) : Rok = Makebcd(rok)
      I2cstart
      I2cwbyte &HA0
      I2cwbyte 0                                                   'dodalem ta linijke
      I2cwbyte 2                                                   'wpisalem 2 a bylo 4
      I2cwbyte Dni
      I2cwbyte Miesiace
      I2cwbyte Rok
      I2cstop
    
    
      S = Makebcd(s) : M = Makebcd(m) : G = Makebcd(g)
      I2cstart
      I2cwbyte &HA0
      I2cwbyte 2                                                ' bylo 0
      I2cwbyte S
      I2cwbyte M
      I2cwbyte G
      I2cstop
    
      Cls
      Return


    Dodano po 2 [godziny] 50 [minuty]:

    juz prawie sie udalo:P
    okazalo sie, ze kod odpowiedzialny za zapis daty jest trefny, zmnienilem w nim pare rzeczy i wyglada teraz tak:
    
      Dni = Makebcd(dni) : Miesiace = Makebcd(miesiace) : Rok = Makebcd(rok)
      I2cstart
      I2cwbyte &HA0
      I2cwbyte 0
      I2cwbyte 8
      I2cstop                                       'dodalem to
      I2cstart                                      'dodalem to
      I2cwbyte &HA0                           'dodalem to
      I2cwbyte 5                                 'dodalem to, dziala jak wpisuje 5tke
      I2cwbyte Dni
      I2cwbyte Miesiace
      I2cwbyte Rok
      I2cstop

    i juz prawie dziala - mozna ustawiac date i zostaje ona zapamietana, problem jest tylko taki, ze rok maxymalnie wyswietla sie 25 mimo ze powinno dojsc do 99r.
    moglby mi ktos napisac od czego jest linijka "I2cwbyte 5" i jaka prawidlow powinna byc cyfra?? probowalem z 0, 2, 3, 4, 5, 8 - wyswietlaja sie krzaki, dzial tylko z 5tka ale sa wtedy z ustawieniem wiekszego roku niz 25 mimo, ze jest zadekladowane do 99...
  • #12 3371568
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    sliver1 napisał:
    ...i juz prawie dziala - mozna ustawiac date i zostaje ona zapamietana, problem jest tylko taki, ze rok maxymalnie wyswietla sie 25 mimo ze powinno dojsc do 99r...

    Zajrzyj łaskawie do dokumentacji PCF-a , bo to co tu wypisujesz ... woła o pomstę do nieba :(
    Dlaczego zmienną Rok wpisujesz do rejestru timera :?:
    Po co maskujesz rejestry 4 i 5 :?:
    Czy wiesz , że rok zapisany jest tylko na 2 bitach , w rejestrze nr.5 , razem z dziesiątkami i jednościami dnia miesiąca :?:
    Wątpię :(
    Nie zgaduj , zajrzyj do dokumentacji :D

    Piotrek
  • #13 3371639
    Andy74
    Poziom 25  
    Posty: 525
    Pomógł: 103
    Ocena: 24
    Na początek takie pytanie: Czy przeglądałeś te pliki które zamieściłem w poprzednim poście? Tam jest ładnie wyjaśnione o co chodzi z tym rokiem.

    Nie możesz ustawić w PCF-ie roku większego niż 3 z uwagi na fakt, że jest on zapisywany tylko w dwóch najstarszych bitach rejestru dni miesiąca. Skoro to tylko dwa bity, to może on się zmieniać w zakresie od 0 do 3, przy czym każdy 0 jest traktowany jako przestępny (czyli luty będzie miał 29 dni). Dlatego napisałem że PCF jest trudniejszy w obsłudze. Obsługa wyświetlania/zapisywania roku wymaga dodatkowych obliczeń w programie. Podobnie ma się sprawa z dniem tygodnia, z tym, że jest on z kolei umieszczony w trzech najstarszych bitach rejestru miesięcy i może przyjmować wartość od 0 do 6.
    Ale możesz sobie (na początek) uprościć sprawę jeśli nie będziesz korzystał z odczytu roku i dnia tygodnia. Wystarczy odpowiednio ustawić rejestr kontrolny (pod adresem 0) i wtedy bity odpowiedzialne za te dwie wartości będą maskowane przy odczycie.

    Przykład:
    'Zapis:
    
       S = Makebcd(s) : M = Makebcd(m) : G = Makebcd(g)
       Dni = Makebcd(dni) : Miesiace = Makebcd(miesiace)       ' : Rok = Makebcd(rok)
    
    
       I2cstart                   'rozpoczęcie transmisji
       I2cwbyte &HA0              'ustawienie trybu zapisu
       I2cwbyte 0                 'wybranie zapisu do rejestru kontrolnego
       I2cwbyte &B00001000        'ustawienie rejestru kontrolnego - zegar uruchomiony, maskowanie włączone
       I2cwbyte 0                 'zerowanie setnych sekundy
       I2cwbyte S                 'zapis sekund
       I2cwbyte M                 'zapis minut
       I2cwbyte G                 'zapis godzin
       I2cwbyte Dni               'zapis dnia miesiąca
       I2cwbyte Miesiace          'zapis miesiąca
       I2cstop                    'koniec transmisji
    
    'Odczyt:
    
       I2cstart                   'inicjalizacja magistrali I2C
       I2cwbyte &HA0              'podanie adresu podstawowego PCF8583
       I2cwbyte 2                 'wybranie drugiego rejestru (sekund)
       I2cstart                   'start transmisji
       I2cwbyte &HA1              'zgłoszenie zamiaru odczytu informacji
       I2crbyte S , Ack           'odczyt Rejestru Sekund (z potwierdzeniem - Ack)
       I2crbyte M , Ack           'odczyt rejestru minut (z potwierdzeniem - Ack)
       I2crbyte G , Ack           'odczyt rejestru godzin (tryb 24h) (z potwierdzeniem - Ack)
       I2crbyte Dni , Ack         'odczyt dnia miesiąca (z potwierdzeniem - Ack)
       I2crbyte Miesiace , Nack   'odczyt miesiąca (bez potwierdzenia - Nack)
       I2cstop                    'zatrzymanie transmisji
    
    'Wyświetlanie:
    
       Lcd Bcd(g) ; ":" ; Bcd(m) ; ":" ; Bcd(s)
       Lowerline
       Lcd Bcd(dni) ; "/" ; Bcd(miesiace)
    

    Jak widzisz do prawidłowego wyświetlenia daty/godziny nie musisz jej mozolnie przeliczać na postać dziesiętną, zamieniać na string, po czym formatować - wystarczy użyć funkcji bcd() przy wyświetlaniu. Oczywiście to nie jest gotowy, działający program - odpowiednie jego części musisz powstawiać do swoich podprogramów.
    Gdy opanujesz to co podałem będziemy działać dalej ;)

    Pozdrawiam
    Andy

    edit: Trochę mi zajęło czasu pisanie tego posta i Kolega Zumek wypowiedział się w międzyczasie (żeby nie było że powtarzam to co napisał ;)). Celowo nie dawałem dotąd żadnych gotowców, by zmusić naszego początkującego Kolegę do samodzielnej pracy. Trudno przepisywać tutaj dokumentację układu scalonego, ale rozumiem, że początki nie są łatwe, a gdy ktoś naprowadzi na odpowiedni tok rozumowania - wszystko staje się jasne.
  • #14 3373691
    sliver1
    Poziom 22  
    Posty: 870
    Pomógł: 2
    Ocena: 122
    Zastosowalem sie do twoich porad "Andy74", zegar z data dziala ale potrzebuje jeszcze wskazan roku.
    Zamiast &B00001000 wpisalem 8 bo wg. tego co jest w dokumentacji wtedy mozliwy powinnien byc odczyt roku(tak mi sie wydaje) ale u mnie jakos to nie dziala i np. luty ma podczas ustawiania tyle co inne miesiace czyli 31 dni.. Jak zrobic aby automatycznie program wiedzial, ile dni ma kazdy miesiac??

Podsumowanie tematu

✨ Problem dotyczył błędnego odczytu czasu z układu PCF8583 podłączonego do Atmegi32, gdzie na wyświetlaczu pojawiały się wartości 165:165:165 zamiast prawidłowych godzin, minut i sekund. Przyczyną był nieprawidłowy adres I2C używany w kodzie – zamiast &HD0 i &HD1 należało stosować &HA0 (zapis) i &HA1 (odczyt), co wynika z dokumentacji PCF8583 i konfiguracji pinu A0. Ponadto, rejestry daty i czasu w PCF8583 różnią się od innych popularnych układów, np. DS1307, dlatego kod napisany dla DS1307 nie działa poprawnie z PCF8583. W PCF8583 rok jest zapisywany tylko na dwóch bitach w rejestrze dni miesiąca, a dzień tygodnia w trzech bitach rejestru miesięcy, co wymaga specjalnej obsługi w oprogramowaniu. Ustawianie i odczyt daty wymaga uwzględnienia tych specyfik i odpowiedniego maskowania bitów. Po poprawieniu adresów i dostosowaniu kodu do specyfiki PCF8583 zegar zaczął działać poprawnie, jednak pojawiły się dalsze pytania dotyczące automatycznego rozpoznawania liczby dni w miesiącach oraz prawidłowego odczytu roku i obsługi lat przestępnych. Dyskusja podkreśliła konieczność dokładnego zapoznania się z dokumentacją układu oraz różnice w protokole i rejestrach między PCF8583 a innymi RTC.
Wygenerowane przez model językowy.
REKLAMA