[116] RTC - układy czasu rzeczywistego cz. 1
![[116] RTC - układy czasu rzeczywistego cz. 1](/_next/image?url=https%3A%2F%2Farduino.pl%2Fimgproxy%2FlALBfToZUtvE_zOU41jj0pko2Ecg9RAW3j9gIgIaMAA%2Ff%3Awebp%2Fw%3A1200%2FbG9jYWw6Ly8vaW1hZ2VzLzAtNjg1L2FmOGJhL2FjMWZlLzAtNjg1YWY4YmFhYzFmZTQ4ODkwNTQ3NS5wbmc%3D.webp&w=3840&q=75)
Czas najwyższy zająć się tak zwanymi zegarami RTC. O czym mowa? Do tej pory źródłem czasu w moich przykładach było samo Arduino i źródło to miało dwie wady: nie było zbyt dokładne i jak brakło prądu, to ustawienia zegara przepadały. Profesjonalnie robi się to inaczej.
RTC czyli Real Time Clock to układ scalony zaprojektowany tylko do jednego celu: bycia dokładnym zegarkiem, z własnym zasilaniem, zegarkiem tak oszczędnym, by wymiana baterii była konieczna jak najrzadziej. W praktyce baterie wystarczają na kilka lat i bardziej rozładowują się same z siebie niż z powodu podłączenia do obwodów zegara.
Układy RTC mają zwykle bardzo niewielkie możliwości poza byciem zegarem i najczęściej dysponują dodatkowo kilkudziesięcioma gratisowymi bajtami do własnego zagospodarowania, których stan jest pamiętany dzięki bateryjce. W praktyce układy takie mają formę płytki z obsadką na baterię litową, zwykle 2032, ale zdarzają się mniejsze. Swego czasu jakiś diabeł wymyślił wersje, w których bateria znajdowała się wewnątrz przerośniętej obudowy. Takie zegary siedziały często w płytach głównych w czasach pierwszych Pentium. Problem w tym, że jednak w końcu baterie te wyczerpały się i jedyną metodą naprawy układu jest jego rozwiercenie, odłączenie martwego ogniwa – za pomocą miniaturowej szlifierki i podłączenie baterii z zewnątrz.

Jedna z płyt z wczesnym Pentium przeszła u mnie udaną operację i służy mi w retro eksperymentach. Dziś jednak używa się nowocześniejszych układów, najczęściej z którymś ze współczesnych interfejsów. Wybrałem sobie dwie kostki i nimi teraz się zajmiemy.

Oto układ DS1302 wraz z towarzyszącym koszyczkiem na pastylkową baterię litową. Na płytce znajdziemy jeszcze typowy kwarc zegarkowy o częstotliwości 32768 Hz, czyli 2 do potęgi 15. Dlaczego tyle? To, że jest to potęga dwójki jest oczywiste: łatwo z tego uzyskać impulsy sekundowe. Wartość natomiast została wybrana kompromisowo, ze względu na zużycie energii, wymiary i specjalizację ogólnoświatową, dzięki czemu kwarce te są tanie i dokładne, mimo stosunkowo niskiej częstotliwości rezonansowej.

Mają charakterystyczną postać małej rurki i znajdziemy ten kształt w każdym zegarku elektronicznym czy urządzeniu używającym takiego zegara. Układ zlicza impulsy, by udostępnić czas: od sekund do lat, uwzględniając lata przestępne. Pozwala także zachować 31 bajtów użytkownika, zwykle konfiguracji urządzenia, loginów czy haseł i pracuje w szerokim zakresie napięć: od 2 do 5 i pół wolta.

Zasilanie rozwiązano tu sprytnie: mamy dwa wejścia, jedno jest przypisane baterii, akumulatorowi lub superkondensatorowi. Drugie – linii zasilającej. Dopóki drugie napięcie będzie wyższe od pierwszego, będzie zasilać całość. Domyślnie operacje zapisu i odczytu wykonujemy wówczas, gdy tak właśnie będzie, więc prąd zasilający z wejścia bateryjnego będzie bardzo mały.
Wartości trochę nieszczęśliwie przechowywane są w kodzie BCD. To znaczy pojedyncze sekundy na czterech najmłodszych bitach, dziesiątki – na trzech starszych i tak dalej.

Z drugiej strony, wyłuskiwane wartości można wprost wysyłać na wyświetlacze, co czasem upraszcza kod programu. Zegar może pracować także w systemie dwunastogodzinnym i wówczas jeden z bitów określa czy mamy poranek, czy wieczór. Ciekawie wygląda sprawa z dniem tygodnia. Ponieważ niektórzy uważają, iż pierwszym jest niedziela, a inni – poniedziałek, nie zdefiniowano tu co jest czym. Po prostu o północy zwiększa się licznik modulo siedem, a już programista ustala sobie czy jedynka to poniedziałek, czy niedziela. Z tego powodu nie mamy tu magicznego kalendarza, który określi dzień tygodnia dla daty i numer dnia tygodnia należy wpisywać ręcznie przy ustawianiu zegara. Czas na realizację programową. Jak zwykle nie będziemy tego programować ręcznie, bo skoro istnieje biblioteka – dlaczego by z niej nie skorzystać?
#include <virtuabotixRTC.h> // Biblioteka obsługująca zegar DS1302
virtuabotixRTC zegar(6, 7, 8); // Piny, kolejno: CLK, DAT, RST
const byte resetujZegar = 5; // Stan wysoki zezwala na reset zegara po resecie Arduino.
void setup() {
pinMode(resetujZegar, INPUT_PULLUP); // Deklaruj port resetu zegara.
Serial.begin(115200); // Inicjuj monitor.
if (digitalRead(resetujZegar) == HIGH) { // Jeśli podczas resetu Arduino przycisk jest wciśnięty...
zegar.setDS1302Time(57, 59, 23, 2, 31, 12, 2024); // Ustaw: sekundy, minuty, godziny, dzień tygodnia, miesiąca, miesiąc, rok.
}
}
void loop() {
zegar.updateTime(); // Funkcja ładująca dane z układu DS1302 do bufora.
Serial.print(zegar.year); // Rok (pełna, czterocyfrowa liczba).
Serial.print("-");
Serial.print(zegar.month); // Numer miesiąca.
Serial.print("-");
Serial.print(zegar.dayofmonth); // Dzień miesiąca (uwzględniane są lata przestępne).
Serial.print(" (");
Serial.print(zegar.dayofweek); // Dzień tygodnia (1-7, nie jest obliczany wg kalendarza).
Serial.print(") ");
Serial.print(zegar.hours); // Godzina.
Serial.print(":");
Serial.print(zegar.minutes); // Minuta.
Serial.print(":");
Serial.println(zegar.seconds); // Sekunda.
delay(1000);
}
Bibliotekę o nazwie virtuabotixRTC.h należy sobie ściągnąć z sieci, bo w zestawieniu bibliotek w Arduino Uno nie znajdziemy jej. Wymaga nazwania zegara – oczywiście nazwałem go zegar i zadeklarowania linii zegara, danych i restartu. Szkic jest prosty i stanowi tak naprawdę tylko przykład do implementacji we własnych rozwiązaniach. Toteż demonstruje jedynie dwa elementy: programowanie czasu i jego odczyt.
zegar.setDS1302Time(57, 59, 23, 2, 31, 12, 2024); // Ustaw: sekundy, minuty, godziny, dzień tygodnia, miesiąca, miesiąc, rok.
W pierwszym przypadku należy podać ciąg liczb w kolejności: sekundy, minuty, godziny, dzień tygodnia – umownie, jak mówiłem, dzień miesiąca, miesiąc i rok. W pętli głównej będziemy wyłuskiwać elementy zegara za pomocą zdefiniowanych przez twórcę biblioteki komend. Wysyłam je raz na sekundę na monitor. W nawiasie siedzi sobie dzień tygodnia.
Program działa, ale po resecie zawsze ustawia ostatnie sekundy sylwestra – bo tak mu kazałem dla przykładu. A przecież dobrze byłoby na chwilę odłączyć zasilanie i zobaczyć, czy zegar nadal będzie pracować. Jednak każdorazowy reset ustawia wartości domyślne. Dlatego wprowadziłem dodatkowy element – wykorzystując przycisk na mojej płytce edukacyjnej TME. Teraz zaprogramowanie zegara wartościami domyślnymi będzie możliwe wyłącznie z chwilą, gdy podczas resetu ten przycisk będzie wciśnięty. Zresetujmy więc ustawienia i odłączmy zasilanie na kilka minut. Jeśli po ponownym uruchomieniu zegara, nie dotykając przycisku, uzyskamy wyniki kilka minut późniejsze – znaczy zegarek działa i bateria jest sprawna.
W kolejnym artykule przedstawię inny nieco układ: DS1307 oraz RTC siedzące w nowym Arduino Uno R4.