Przejdź do głównej zawartości

Programowanie AVR cz. 4: ATtiny2313 + PCF8583P + AT24C04 + I2C,czyli... zabrakło pamięci, ale jest zegar nastawiany "w locie".

Kontynuując zabawę z magistralą I2C (patrz: poprzedni artykuł o programowaniu AVR) i grzebanie w elektronicznym złomie, natknąłem się na niepozorny układ scalony PCF8583P, zamontowany wraz z - jak się domyśliłem - odpowiednim oscylatorem kwarcowym na prehistorycznej płytce uruchomieniowej, jeszcze chyba z czasów AT89C4051. Układ ten to zegar czasu rzeczywistego (RTC) wraz z kalendarzem i obsługa alarmów, zarządzany (programowanie, odczyt) poprzez magistralę I2C. Nie zastanawiając się długo postanowiłem dołączyć ten układ do systemu z poprzedniego wpisu, żeby stworzyć wypasiony zegar, kalendarz, budzik... Niestety, szybko okazało się, że mój ulubiony mikrokontroler ATtiny2313 ma zbyt mało pamięci FLASH, żeby pomieścić finezyjny kod, który zaczął mi wychodzić (żaliłem się już w moim streamie Google+). Dlatego też ograniczyłem program demonstracyjny do samego zegara - jedyny ficzer, jaki się pojawił, to nastawianie godziny i minuty "w locie" za pomocą dwóch przycisków. Oznacza to, że każda zmiana godziny czy minuty (zmiana w górę, czyli inkrementacja) powoduje natychmiastową aktualizację ustawień zegara PCF8583P. Oczywiście aktualny czas jest wyświetlany na jednowierszowym LCD.
Początkowo program działał dziwnie, udało mi się jednak - częściowo w oparciu o analizę, częściowo metodą doświadczalną - zapanować nad tą niestabilnością i teraz wszystko jest OK. Zachęcam do przejrzenia kodu źródłowego, mimo, że nie zawiera jakichś specjalnych wodotrysków, ech...

' Obsługa pamięci EEPROM 24c04 i zegar czasu rzeczywistego PCF8583P
$regfile = "attiny2313.dat"
$crystal = 4000000
$hwstack = 40
$swstack = 16
$framesize = 32
' UWAGA:
' Fragment programu dotyczący komunikacji z pamięcią szeregową AT24C04C został
' usunięty ze względu na zbyt duży rozmiar kodu wynikowego (został przekroczony
' maksymalny rozmiar pamięci Flash - 2048B)
' Zostały tylko definicje stałych związanych z adresami pamięci.
' Pamięć 24c04 (SLAVE):
' - wyprowadzenie A1 podłączone do masy, stąd adresy jak niżej.
' Pierwsze 256 bajtów - bank 1 (bit P0 = 0)
Const Addrw_eep_p0 = 168
Const Addrr_eep_p0 = 169
' Drugie 256 bajtów - bank 2 (bit P0 = 1)
Const Addrw_eep_p1 = 170
Const Addrr_eep_p1 = 171
' Zegar czasu rzeczywistego PCF8583P (SLAVE):
' - wyprowadzenie A0 podłączone do masy
Const Addrw_rtc = 160
Const Addrr_rtc = 161
Config Submode = New
' Konfiguracja wyświetlacza
Config Lcd = 16 * 1a
' Porty mikrokontrolera (dwie linie portu B), które będą emulować wyprowadzenia magistrali I2C (mikrokontroler to MASTER)
Config Scl = Portb.1
Config Sda = Portb.0
' Do linii portu D podłączone są diody kontrolne oraz przyciski ustawiania zegara
Config Portd = &B1110011
Portd = &B0001100
' Timer0 zgłasza przerwanie co ok. 16 ms - następuje wtedy odczyt czasu i daty z RTC
' oraz konwersja z BCD na format dziesiętny
Config Timer0 = Timer , Prescale = 1024
'Włączenie obsługi przerwań i - w szczególności - przerwania timera 0
Enable Interrupts
Enable Timer0
On Timer0 Show_date_time
Dim Value As Byte , Value1 As Byte , Value2 As Byte
Dim Hours As Byte , Minutes As Byte , Seconds As Byte
Dim Change As Boolean
Dim Send As Boolean
Dim Time_str As String * 9
Dim Hour_str As String * 3
Dim Minute_str As String * 3
Dim Second_str As String * 3
Portd.5 = 0 ' dioda czerwona
Portd.4 = 0 ' dioda niebieska
Portd.3 = 1 ' przycisk minut
Portd.2 = 1 ' przycisk godzin
Cursor Off
Cls
Change = 1
Do
If Change = 1 Then
Hour_str = Str(hours)
Minute_str = Str(minutes)
Second_str = Str(seconds)
If Hours < 10 Then
Time_str = "0" + Hour_str
Else
Time_str = Hour_str
End If
If Minutes < 10 Then
Time_str = Time_str + ":0" + Minute_str
Else
Time_str = Time_str + ":" + Minute_str
End If
If Seconds < 10 Then
Time_str = Time_str + ":0" + Second_str
Else
Time_str = Time_str + ":" + Second_str
End If
Locate 1 , 1
Lcd Time_str
Change = 0
End If
Debounce Pind.3 , 0 , Incr_min , Sub
Debounce Pind.2 , 0 , Incr_hour , Sub
If Send = 1 Then
' Opóźnienie konieczne ze względu na prawidłową pracę magistrali I2C
Waitms 25
Gosub Send_time
Start Timer0
Send = 0
End If
Loop
End
' Zapis czasu do PCF8583P
Sub Write_stream_3b(byval Adres As Byte , Value As Byte , Value1 As Byte)
I2cstart
I2cwbyte Addrw_rtc
I2cwbyte Adres
I2cwbyte 0
I2cwbyte Value
I2cwbyte Value1
I2cstop
' Konieczny jeszcze jeden bit stopu (bez niego problemy ze stabilnością)
I2cstop
End Sub
' Odczyt czasu z PCF8583P i konwersja BCD->DEC
Sub Read_stream_3b(byval Adres As Byte)
I2cstart
I2cwbyte Addrw_rtc
I2cwbyte Adres
I2cstart
I2cwbyte Addrr_rtc
I2crbyte Value , Ack
I2crbyte Value1 , Ack
I2crbyte Value2 , Nack
I2cstop
Seconds = Makedec(value)
Minutes = Makedec(value1)
Hours = Makedec(value2)
End Sub
' Wyłączanie/włączanie odmierzania czasu przez PCF8583P
Sub Toggle_pcf_timer(byval Pcf_timer As Byte)
I2cstart
I2cwbyte Addrw_rtc
I2cwbyte 0
If Pcf_timer = 0 Then
I2cwbyte 128
Else
I2cwbyte 0
End If
I2cstop
End Sub
' Zapis zmienionych ustawień zegara; sekundy zerowane
Send_time:
Value = Makebcd(minutes)
Value1 = Makebcd(hours)
Write_stream_3b 2 , Value , Value1
Toggle_pcf_timer 1
Return
' Podprogram obsługi przerwania timera 0
' - odczyt i dekodowanie czasu z PCF8583P
Show_date_time:
Read_stream_3b 2
Change = 1
Return
' Nastawianie zegara - inkrementacja minut
Incr_min:
Stop Timer0
Toggle_pcf_timer 0
Minutes = Minutes + 1
If Minutes >= 60 Then
Minutes = 0
End If
Send = 1
Return
' Nastawianie zegara - inkrementacja godzin
Incr_hour:
Stop Timer0
Toggle_pcf_timer 0
Hours = Hours + 1
If Hours >= 24 Then
Hours = 0
End If
Send = 1
Return
view raw zegar.bas hosted with ❤ by GitHub

Całość uruchamiana była w układzie zawierającym na magistrali I2C również wspomnianą pamięć EEPROM, a ponieważ PCF8583 jest poniekąd modyfikacją pamięci z dołożoną ekstra funkcjonalnością (posiada np. taką samą jak AT24C04, zaszytą "preambułę" adresu), musiałem ustalić na nowo adresy sprzętowe slave'ów. Być może powodem niestabilnego działania układu (w pewnych warunkach) było zachwianie parametrów elektrycznych magistrali, nie pozwalające na poprawną transmisję danych? Nie wgłębiałem się, więc jest to sprawa do zbadania.
Poniżej schemat całego układu demonstracyjnego. Niestety, nie udało się zaprogramować i wykorzystać wszystkich jego możliwości - chyba pora przerzucić się na którąś z ATmeg...

Na koniec krótka konkluzja. Chcąc zbudować zegarek na ATtiny2313 nie musimy angażować do tego celu specjalizowanych układów, których programowa obsługa zaśmieci niepotrzebnie cenną pamięć mikrokontrolera - mamy przecież w naszym procesorku timer, który może generować przerwanie co jedną sekundę... ;-) Jednak zaletą zastosowania oddzielnego układu jest to, że zapewniając mu zasilanie (podtrzymanie) bateryjne, możemy mieć ciągły pomiar czasu nawet po wyłączeniu zasilania systemu mikroprocesorowego. Rozwiązanie takie zastosował kolega dołączając do RaspberryPi moduł zegara bazujący na bliźniaczym układzie PCF8563P - opis znajdziemy na jego blogu.

ERRATA:

Proszę koniecznie zajrzeć do wpisu: Programowanie AVR cz. 4,5: Poprawki związane z drobnym przeoczeniem.

Komentarze

Popularne posty z tego bloga

Niesamowicie prosty czujnik zmierzchowy.

Tym razem zero programowania, będzie natomiast nostalgiczno-wspomnieniowy układzik, lekko zmodyfikowany. Otóż kilka dni temu rozmawialiśmy w gronie znajomych o różnego rodzaju czujnikach zmierzchowych i czujnikach ruchu. Ponieważ należę do tych wariatów, co to hołdują jeszcze owej przestarzałej i kompletnie odrealnionej dziś zasadzie: "po co kupować, gdy można zrobić", stwierdziłem, że poskładam takie coś (czujnik zmierzchowy; sensor ruchu faktycznie lepiej nabyć, choćby ze względu na rozmiary ;)) i być może podłączę do jakiegoś mikrokontrolera. Przypomniało mi się też przy okazji, że znalazłem ostatnio w elektronicznych śmieciach stary fotorezystor (dla niewtajemniczonych: element zmieniający rezystancję, czyli opór elektryczny, pod wpływem działania strumienia światła) RPP130, jeden z kilku pozostałych po montowanych wieki temu układach tranzystorowych do zdalnego sterowania pracą urządzeń za pomocą latarki... No OK, nie było to specjalnie rozbudowane zdalne sterowanie ;) ...

Aktualizacja oprogramowania układowego w ESP-01 do najnowszej wersji NodeMCU

Oprogramowanie i projekt NodeMCU cieszą się niesłabnącym zainteresowaniem świata konstruktorów urządzeń IoT, zatem co jakiś czas warto odświeżyć sobie firmware w naszych płytkach ESP. Osobiście jestem przeciwnikiem zmienienia czegoś, co dobrze działa, tylko dla zasady czy z chęci cieszenia się świadomością posiadania najnowszej wersji, ale tym razem chodzi jednak o coś innego – zwiększenie funkcjonalności i zapewnienie poprawnego działania oraz kompatybilności z najnowszymi projektami i bibliotekami. W tytule tego artykułu jest mowa o najprostszych płytkach z układem ESP8266 – ESP-01 . To właśnie w oparciu o ten model opracowałem płytkę prototypową, o której pisałem w poprzednim rozdziale. Dotychczas wszystkie moje płytki ESP miały na pokładzie oprogramowanie NodeMCU w wersji 0.9.5 . Zorientowani choć trochę w temacie od razu zauważą (Google? Bing?), że wersja ta ma już co najmniej dwa lata... Najwyższy czas zatem na aktualizację.

Płytka prototypowa na bazie ESP8266 (ESP-01)

To nie jest kolejny artykuł traktujący od początku do... nieco dalej (bo na pewno nie do końca) o płytkach ESP8266 . Żeby się dowiedzieć, co to takiego, odwiedźcie proszę np. tę stronę (oraz wiele innych – poproście o pomoc Waszą ulubioną wyszukiwarkę): http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family . No ale żeby nie było, ESP8266 to układ zawierający na pokładzie wydajny mikrokontroler z rdzeniem RISC-owym, taktowany zegarem 40MHz (wersja, o której jest ten wpis) lub 80MHz, 512KB pamięci flash i podsystem komunikacji przez sieć WiFi . Jest powszechnie wykorzystywany jako swego rodzaju karta sieciowa do połączeń bezprzewodowych naszych urządzeń IoT , które budujemy w zaciszu domowych laboratoriów (i nie tylko). Układ montowany jest na płytkach występujących w kilku wersjach, różniących się przede wszystkim liczbą wyprowadzeń uniwersalnych, czyli GPIO – im większa liczba, tym większe możliwości wykorzystania układu (więcej urządzeń peryferyjnych itp.). Są też pewne ...