Przy okazji jednego z ostatnich projektów zmuszony byłem rozszerzyć swoje funkcje obsługi RTC PCF8583 o obsługę daty. Jak wiadomo zawsze w tym PCF są problemy z obsługą dnia tygodnia i roku. Ja zrealizowałem to tak:

uint8_t yearTemp1,yearTemp2,firstRun;
//------------------------------------------------
void odczytajRTC(uint8_t *hours, uint8_t *minutes, uint8_t *seconds,uint8_t *day, uint8_t *month, uint8_t *year, uint8_t *wday)
{
 TWI_read_buf( PCF8583_ADDR, 0x1f, 1, i2c_buffer );
 *year=i2c_buffer[0];

 TWI_read_buf( PCF8583_ADDR, 0x02, 5, i2c_buffer );
 yearTemp2=yearTemp1;
 (*seconds) = bcd2dec( (i2c_buffer[ss] ));
 (*minutes) = bcd2dec( (i2c_buffer[mm] ));
 (*hours) = bcd2dec( (i2c_buffer[hh] ));
 (*day) = bcd2dec( (i2c_buffer[yearDate] )& 0x3F);
 (yearTemp1) = bcd2dec( i2c_buffer[yearDate]>>6);
 (*month) = bcd2dec( (i2c_buffer[wdaysMonths] )& 0x1F);
 //obsługa roku
 if((yearTemp1!=yearTemp2)&& (firstRun))
 {
 i2c_buffer[0]=(*year);
 i2c_buffer[0]++;
 TWI_write_buf( PCF8583_ADDR, 0x1f, 1, i2c_buffer );
 }
 firstRun=1;
 TWI_read_buf( PCF8583_ADDR, 0x1f, 1, i2c_buffer );
 *year=i2c_buffer[0];
/*
 * wyznaczenie dnia tygodnia z wykorzystaniem wzoru Zellera na kalendarz wieczny.
 * Algorytm matematyka Mike'a Keith'a.
 */
 int y,m,d;
 y=2000+(*year);
 m=(*month); d=(*day);
 (*wday)=((d+=m<3?y--:y-2,23*m/9+(d-1)+4+y/4-y/100+y/400)%7)+1;

 return;
}
void zapiszRTC(uint8_t hours, uint8_t minutes, uint8_t seconds,uint8_t day, uint8_t month, uint8_t year, uint8_t wday)
{
 i2c_buffer[ss] = dec2bcd((0)); // sekundy
 i2c_buffer[mm] = dec2bcd((minutes)); // minuty
 i2c_buffer[hh] = dec2bcd((hours)); // godziny
 i2c_buffer[wdaysMonths] = (dec2bcd((wday-1))<<5)|dec2bcd(month);
 i2c_buffer[yearDate] = (dec2bcd(yearTemp1)<<6)|dec2bcd(day);
 TWI_write_buf( PCF8583_ADDR, 0x02, 5, i2c_buffer );
 i2c_buffer[0] = year;
 TWI_write_buf( PCF8583_ADDR, 0x1f, 1, i2c_buffer );
 return;
}

Nie umieszczam tu kodów obsługi samego i2c dla AVR ponieważ w większości pochodzą one z netu i są ogólnodostępne.
Założenie było takie, że wartość roku (np. 12 dla 2012) przechowuję w pamięci RAM pcfa, natomiast zmianę roku (podczas normalnego odliczania czasu) dokonuję przez odczytywanie wartosci roku (0-3) z rejestru roku pcfa.
Z kolei numer dnia tygodnia zrealizowany jest całkowicie z pominięciem pcfa - wykorzystałem tu algorytm wiecznego kalendarza Zellera.

Od razu mówię: specjalnie co sekundę odczytuję z PCFa czas i datę - chcę eksperymentalnie stwierdzić jak będzie to wpływać na jego pracę. Oczywiście nic nie stoi na przeszkodzie, aby z tego kodu zrobić 2 niezależne funkcje lub obecną funkcję edytować o dodatkowy parametr definiujący zapis / odczyt konkretnie tylko czasu lub tylko daty.

Polecam również zapoznanie się z bardzo ciekawym opisem obsługi PCF8583 na forum elektroda.pl

 

UWAGA!!!

Dzięki zaangażowaniu jednego z Użytkowników udało się wychwycić błąd w kodzie niskopoziomowej obsługi i2c - błąd dotyczy wystawiania na magistralę sygnału STOP. Zasadniczo wszystko działa OK (przynajmniej w moich kodach) dlatego, że zapisy/odczyty po i2c nie są (u mnie) przeprowadzane w sposób ciągły. Tzn. jednorazowo zapisywany/odczytywany jest cały bufor a na koniec operacji powinien być wystawiony poprawny stop. Ponieważ operacje wykonywane są rzadko, więc nic się nie dzieje, bo z kolejną transmisją nie wstrzelamy się w moment w którym stop jest jeszcze wystawiany.
Problem pojawiłby się, gdybyśmy robili non stop zapytania do układu - wtedy na 99% wystąpiłyby przekłamania. Na swoje usprawiedliwienie mam tylko to, że nie ja jestem autorem kodu nispoziomowej obsługi magistrali, z którego korzystam. Stąd przeoczenie. Obecnie na stronie znajdują się już poprawione kody obsługi.

Serdeczne podziękowania za nadesłane info dla Krzystofa Ruszel.

Do pobrania:

Użyj opcji uploadu plików, aby przekazać mi kod do sprawdzenia. Postaram się zajrzeć do niego tak szybko jak będzie to możliwe. Paczkę z poprawionym kodem umieszczę w tym samym miejscu.

 

 

Jeżeli wystąpi sytuacja, w której zostanie wyświetlona zawartość folderu z innego działu - należy wyczyścić cache przeglądarki! Następnie przeładować stronę.

Komentarze  

 
# CharlesCharles 2016-11-24 07:45
Hey are using WordPress for your blog platform? I'm new to the blog world but I'm trying to get started and set up my own. Do you require any coding knowledge to make your own blog? Any help would be really appreciated!
Odpowiedz | Odpowiedz z cytatem | Cytować
 

Licznik odwiedzin

Mapa odwiedzin



 

Copyright © ST WebSite 2017

Stronę hostuje FutureHost. []

Strona korzysta z plików cookie. Dane przechowywane na Twoim komputerze służą wyłą…cznie do poprawienia funkcjonalnoś›ci witryny. Jeżeli tego nie akceptujesz - powinieneś› ją… opuś›cić‡.

Akceptujesz ciasteczka z tej witryny?