
Witajcie, zapraszam na relację z konstrukcji zegara na PIC18F2550 napisaną w formie tutoriala, wszystko krok po kroku. Pokażę tu jak i z czego tworzyłem prosty projekt DIY na prośbę jednego z czytelników. Wykorzystamy tu wyświetlacze 7-segmentowe, rejestr przesuwny, obsłużymy przyciski a może nawet potem z I2C coś ruszymy. Nie będzie to kompletny opis i pewnie będzie kontynuowany w dalszym temacie, więc proszę nie oczekiwać pełnoprawnego produktu na końcu postu.
Docelowo zegar będzie mieć nawet zaprojektowaną pod niego płytkę, będzie pokazywać czas i datę, wykonywać pomiary temperatura i wilgotności i też będzie w stanie oferować kontrolę przekaźnikami, ale to wszystko dopiero za jakiś czas.
Powiązane tematy samouczkowe
Wiele konceptów stąd było omawianych już wcześniej, w związku z czym szczegółowość tłumaczenia tutaj będzie już nieco mniejsza. Zamiast tego po prostu zalinkuję tutaj wcześniejszejsze moje materiały na powiązane tematy:
Tutorial podzielony jest na osobne tematy i tutaj znajdują się do nich linki.
PIC18F SDCC tutorial cz. 1 - Konfiguracja środowiska pracy
https://www.elektroda.pl/rtvforum/viewtopic.php?p=18304424#18304424
PIC18F SDCC tutorial cz. 2 - Blink LED, piny IO, cyfrowe wejścia i wyjścia
https://www.elektroda.pl/rtvforum/viewtopic.php?p=18389188#18389188
PIC18F SDCC tutorial cz. 3 - Ustawienia oscylatora. Oscylator wewnętrzny, zewnętrzny, rezonator kwarcowy, PLL
https://www.elektroda.pl/rtvforum/topic3657704.html
PIC18F SDCC tutorial cz. 4 - Timery, przerwania
https://www.elektroda.pl/rtvforum/viewtopic.php?p=18580858#18580858
PIC18F SDCC tutorial cz. 5 - Obsługa wyświetlacza siedmiosegmentowego
https://www.elektroda.pl/rtvforum/viewtopic.php?p=18580877#18580877
PIC18F SDCC tutorial cz. 6 - Sterownik wyświetlacza LED MM5450
https://www.elektroda.pl/rtvforum/topic3845301.html
Poboczne powiązane tematy:
Wyświetlacz 7 segmentowy tunera, uruchomienie z Arduino, rejestr przesuwny
Uwaga organizacyjna i podziękowania
Temat powstał na bezpośrednią prośbę i zainteresowanie jednego z czytelników, który również ma swój wkład w rozwój tego mini-projektu, a nawet wysłał mi do niego nieco wybranych przez siebie części:


W związku z tym projekt jest taki a nie inny. Za wysłanie mi części bardzo dziękuję! Projekt będzie prowadzony dalej też i rozwijany wedle uwag czytelnika.
Użyte środowisko i MCU
Tak jak w tytule tematu - PIC18F2550 będzie sercem układu. Natomiast jeśli chodzi o środowisko, to początkowo pisałem na SDCC, ale potem by oszczędzić czasu przeniosłem się na MikroC, gdyż tam miałem gotowe funkcje do I2C. Nie wykluczam, że do SDCC potem wrócę, zwłaszcza, że preferuję te bardziej otwarte rozwiązania.


Krok 1: Minimalny układ
Minęło trochę czasu, więc robimy twardy reset - zaczynam całkiem na nowo, oto minimalny układ z PIC18F na płytce stykowej.

Zasilaczyk do płytki stykowej też jest tu przydatny, bo normalnie brzegowe linie masa/zasilanie nie są połączone, a on je tutaj łączy i też w razie czego pozwala zasilić projekt z zasilacza.
Na początku też należy sprawdzić czy wszystko gra i czy blink LED działa:

Typowym błędem jest wgrywanie wsadu na z jakiegoś powodu martwy/niestartujący mikrokontroler bądź wgrywanie złego wsadu (starego, ze złego folderu, itd), więc warto sprawdzić, czy w ogóle nasz program się odpala i miga tak jak chcemy.
Krok 2: Rejestr przesuwny
Wyświetlacz już omawialiśmy, ale wtedy zajęliśmy cały jeden port 8-bitowy (8 pinów, czy tam 7, nie licząc kropki) by nim sterować. Spróbujmy zredukować ilość pinów - użyjemy do tego rejestru przesuwnego, czyli konwertera serial-in na paralel-out, wejście szeregowo (jedna linia danych i zegar), a wyjście równoległe (tutaj 8 pinów).
Układ taki można kupić, ale by urozmaicić zabawę użyłem takiego z elektrośmieci. Wylutowałem go z PCB metodą topnik + spoiwo Pb, po prostu naniosłem topnik a potem spoiwo na jego wszystkie nóżki a potem je równomiernie podgrzałem grotem. Tak podgrzane luty pozwalają układowi wypaść z PCB, działa to dość dobrze o ile jego nóżki nie są zagięte a samo PCB jest jeszcze z czasów gdy nie panowało spoiwo bezołowiowe:






Rejestr uwolniony!
Tak oto zyskujemy 74HCT164:

Oczywiście można kupić inny rejestr przesuwny, zresztą i tak są one dość tanie.

A jak nim sterować? To już pokazywałem w kontekście Arduino:
Wyświetlacz 7 segmentowy tunera, uruchomienie z Arduino, rejestr przesuwny
Pin MR resetuje cały układ - gdy ustawimy go w stan niski, to on zeruje wszystkie wyjścia. Piny DSA i DSB stanowią wejścia, na wejście rejestru wchodzi wynik iloczynu logicznego (AND) wartości na tych pinach. Na wejście rejestru informacja pobierana jest gdy sygnał zegara przechodzi ze stanu niskiego na wysoki (tzw. zbocze rosnące).
Wystarczy krótka funkcja:
Code: c
Zakomentowana linijka z HC_DATA pozwala określić kolejność przekazywania bajtów - od najmłodszego, czy od najstarszego?
Oczywiście piny trzeba ustawić, zdefiniować HC_DATA i tak dalej, jak również ustawić je w tryb wyjść.
Oto cały kod przykładu, wraz z główną pętlą gdzie na rejestr przekazywane są kolejne liczby:
Code: c
W celu demonstracji użyłem płytki SYB170 z diodami LED:

Wykonałem połączenia - HC_CLOCK, HC_DATA, HC_RESET na odpowiednie wejścia rejestru. Dodatkowo też zasilanie, wiadomo, oraz na wyjścia rejestru LEDy.
W ten sposób powstało prymitywne odliczanie binarne:
I tutaj pojawia się pierwszy problem - czemu wszystko tak miga? Czyżby był błąd?
Niestety nie ma tutaj błędu - użyty rejestr przesuwny ma taką prostą konstrukcję, że kolejno przesuwa wyjścia co może być widoczne dla człowieka. Można by użyć droższego rejestru, takiego z kontrolą latch (przerzucenia w jednym momencie nowych danych na wyjścia), ale my sobie poradzimy i bez tego - niedługo pokażę jak.
Krok 3: Wyświetlacz - jedna cyfra
Czytelnik wysłał mi te piękne, niebieskie wyświetlacze, która zdają się być nawet nieco większe od wyświetlaczy które posiadam ze sprzętów z elektrośmieci i dają fajny, przyjemny odcień światła:

Jest to model 5261AB, wyświetlacz ze wspólną katodą, dwucyfrowy.

Wymiary i pinout:

No i cena:

Jakieś 25 zł za 10 sztuk... 2.5zł za sztukę.
Warto zajrzeć też do jego parametrów - mamy tu parametry potrzebne do określenia jaki rezystor jest potrzebny, Vf, prąd segmentu... tak jak dla zwykłej diody LED:

Ciekawe, że producent również określa, że przy 1/10 wypełnienia przy 10kHz można puszczać do 100mA przez segment. To się może nam przydać, gorzej, jeśli dobierzemy taki rezystor a potem nasz multipleksing się popsuje i wyświetlacz dostanie ciągły prąd 100mA...
Ostatecznie zdecydowałem się na te 30mA prądu ciągłego i uruchomiłem wyświetlacz pojedynczo. Tak jak w poprzednim temacie (część o wyświetlaczu), ale zamiast zapisywać segmenty danego znaku do portu B:
Code: c
wysyłam je do rejestru przesuwnego:
Code: c
Oto cały kod:
Code: c
Rezultat:
Każda z cyfr ma osobno wszystkie piny od segmentów. To trochę mi skomplikowało sprawę. Wiadomo, że wspólne anody (czy tam katody) powinny być osobno by sterować osobno każdą z cyfr, ale segmenty... no cóż, troszkę musiałem popodłączać na płytce by obie cyfry uruchomić:

Krok 4: Wyświetlacz - multipleksing
Pora powitać tranzystory - tutaj dwa, po jednym na cyfrę. Oczywiście wraz z rezystorami ograniczającymi prąd bazy, tak jak w poprzedniej części o wyświetlaczu. Użyłem tutaj BC547, NPN, oczywiście wspólna katoda do kolektora a emiter tranzystora do masy. Odpowiednio zmodyfikowałem kod, na razie bez przerwań.
Code: c
Kod odlicza i bardzo szybko (niezauważalnie dla ludzkiego oka) wyświetla na przemian obie cyfry. Dodatkowo tutaj jest wspomniane wcześniej rozwiązanie problemu z rejestr przesuwnym - przed shiftOut wyłączam oba tranzystory, by nie było tego krótkiego momentu gdzie świecą się losowe segmenty.
Tyle, że powyższy kod robi wszystko w main i blokuje wszystkie inne czynności funkcją delay1ktcy. Pora użyć timera i przerwania, po prostu zwolnymi sobie main a funkcja przerwania będzie wywoływana co dany czas poprzez timer.
Mamy do tego nawet wygodne narzędzie - MikroC Timer Calculator:

Poniżej mamy zasadniczo to samo, ale już z przerwaniem i timerem:
Code: c
Tak jak w temacie o przerwaniach. Rezultat:
Krok 5: Wyświetlacz - lutujemy...
Tutaj niestety przychodzi taki moment, że trzeba pożegnać się z płytką stykową i użyć wygodniejszego rozwiązania - łączenie wspólnych segmentów dla wielu cyfr byłoby tam już naprawdę problematyczne. Nie chciałem jeszcze projektować pod wyświetlacz PCB, więc zdecydowałem się na dość czasochłonną, ale skuteczną metodę dostępną dla każdego - wiercone płytki prototypowe, tutaj z osobnymi polami miedzi (każde jest osobno, dopiero musimy utworzyć nasze ścieżki):

Takie płytki są naprawdę bardzo tanie, ale lutowanie na nich zajmuje dużo czasu:

No i trzeba uważać, by nie przegrzewać ich padów, tam każdy pad lutowniczy jest osobno i nie ma dużej pojemności cieplnej, jak początkujący go przypali przesadnie rozgrzanym grotem to ten pad odpadnie.
Wstępne przymiarki:

Zworki łączące segmenty obu cyfr:



Lutowanie na spodzie:

Drugi wyświetlacz:

Gotowe:

Niestety na spodzie też musiałem łączyć i sztukować:

Uprzedzając pytanie - dwukropki powstaną poprzez dodatkowe diody LED... po prostu takie wyświetlacze dostałem.
Dużo było zabawy z tym lutowaniem.
Kod został wzbogacony o obsługę dwóch dodatkowych cyfr.
Code: c
Efekt:

Krok 6: Odmierzanie czasu
Mniej więcej na tym etapie podpiąłem timer do odmierzenia czasu. Użyłem timera pierwszego, bo zerowy był już zajęty przez odświeżanie wyświetlacza. Do obliczenia wartości przepełnienia użyłem mikroC timer calculator. Tyle, że timer 1 nie był w stanie wywoływać przerwania co 1s, więc wybrałem okres 250ms:
Code: c
Na ten moment zdecydowałem się zliczać osobno sekundy, minuty i godziny. Możliwe, że potem wrócę do zliczania pełnej ilości sekund zamiast tak dzielić, ale w ten sposób było mi wygodniej. W przerwaniu timer1 zliczam wywołania do 4 a potem ustawiam kolejną sekundę:
Code: c
A oto funkcja wyświetlania tego (dba o to, by zawsze pozycje odpowiednich cyfr godziny/minuty/sekundy były niezmienne):
Code: c
Powyższa funkcja zakłada już 6 cyfr, ale w razie czego dwie ostatnie można po prostu zakomentować.
Krok 7: Przyciski - część 1
Teraz zobaczymy jak można ładnie wykorzystać istniejącą już konstrukcję układu aby dodać do niego przyciski bardzo "tanim kosztem", a dokładniej kosztem jednego wejścia mikrokontrolera. Tak, starczy tylko jedno IO - a będzie można było obsłużyć aż do 8 przycisków.
Wystarczy podłączyć przyciski pomiędzy wybrany IO, a linie segmentów. Dodatkowo wybrany IO będzie mieć rezystor pull up (tutaj programowalny w PIC), by domyślnie ustawić stan wysoki. Następnie w procedurze skanowania przycisków będziemy kolejno wystawiać pojedynczy stan niski na kolejne przyciski (pozostałe bity) i badać czy ten stan niski "przeszedł" na pin wejścia.
Jeśli "przejdzie", to znaczy, że dany przycisk jest wciśnięty. W przeciwnym razie, przycisk nie jest wciśnięty.

Code: c
Przerwanie ma teraz 5 kroków - 4 dla cyfr, a piąty dla skanu przycisków. Zmienna "cnt" reprezentuje stan przycisków, gdzie każdy bit odpowiada danemu przyciskowi. Kod można by umieścić w pętli, ale już nie chciałem komplikować - tu widać, że kolejno wystawiam stan niski na każdy kolejny pin rejestru i badan stan przyciski.
Oto krótki test przycisków:
Każdy przycisk odpowiada kolejnej potędze dwójki - jest dobrze, ale co się dzieje jak wciśniemy dwa przyciski na raz?
Niestety wtedy system się psuje, wyświetlacz nawet nie wyświetla poprawnie.
Bierze się to stąd, że zwierając dwa przyciski zwieramy wtedy też dwa wyjścia rejestru przesuwnego, więc uniemożliwiamy multipleksing fragmentów....
Krok 8: Przyciski - część 2
Trzeba naprawić problem z poprzedniego akapitu. Naprawa będzie w pełni sprzętowa. Po prostu musimy zablokować przyciski/wyjścia rejestru przesuwnego tak, by prąd mógł płynąć tylko w jedną stronę i nie mógł "zawrócić" - wystarczy dodać diody:

Tak włączone diody wciąż umożliwiają zwarcie danym przyciskiem naszego pojedynczego wejścia MCU do masy, ale jednocześnie uniemożliwiają zrobienie spięcia poprzez wciśnięcie kilku przycisków. Od teraz wciśnięcie na raz kilku przycisków daje poprawne rezultaty, np. jak wciśniemy przyciski pierwszy i trzeci to otrzymamy w rezultacie liczbę 5, czyli 2 do potęgi 0 dodać 2 do potęgi 2, czyli 1 + 4 = 5.
Krok 9: Przyciski - część 3 - zdarzenia
Teraz pora dodać proste programowane rozwiązanie problemu drgania styków oraz wprowadzić dwa przyciskowe zdarzenia - pierwsze wciśnięcie (wolna reakcja) oraz trzymanie przycisku (jak trzymamy dłużej niż dany okres czasu to zdarzenie się powtarza). Tak jak na komputerze - wciśnijcie dowolny klawisz, np. 'a' to zobaczycie, że klawisz pojawia się raz a potem się wielokrotnie powtarza.
Na początku zdefiniujmy te tytułowe zdarzenia:
Code: c
Przy okazji zmienną określającą jak szybko powtórnie wyśle się zdarzenie hold.
Code: c
W celu dodania obsługi zdarzeń przetworzymy uzyskaną maskę przycisków.
Może na początek poprawmy samo jej tworzenie - tak, by już była pętla:
Code: c
Wcześniej to było rozpisane osobno dla każdego i.
Od razu lepiej. Teraz pytanie, co zrobić z tą zmienną newButtons?
Oto przetwarzanie przycisków:
Code: c
Pamiętamy stary stan przycisków i w pętli porównujemy go z nowym. Jeśli nastąpi zmiana danego stanu przycisku, to resetujemy licznik tego przycisku. W przeciwnym razie go zwiększamy. Jak licznik osiągnie pierwszą ustalaną wartość (tutaj BUTTON_MIN_REPEATS) to wyzwalamy zdarzenie wciśnięcia - wciśnięcie pierwsze. Potem jeśli minie trochę czasu (dwa razy czas do pierwszego wciśnięcia) to co BUTTON_MIN_REPEATS jednostek czasu wyzwalamy kolejne zdarzenia, ale już oznaczone jako BUTTON_PRESS_HOLD.
Analogicznie można by dodać też np. zdarzenie RELEASE (puszczenie przycisku), ale aż tak nie chciałem kombinować.
Teraz przykład obsługi zdarzenia - wykorzystanie do edycji wartości sekund.
Code: c
Argument b to indeks przycisku, eventType to rodzaj zdarzenia. Na bazie rodzaju zdarzenia dobieramy co ile zmieniamy wartość (1 lub 10) i tą wartość dodajemy lub odejmujemy od sekund.
Wszystko działa (chociaż chyba częstotliwość repeats można by zmniejszyć?):
Krok 10: Wprowadzenie I2C
Na tym etapie zdecydowałem się przejść na mikroC PRO for PIC, gdyż nie chciałem bawić się w uruchamianie od 0 I2C, jak jest przecież gotowa biblioteka i działa w darmowej wersji tego kompilatora.
I2C wymaga rezystorów pull-up na liniach SDA i SCL. Na PIC18F2550 te linie to RB0 i RB1. Do testów użyłem termometru TC74.

TC74 używam zawsze na próbę ze względu na jego prostotę.
Dokumentacja użytej biblioteki I2C znajduje się tutaj:
https://download.mikroe.com/documents/compilers/mikroc/pic/help/i2c_library.htm
Urządzenia I2C mają różne adresy, dzięki temu można na jednej magistrali podłączyć wiele urządzeń. MCU wywołuje najpierw adres urządzenia, a potem z nim się komunikuje. Z tego też powodu zabawę z I2C zaczynam zawsze od skanera:
Code: c
Powyższy kod podpiąłem do wyświetlacza by wiedzieć czy jakikolwiek adres się zgłasza - to pozwala sprawdzić, czy urządzenie I2C jest widziane.


Pozwoli to też uniknąć błędów typu "kod komunikacji jest dobry, ale wpisany jest zły adres, więc nie otrzymujemy odpowiedzi".
Sprawdźmy, czy adres jest ok. TC74A0...

Te adresy są bez bitu R/W, więc go dopisałem jako 0. Zgadza się!

Potem już (zgodnie z notą katalogową) podpiąłem odczyt temperatury z TC74:
Code: c
Weryfikacja działania (temperatura w pokoju + podgrzanie sensora latarką):


Krok 11: Piąta i szósta cyfra
Bez zbędnego komentarza - dolutowałem kolejną parkę cyfr. Niestety brakło miejsca na ładne wyprowadzenie golpinów od baz tranzystorów, ale to tylko prototyp.



Krok 12: Edycja godziny/minuty/sekundy
Jak na razie tylko na próbę - zobaczmy, jak zrobić prostą edycję.
Po prostu damy kolejną zmienną określającą tryb pracy (zwykła praca, edycja godzin, minut, sekund)oraz kolejny przycisk, który pozwala przełączać pomiędzy kolejnymi trybami.
Code: c
Do zwiększania/zmniejszania wartości zmiennej użyłem preprocesora, pozwala to uniknąć nadmiernego pisania, a kompilator i tak nie widzi różnicy. Dodatkowo przy edytowanej parze cyfr podświetlam kropkę poprzez dotFlags, gdzie zapalony bit na danej pozycji odpowiada zapalonej kropce na danej pozycji.
Krok 13: Czujnik temperatury i ciśnienia BMP280
W zestawie od czytelnika dostałem też czujnik BMP280. Wiem, że dopiero co uruchomiłem prymitywny termometr TC74, ale myślę, że BMP280 też warto odpalić.


Co to za czujnik?

Ile kosztuje taka zabawa?

Przyznam, że moim zdaniem jest dość tani. Zacząłem znów od skanu I2C (pozwala to uniknąć problemów z posiadaniem złego adresu urządzenia):

Potem podjąłem najpierw próbę pisania komunikacji z BMP280 od zera, ale po konsultacji z notą katalogową i z przykładowymi sterownikami uznałem, że to nie jest tak łatwo jak z TC74, że od razu dostaje się wynk, tylko jest dużo zabawy z tym (kalibracje jakieś, obliczenia, przesunięcia bitowe) i ostatecznie użyłem biblioteki BMP280 od https://simple-circuit.com/ .
Kod testowy:
Code: c
To naprawdę tylko tyle. Bardzo dobra biblioteka. Jedynie dodam, że mój skaner I2C się przydał, bo biblioteka miała wpisana domyślnie w nagłówku inny adres niż ten co miał mój czujnik.
Ciśnienie:

Temperatura (przed i po podgrzaniu światłem):


Krok 14: sterowanie przekaźnikami
Na koniec zrobiłem szkic sterowania przekaźnikami, a dokładnie tutaj przyjąłem format możliwości ustawienia zdarzeń, które zawierają:
- czas (HH:MM:SS)
- indeks przekaźnika
- stan do ustawienia (on or off)
Jednym z plusów takiego podejścia jest możliwość nadpisania stanu przekaźnika poprzez użytkownika (po prostu user może nacisnąć przycisk i przekaźnik wyłączyć)
W kodzie użyłem konwencji z HH:MM:SS, chociaż tak jak pisałem wcześniej, pewnie docelowo będę trzymać tylko całkowitą ilość sekund z danej doby:
Code: c
W momencie zmiany sekundy sprawdzam ustawione zdarzenia i w razie czego wykonuję zmianę na pinie.
To na razie wstępny szkic, ale docelowo rozważam rozdzielenie tego na alarmy (po prostu funkcjonalność budzika) oraz przekaźniki (załączanie dowolnego urządzenia).
Do struktury relaySlot_t można by np. też dopisać konfigurowalną ilość w minutach po jakiej dany slot się wyłączy, też opcjonalnie, bo na ten moment jeśli chcemy coś włączać i wyłączać to trzeba użyć dwa sloty (jeden do zdarzenia ON, drugi dla OFF).
Nie jest to sterowanie w pełni kompletne, brakuje jego wykonania oraz sposodu dostępu do GPIO. Reszta w drugiej częsci.
Krok 15: złożone w całość
Ostatecznie złożyłem w całość odliczanie czasu, pomiary temperatury i pomiary ciśnienia oraz szkic systemu ustawiania godziny oraz ustawiania zdarzeń.
Normalnie zegar wyświetla bieżący czas, ale co około pół minuty pokazuje też ciśnienie w hPa (musiałem uciąć a przez brak miejsca na wyświetlaczu) oraz temperaturę (muszę dodać wyświetlanie kropki).
Działa również edycja godziny i zdarzeń, bieżącą edytowaną wartość pokazuje kropka.
Przy zdarzeniach edytujemy też Px (P0, P1, itd) jako numer przekaźnika/GPIO, oraz zmieniamy En na no (stan Enabled lub not active).
Czas, ciśnienie, temperatura:
Edycja godziny:
Edycja przekaźnika (stan En/no, Px, godzina):
Z tego co widzę, to chyba będę musiał pozwolić na częstsze wciśnięcia przycisków, bo zbyt częste kliknięcia się gubią.
Krótka ściąga co dalej
Inaczej zwana też potocznie "listą TODO", czyli to co jest do zrobienia za jakiś czas.
- reorganizacja kodu
- RTCC na I2C
- dolutować LEDy w roli kropek do wyświetlaczy (bo akurat takie dostałem wyświetlacze...)
- lepszy system przekaźników/alarmów
- ustawienie daty i jej wyświetlanie
- powrót z MikroC do SDCC (czyli ogarnięcie I2C w SDCC, bo to przez brak gotowego I2C tymczasowo zrobiłem migrację do Mikro)
- rozważania co do PCB i przekaźników
Podsumowanie
To był trochę chaotyczny, trochę szczegółowy opis pierwszego etapu tworzenia zegara dla czytelnika. Projekt powstawał powoli, w wolnych chwilach, w formie takiej amatorskiej zabawy.
Jeszcze raz dziękuję czytelnikowi za wysłanie mi części, zabawa była przednia (a to dopiero początek), tym bardziej, że dawno już chciałem coś porobić w starym stylu na PIC18F, bez żadnych WiFi, IoT i serwerów.
Opis byłby dłuższy, ale już zbliżam się do limitu znaków w poście na forum (a taki u nas na Elektrodzie istnieje).
W dalszej części spróbuję nieco ogarnąć kod, bo teraz tam miejscami jest źle, oraz wdrożyć system daty, już zapewne na zewnętrznym RTCC z bateryjką CR. Ulepszy się też system przekaźników/budzika, też przyda się dodać buzzer.
Jak macie jakieś merytoryczne uwagi bądź sugestie jak np. lepiej zorganizować system kontroli przekaźnikami/budzikami/cokolwiek innego to zapraszam do komentowania.
PS: Jeśli interesuje was nieco inne podejście do robienia zegara, tym razem z wyświetlaczem na MAX7219, to możecie zobaczyć mój temat sprzed 3 lat:
Zegar/kalendarz na PIC16F1455, MAX7219, DS1302 - szczegółowy opis/kody/STLe. Tu chciałem nieco zrobić odmianę, z tego powodu realizuję całość inaczej.
Cool? Ranking DIY