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.

Pcf8583+Atmega8 i problem z odczytem roku

lejk 14 Wrz 2006 19:32 3787 13
  • #1 14 Wrz 2006 19:32
    lejk
    Poziom 15  

    Mam problem. Program pozwala wyświetlić tylko rok z przedziału 2000-2004. Jak zmodyfikować ten program żeby wyświetlić aktualny przedział lat. Dzięki za podpowiedzi.
    Ps.Szukałem i czytałem forum , wpisując do zmiennej Rok wartość od 00-04 zmieniamy lata od 2000 do 2004 ale nie znalazłem informacji co zrobić żeby zmienić przedział lat na np. 2004-2008 itd.

    Code:

    $regfile = "m8def.dat"                                     
    $crystal = 8000000

    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5
    I2cinit
    Config Sda = Portb.0
    Config Scl = Portb.1
    'Declare Sub Zapiszdate
    Declare Sub Odczytajdate
    Declare Sub Wysw

    ' Zmienne dla zegara RTC
    Dim Sekunda As Byte
    Dim Minuta As Byte
    Dim Godzina As Byte
    Dim Dzien As Byte
    Dim Miesiac As Byte
    Dim Rok As Byte
    Dim Dzientyg As Byte
    Dim Rokdzien As Byte
    Dim Tydzienmiesiac As Byte

    ' Adres zapisu to 162 a odczytu to 163 bo końcówka A0 jest podłączona do Vdd
    ' Sub Zapiszdate
     Godzina = 23
     Minuta = 43
     Sekunda = 0
     Dzien = 13
     Miesiac = 09
     Rok = 0

     Sekunda = Makebcd(sekunda)
     Minuta = Makebcd(minuta)
     Godzina = Makebcd(godzina)
     Dzien = Makebcd(dzien)
    Miesiac = Makebcd(miesiac)
     Rok = Rok * 64
     Rokdzien = Rok + Dzien
     Dzientyg = Dzientyg * 32
     Tydzienmiesiac = Dzientyg + Miesiac
     I2cstart
     I2cwbyte 162
     I2cwbyte 0                                                 ' Wybieram rejestr sterujący/stanu i zapisuję do niego wartość zero czyli inicjuję go
     I2cwbyte 0
     I2cstop
     I2cstart
     I2cwbyte 162
     I2cwbyte 2
     I2cwbyte Sekunda
     I2cwbyte Minuta
     I2cwbyte Godzina
     I2cwbyte Rokdzien
     I2cwbyte Tydzienmiesiac
     I2cstop
    ' End Sub
      Do
    'Call Zapiszdate
    Call Odczytajdate
    Call Wysw
    Loop
    '----------------------------------------------------------------------------

    ' Procedura odczytująca kompletną datę z PCF8583
    Sub Odczytajdate
     I2cstart
     I2cwbyte 162
     I2cwbyte 2
     I2cstart
     I2cwbyte 163
     I2crbyte Sekunda , Ack
     I2crbyte Minuta , Ack
     I2crbyte Godzina , Ack
     I2crbyte Rokdzien , Ack
     I2crbyte Tydzienmiesiac , Nack
     I2cstop

      Rok = Rokdzien
     Shift Rok , Right , 6
     Dzien = Rok
     Shift Dzien , Left , 6
     Dzien = Rokdzien - Dzien
    'Dzien = Makedec(dzien)
     Dzientyg = Tydzienmiesiac
     Shift Dzientyg , Right , 5
     Miesiac = Dzientyg
     Shift Miesiac , Left , 5
     Miesiac = Tydzienmiesiac - Miesiac
     'Miesiac = Makedec(miesiac)

    ' Usuwamy Dla Rejestru Godzin Dodatkowe Znaczniki Am / Pm I Trybu 12 / 24h
     Shift Godzina , Left , 2
     Shift Godzina , Right , 2
     'Godzina = Makedec(godzina)
     'Minuta = Makedec(minuta)
     'Sekunda = Makedec(sekunda)
     Waitms 950
    End Sub
    '-----------------

    Sub Wysw
    Cls
    Upperline
    Lcd Bcd(godzina) ; ":" ; Bcd(minuta) ; "." ; Bcd(sekunda)
    Lowerline
    Lcd Bcd(dzien) ; "-" ; Bcd(miesiac) ; "-" ; Bcd(rok)
    End Sub
    End
    [/quote]

    0 13
  • Pomocny post
    #2 14 Wrz 2006 19:50
    max_gg
    Poziom 26  

    PCF mierzy czas w cyklu czteroletnim (wartości od 0 do 3, gdzie zero to rok przestępny)
    I od programisty zależy, jak będzie to czytał i zapisywał...
    Musisz ustalić algorytm podziału roku w taki sposób, by np. rok 2007 odpowiadał wartości 3, a 2008 wartości 0. Wykorzystując wewnętrzny RAM tego ukłądu można przechowywać informację o roku - na wypadek zaniku zasilania...

    Jeżeli zrobisz to np. tak:

    Code:

    tmp_year = year - 2000
    tmp = tmp_year mod 4

    to otrzymasz wartość do wysłania do PCF-a

    Przy odczycie możesz już skorzystać z zapamiętanej wcześniej wartości roku...

    0
  • #3 14 Wrz 2006 20:41
    lejk
    Poziom 15  

    Dzieki za podpowiedź ale nie wiem jak mam to zastosować w tym programie
    . Czy mam wprowadzić dodatkowe zmienne czy zastąpić te które już są w programie.Jeśli będziesz miał cirpliwość żeby trochę bardziej łopatologicznie wytłumaczyć zagadnienie będę wdzięczny.

    0
  • Pomocny post
    #4 14 Wrz 2006 20:56
    max_gg
    Poziom 26  

    Nie, te zmienne co podałem to tylko przykład...
    Potrzebowałbyś jednej dodatkowej - tymczasowej, czyli tmp...
    Nie jestem teraz w stanie sprawdzić, ale mogłoby być tak:

    Code:

    tmp = Rok - 2000
    tmp = tmp mod 4 ' operator mod zwraca resztę z dzielenia przez 4,
                              'czyli jeśli byłby rok 2007, to 2007 - 2000 = 7-> 7 mod 4 = 3 ;)


    i w momencie zapisu roku do PCF-a wysyłasz wartość ze zmiennej tmp oraz dodatkowo do pamięci RAM układu (adresy powyżej &h0F) wpisujesz aktualny rok... A ten jest wpisany przez użytkownika...

    0
  • Pomocny post
    #5 14 Wrz 2006 22:32
    Jj_Johnys
    Poziom 21  

    Witam. Miałem ten sam problem gdy pierwszy raz użyłem PCF8583. I zrobiłem identycznie jak teraz radzi Max_gg, czyli właściwy rok zapisywałem w ramie PCF (btw. zawartośc ramu znika wraz z zasilaniem, trzeba zastosować podtrzymywanie bateryjne!), a do rejestru wpisywałem tylko końcówkę 0-3.

    Jednak nastał czas kiedy zadałem sobie pytanie: co jeśli urządzenie nie będzie włączane np. przez 5 lat?... Polecam to przemyśleć. I dodam tylko że w końcu wymieniłem ten układ PCF8563, pozdrawiam. JnS

    0
  • Pomocny post
    #6 14 Wrz 2006 23:03
    Electix
    Poziom 20  

    Siemka!

    A ja ten problem rozwiązałem inaczej. Generalnie to po co Ci pierwsza połowa 4 cyfrowej wartości roku. Wpisz jako stałą w programie 20 i tyle. Do dyspozycji zostanie Ci 99 lat. I teraz tak. W PCF8583 Możesz zapisać w rejestrze roku do 4 lat. Zatem robisz dzielenie całkowite aktualnego roku przez 4 i tą wartość zapisujesz w wolnej komórce pamięci PCF8583, natomiast resztę z dzielenia wpisujesz do rejestru roku PCF8583. Czyli jak mamy teraz 2006r. To 20 wywalasz, a 06 dzielisz przez 4, czyli wyjdzie Ci 1 mnożysz znow razy 4 i to wpisujesz do Ram. Reszta z dzielenia to 2 którą zapisujesz do rejestru roku. Gdy chcesz datę odczytać: odczytujesz wartość RAM, czyli w naszym przypadku 4 i dajesz 2 z rejestru roku i gotowe :)

    Code:

    dim Rp as byte 'poprawka do obliczenia roku
    dim Ro as byte 'rok

    Ro=6

    zapis:
    Rp = Ro \ 4
    Rp = Rp * 4
    Ro = Ro Mod 4
    Ro = Makebcd(ro)
    Rotate Ro , Left , 6 ' w tym miejscu masz wartość roku gotową do zsumowania z wartościa dnia miesiąca, po czym wpisujesz do PCF

    Czytaj:
    Ro = Ro - Dm  'oddzielenie wartosci roku po odczytaniu z PCF
    Rotate Ro , Left , 2
    Ro = Makedec(ro)
    Ro = Ro + Rp
    return


    To przykład jak to może wyglądać. Oczywiście musisz to zaadoptować to do reszty swojego programu. Bo tak na szybko powycinałem to z mojego programu dla przykładu.

    Powinno śmigać:)
    Miłej zabawy! :)

    0
  • #7 15 Wrz 2006 12:41
    max_gg
    Poziom 26  

    :arrow: Electix
    Nie wiem czy zauważyłeś, jaka ilość poleceń jest w podanym przeze mnie rozwiązaniu ;)

    Co do zapisu i odczytu, lepiej wykorzystać maskowanie do oddzielenia roku od dnia miesiąca... Czyli wyANDować potrzebną wartość i wtedy przesuwać...
    Tak samo sumowanie lepiej zrobić poleceniem OR, oczywiście po przesunięciuroku na odpowiednią pozycję...

    0
  • Pomocny post
    #8 15 Wrz 2006 19:37
    Electix
    Poziom 20  

    :arrow: max_gg
    Starałem się koledze Lejk krok po kroku wyjaśnić metodę, a w poście wyżej prosił o łopatologiczny opis. 8)

    Jeżeli chodzi o maskowanie, to można też je zrealizować w układzie zegara PCF8583 podczas odczytu danych z rejestrów 05H i 06H poprzez ustawienie bitu 3 w rejestrze kontrolnym 00H. Wtedy odczytamy samą datę i numer miesiąca, natomiast rok i dzień tygodnia będą przykryte zerami. :)

    0
  • #9 15 Wrz 2006 19:56
    Jj_Johnys
    Poziom 21  

    Wszystko pięknie, ślicznie. Ale ja nadal zwracam uwagę na to iż układ może nie być włączany przez 'x' lat (np. leżeć gdzieś w magazynie czekając na nabywcę). Sam PCF (podtrzymywany bateryjnie) liczy lata 0-3, resztę zapsujemy w jego ramie, ale tym już musi zająć się uC. I teraz jeśli urządzenie zostanie wyłączone np. na 5 lat PCF sobie zliczy do 3 i zacznie od zera. Skąd po włączeniu uC ma niby wiedzieć ile razy przewinął się licznik PCF?

    No, chyba że zależy nam na działaniu układu góra cztery lata - wtedy nie ma problemu. Inaczej trzeba albo zastosować inny układ RTC albo cały czas podtrzymywać uC, tak aby pilnował liczenie lat, pozdrawiam

    ,JnS[/youtube]

    0
  • #10 15 Wrz 2006 19:58
    lejk
    Poziom 15  

    Dziękuję wam bardzo wypróbuję obydwie metody. Nareszcie zrozumiałem o co chodzi . Pozdrawiam.

    0
  • #11 15 Wrz 2006 20:42
    Electix
    Poziom 20  

    Tak się zastanawiałem nad problemem przedstawionym przez Jj_Johnys i mam takie dwie odpowiedzi.

    W urządzeniach czasu rzeczywistego z reguły jest możliwość nastawienia aktualnej daty i czasu, więc rozstrzyganie o tym czy układ policzy te lata czy nie chyba raczej nie ma sensu, bo po uruchomieniu urządzenia czas można nastawić ponownie:) Jak kupujesz komórkę, czy płytę główną komputera, czy magnetowid i wyciągasz je z pudełka, czy nie ustawiasz aktualnego czasu i daty? Pozatym dochodzi jeszcze jedna kwestia. Po tych 5 latach leżenia, ta cała bateryjka podtrzymująca RTC raczej nie jest rześka, co może negatywnie wpływać na pracę układu i raczej nadaje się do wymiany...
    Załóżmy że bateryjka wytrzyma i zegarek liczy. Po takim czasie, liczony przez RTC czas, tak się rozjedzie w stosunku do rzeczywistego... uuuu
    Pozatym 2 razy do roku zmieniamy czas na zimowy/letni:)

    Układ PCF8583 jest za prosty do wykonywania takich funkcji samodzielnie i znakomicie nadaje sie do nie wymagających dokładności systemów czasu rzeczywistego, gdzie ich czas użytkowania z reguły nie jest przewidywana na więcej niż 3 lata.

    Jeżeli byśmy się jednak uparli na poprawne działanie tego sprzętu i to na PCF8583 w okresie długiego leżakowania w magazynie, to możemy ten problem rozwiązać inaczej.
    Mikrokontroler nie musi ciągle pracować może być "uśpiony" gdzie jego pobór energii w tym stanie jest bardzo niewielki. Nasz układ PCF8583 ma natomiast funkcję alarmu i wyjście Int co może służyć do wybudzania mikrokontrolera z "uśpienia" i ten zajmie się zaktualizowaniem odpowiednim daty w PCFie, po czym znów "uśnie". Pisząc odpowiednie procedurki możnaby wtedy zliczać płynące lata, a odpowiednio nastawiając alarmy zmieniać też czas letni/zimowy...
    Jeżeli chcemy uniknąć użycia mikrokontrolera, no to nie pozostaje nam nic innego jak tylko użyć bardziej zaawansowanego układu RTC. Firma Dallas-Maxim produkuje szereg bardzo rozbudowanych układów tego typu z wbudowanymi w ich strukturę rezonatorami kompensowanymi temperaturowo i czasowo. Układy te mogłyby sprostać postawionemu wyżej problemowi "leżakowania w magazynie" :)
    Dziękuję za uwagę i pozdrawiam :)

    0
  • #12 16 Wrz 2006 00:16
    Pavlik71
    Poziom 14  

    Problem "leżakowania" PCF-u to pikuś. Wystarczy, ze urządzenie, będzie wyłączone gdy nastanie 1 stycznia roku przestępnego.

    0
  • #13 16 Wrz 2006 00:59
    Electix
    Poziom 20  

    Nie zgodzę się z Tobą w pełni kolego Pavlik71. Nie koniecznie z rokiem przestępnym będzie problem, ponieważ PCF8583 uwzględnia lata przestępne w swoich licznikach. Jeżeli nawet nie będzie uwzględniana poprawka roku do zawartości rejestru roku, to zawsze po przepełnieniu licznika lat w PCFie zostanie uwzględniony rok przestępny:) Błąd wyniknie tylko z takiej sytuacji że PCF każdy co czwarty rok traktuje jako przestępny ( w większości przypadków to jest wystarczające ) ale niestety nie każdy co czwarty rok jest rokiem przestępnym:) bo rok przestępny to taki który jest podzielny przez 4, ale nie jest podzielny przez 100, lub jest podzielny przez 400. Np rok 1896 był rokiem przestępnym bo 1896/4=474 i 1896/100=18,96 , natomiast 4 lata później 1900r już przestępnym nie był bo 1900/4 = 475 i 1900/100=19 oraz 1900/400=4,75 natomiast rok 2000 był rokiem przestępnym bo pomimo iż dzieli się i przez 4 i przez 100 to też dzieli się przez 400. :)

    To Jako ciekawostka:)

    0
  • #14 16 Wrz 2006 04:20
    Andy74
    Poziom 24  

    Witam!

    Electix napisał:
    Nie koniecznie z rokiem przestępnym będzie problem, ponieważ PCF8583 uwzględnia lata przestępne w swoich licznikach. Jeżeli nawet nie będzie uwzględniana poprawka roku do zawartości rejestru roku, to zawsze po przepełnieniu licznika lat w PCFie zostanie uwzględniony rok przestępny


    A moim zdaniem koledze Pavlik71 nie chodziło o to, czy rok zostanie uwzględniony jako przestępny, czy też nie, a o to że jeśli wyłączymy zasilanie procesora 31 grudnia roku - powiedzmy - 2007, i włączymy 1 stycznia 2008, to stan rejestru roku w PCF-ie zmieni się z 3 na 0. Ponieważ procesor nie był zasilany, to nie wie, że teraz jako rok "0" należy traktować 2008 i data zmieni się nam z 31 grudnia 2007 na 1 stycznia 2004... (weź pod uwagę, że PCF zlicza lata od 0 do 3 i każdy rok "zerowy" jest traktowany jako przestępny). Uff... Starałem się to wytłumaczyć obrazowo, a wyszło jak wyszło :)

    Co do drugiej części Twojej wypowiedzi, to najbliższy taki przestępno/nieprzestępny rok będzie 2100, więc problem raczej nas nie dotyczy - przyznasz chyba... ;)

    Wracając do tematu obliczania roku:
    Mamy przecież do dyspozycji RAM PCF-a. Można na przykład podczas ustawiania daty i za każdym razem w pierwszej sekundzie nowego roku zapisywać tą samą wartość która znajdzie się w rejestrze roku - do wolnej (dowolnej :)) komórki RAM-u (oczywiście pomijając bity dnia miesiąca, czyli liczbę od 0 do 3). Teraz po każdym włączeniu głównego zasilania porównujemy te wartości. Jeśli w RAM-ie jest większa niż w rejestrze lat PCF-a, to przechodzimy do procedury korekcji naszego mnożnika roku (zwiększamy go o 1), po czym aktualizujemy zawartość komórki RAM-u.

    Wykombinowałem sobie to podczas pracy nad ostatnim "wynalazkiem". Jeśli widzicie jakiś błąd w moim rozumowaniu, to dajcie znać. Mam układ jeszcze na warsztacie i mogę coś poprawić w programie w razie potrzeby - to do tych, co zrozumieli cokolwiek z moich mętnych wywodów :)

    W ten sposób można się zabezpieczyć przed błędami przy pracy bez głównego zasilania do 3 lat, niezależnie czy był w tym czasie rok przestępny, czy też nie. To według mnie w zupełności wystarczy, bo przy baterii podtrzymującej, której użyłem, i która jest często stosowana w tym układzie (CR2032) o pojemności ok. 230mAh i poborze prądu przez PCF-a ok. 12µA (zmierzone dla mojego egzemplarza - w/g dokumentacji dla 3V może być do 30µA) zegar ma szansę "chodzić" trochę ponad 2 lata na zasilaniu bateryjnym...

    Pomijam tu sprawę dokładności naszego zegara - mnie udało się osiągnąć ±4 sek. na tydzień przy standardowym kwarcu zegarkowym, co uznałem za wynik bardzo dobry...

    Pozdrawiam
    Andy

    0
  Szukaj w 5mln produktów