- Wymagane materiały:
- Moduł RTC:
- Podłączanie DS3231 RTC z mikrokontrolerem PIC:
- Programowanie PIC dla modułu RTC:
- Krótkie wyjaśnienie pliku nagłówkowego PIC16F877a_DS3231.h:
- Symulacja:
- Wyświetl godzinę i datę na wyświetlaczu LCD:
Prawie wszystkie urządzenia wbudowane są zaprojektowane do interakcji ze światem rzeczywistym. Działają jako pomost do komunikacji między światem cyfrowym a światem rzeczywistym. Aby proces ten był łatwiejszy i wydajniejszy, świat cyfrowy musiał czasami śledzić czas i datę rzeczywistego świata. W ten sposób świat cyfrowy będzie wiedział, jaka jest godzina / dzień w świecie rzeczywistym, a nawet może rozróżnić dzień i noc. Może również służyć jako źródło czasu do wykonywania określonych zadań o określonej godzinie lub w określonym dniu. Więc tutaj łączymy moduł RTC z mikrokontrolerem PIC i wyświetlamy czas i datę na wyświetlaczu LCD 16x2. Ten projekt może być również używany jako zegar cyfrowy.
Wymagane materiały:
- Regulowane zasilanie 5 V.
- PIC16F877A
- Oscylator kwarcowy 20 Mhz
- Kondensator 33pf - 2
- Rezystor 10K, 5,1K, 1K
- Moduł DS3231 RTC
- POT -10k
- Moduł LCD 16 * 2
- Przewody łączące
Moduł RTC:
Najczęstszym sposobem śledzenia czasu lub daty w świecie rzeczywistym przez mikrokontroler jest użycie układu scalonego RTC. Termin RTC oznacza zegar czasu rzeczywistego; ten układ scalony śledzi aktualny czas i datę w świecie i udostępnia te informacje mikrokontrolerowi na żądanie. Układ scalony RTC, którego tutaj używamy, jest najpopularniejszym i dokładnym DS3231. Ten układ scalony dryfuje tylko o kilka sekund każdego roku, dzięki czemu jest wysoce niezawodny. Na potrzeby tego samouczka używamy modułu DS3231 RTC, który można łatwo kupić online lub w lokalnym sklepie ze sprzętem. Moduł jest wyposażony w baterię pastylkową 3 V, która zawsze zasila moduł RTC, a zatem po ustawieniu godziny i daty będzie aktualizowana tak długo, jak długo bateria pastylkowa będzie aktywna.
Moduł DS3231 komunikuje się za pomocą protokołu I2C, więc jeśli nie wiesz, co to jest i jak jest używany z PIC, przeczytaj samouczek I2C z PIC przed kontynuowaniem. Również w tym samouczku zamierzamy utworzyć plik nagłówkowy, który może być użyty do komunikacji z naszym modułem RTC, a także przetestować to samo na sprzęcie, wyświetlając godzinę i datę na wyświetlaczu LCD, więc ważne jest również nauczenie się interfejsu LCD wyświetlacz z mikrokontrolerem PIC. Plik nagłówkowy utworzony w tym samouczku dla DS3231 może być później używany / modyfikowany w celu dostosowania do aplikacji.
Wcześniej używaliśmy DS3231 RTC z Arduino w poniższych projektach:
- Automatyczny karmnik dla zwierząt wykorzystujący Arduino
- Rejestrator danych Arduino
Podłączanie DS3231 RTC z mikrokontrolerem PIC:
Schemat obwodu zegara cyfrowego opartego na mikrokontrolerze PIC przedstawiono poniżej. Jak wspomniano wcześniej, DS3231 działa z pomocą komunikacji I2C, więc będzie miał pin zegara szeregowego (SCL) i szeregowy (SDA), który musi być podłączony do pinów I2C na naszym PIC, który jest pinem 18 (SCL) i pin 23 (SDA). Rezystor podciągający o wartości 4,7 k jest używany do utrzymywania magistrali w stanie wysokim podczas bezczynności.
Wyświetlacz LCD jest również podłączony do styków portu D, aby wyświetlać aktualną datę i godzinę. Pełny schemat obwodu został zaprojektowany na proteusie i jest pokazany poniżej. Zamierzamy użyć tego samego do symulacji lub programowania w dalszej części tego samouczka.
Postępuj zgodnie ze schematem obwodu i wykonaj odpowiednie połączenia, pole I2C pokazane powyżej jest używane do debugowania I2C, więc nie uwzględnimy tego w naszych połączeniach. Nie pokazano również, że moduł RTC musi być zasilany napięciem + 5 V za pomocą pinów Vcc i uziemienia na module. Użyłem mojej płytki prototypowej do wykonania połączenia i po wykonaniu wymaganych połączeń moja konfiguracja wyglądała mniej więcej tak poniżej.
Jeśli jesteś nowy w mikrokontrolerze PIC, zacznij od Wprowadzenie do mikrokontrolera PIC.
Programowanie PIC dla modułu RTC:
Kompletny program dla tego zegara cyfrowego można pobrać z pliku ZIP tutaj. Program zawiera łącznie trzy pliki nagłówkowe. Są to plik lcd.h do pracy z wyświetlaczem LCD, plik PIC16F877a_I2C.h do pracy z komunikacją I2C z PIC i wreszcie PIC16F877a_DS3231.h plik do pracy z modułami RTC. Wszystkie trzy pliki nagłówkowe są wymagane dla tego programu i są dostępne w powyższym pliku ZIP. W dalszej części wyjaśnię główny program, który wykorzystuje wszystkie te pliki nagłówkowe do odczytania godziny i daty z modułu RTC i wyświetlenia ich na ekranie LCD. Następnie wyjaśnię, co faktycznie dzieje się w pliku nagłówkowym RTC. Jak zawsze, program należy rozpocząć od ustawienia bitów konfiguracyjnych i częstotliwości zegara na 20 MHz, ponieważ właśnie tego używaliśmy w naszym sprzęcie.
#pragma config FOSC = HS // Bity wyboru oscylatora (oscylator HS) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT wyłączony) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT włączony) # pragma config BOREN = ON // Brown-out Reset Enable bit (BOR włączony) #pragma config LVP = OFF // Niskonapięciowe (pojedyncze zasilanie) In-Circuit Serial Programming Bit Enable (RB3 to cyfrowe we / wy, HV włączone MCLR musi być używany do programowania) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (ochrona przed zapisem wyłączona; cała pamięć programu może być napisane do kontroli EECON) #pragma config CP = OFF // Bit ochrony kodu pamięci programu Flash (ochrona kodem wyłączona) #define _XTAL_FREQ 20000000
Następnym krokiem byłoby zdefiniowanie pinów LCD, jeśli spojrzysz na sprzęt, zauważysz, że połączyliśmy piny LCD z PORT D od RD2 do RD7, więc definiujemy to samo, jak pokazano poniżej.
# zdefiniować RS RD2 # zdefiniować EN RD3 # zdefiniować D4 RD4 # zdefiniować D5 RD5 # zdefiniować D6 RD6 # zdefiniować D7 RD7
Domyślnie przy zakupie modułu RTC nie zostanie w nim ustawiony prawidłowy czas i data, dlatego musimy ustawić go przez nasz program. Dlatego deklarujemy zmienną dla każdego pliku danych i pliku w czasie rzeczywistym i dacie, jak pokazano poniżej. W momencie wgrywania programu mój czas i data to 10:55 w dniu 6-5-2018, więc ustawiłem zmienne jak poniżej. Możesz ustawić prawidłową godzinę i datę zgodnie z aktualną aplikacją
/ * Ustaw bieżącą wartość daty i godziny poniżej * / int sec = 00; int min = 55; int godzina = 10; int data = 06; int miesiąc = 05; int rok = 18; / * Ustaw datę i godzinę * /
Następnie dodajemy wszystkie pliki nagłówkowe, o których rozmawialiśmy. Jeśli pobrałeś i otworzyłeś program z pliku ZIP, nie będzie problemu, w przeciwnym razie upewnij się, że wszystkie pliki nagłówkowe zostały dodane do pliku źródłowego lub katalogu projektu.
#zawierać
Ponieważ użyliśmy PORT D jako pinów wyjściowych do połączenia wyświetlacza LCD, musimy zadeklarować je jako piny wyjściowe w naszym programie i zainicjować wyświetlacz LCD, jak pokazano poniżej
TRISD = 0x00; // Zrób piny Port D jako outptu dla interfejsu LCD Lcd_Start (); // Zainicjuj moduł LCD
Moduł RTC komunikuje się za pomocą protokołu I2C więc musimy włączyć komunikację I2C naszym mikrokontrolerem PIC. Większość urządzeń, w tym nasze moduły DS3231, ma częstotliwość roboczą I2C 100 kHz, więc rozpoczynamy komunikację I2C z częstotliwością 100 kHz, jak pokazano poniżej
I2C_Initialize (100); // Zainicjuj I2C Master z zegarem 100 KHz
Jak tylko ustanowimy komunikację I2C z modułem RTC, pierwszą rzeczą, jaką robimy, jest ustawienie aktualnego czasu i daty, które wprowadziliśmy do naszego programu. Można to zrobić, wywołując funkcję set_Time_Date, jak pokazano poniżej. Po ustawieniu godziny i daty moduł automatycznie je śledzi i zwiększa ich wartość, tak jak zegar cyfrowy.
Set_Time_Date (); // ustaw czas i datę w module RTC
Aby wskazać, że program został uruchomiony, wyświetlimy małą wiadomość intro, która pozostanie na ekranie przez 2 sekundy. Ten komunikat wyświetli RTC z PIC - Circuit Digest na ekranie. Program do tego samego pokazano poniżej
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("RTC z PIC"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
Wewnątrz naszej nieskończonej while pętli powinniśmy odczytać aktualny czas i datę, a następnie wyświetla wartości w naszym ekranie LCD. Aby odczytać czas i datę z modułu RTC, można użyć funkcji Update_Current_Time_Date, jak pokazano poniżej. Ta funkcja odczyta wartość z modułu RTC i zaktualizuje zmienne sec, min, godzina, data, miesiąc i rok o bieżące wartości. Następnie możemy ich użyć do naszych celów.
Update_Current_Date_Time (); // Odczytaj aktualną datę i godzinę z modułu RTC
Zmienne są typu integer, musimy je przekonwertować na pojedyncze znaki, abyśmy mogli je wyświetlić na ekranie LCD. Więc używamy operatora modułu, aby uzyskać cyfrę jednokrotną i podzielić zmienną przez 10, aby uzyskać cyfrę dziesiątek. To samo dotyczy wszystkich zmiennych.
// Podziel znak na znak do wyświetlenia na lcd char sec_0 = sec% 10; char sec_1 = (sec / 10); char min_0 = min% 10; char min_1 = min / 10; char godzina_0 = godzina% 10; char hour_1 = godzina / 10; char data_0 = data% 10; znak data_1 = data / 10; char month_0 = miesiąc% 10; char month_1 = miesiąc / 10; znak rok_0 = rok% 10; char rok_1 = rok / 10;
Pozostaje tylko wyświetlić informacje, które uzyskaliśmy na ekranie LCD. Można to łatwo zrobić za pomocą funkcji LCD, które omówiliśmy wcześniej w naszym samouczku LCD. Tak więc kod do wyświetlania czasu jest podany poniżej, ta sama metoda służy również do wyświetlania daty. Po wyświetleniu danych podawane jest opóźnienie 500 ms, dzięki czemu działa ono jako interwał aktualizacji.
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("CZAS:"); Lcd_Print_Char (godzina_1 + „0”); Lcd_Print_Char (godzina_0 + „0”); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0');
Krótkie wyjaśnienie pliku nagłówkowego PIC16F877a_DS3231.h:
Rzeczy wyjaśnione do tej pory wystarczą, aby użyć modułu DS3231 z PIC do własnych projektów, ale dla ciekawskich chcieliby wiedzieć, co faktycznie dzieje się w pliku nagłówkowym, a dane są faktycznie odbierane z modułu RTC przez PIC, czytaj dalej.
Najlepszym sposobem, aby przez to przejść, jest całkowite przeczytanie arkusza danych DS3231. Krótko mówiąc, co jest potrzebne, moduł działa jako slave dla PIC, a adres wszystkich modułów DS3231 to D0. Zatem zapisujemy dane do modułu musimy podać adres D0, a do odczytu danych z RTC musimy podać adres D1. Jeśli przekażemy adres zapisu do modułu RTC, przygotujemy się do pobrania danych z PIC, tak więc kolejne dane zapisane przez PIC zostaną odebrane i zapisane w module RTC. Podobnie, jeśli wyślemy adres do Readnastępnie PIC powinien przygotować się do odczytu wartości z RTC, ponieważ moduł RTC rozpocznie wysyłanie wszystkich posiadanych danych. Sekwencja bitów zarówno dla D0, jak i D1 jest pokazana poniżej z arkusza danych. Zwróć uwagę, że adres 0b11010000 oznacza D0 (zapis), a 0b11010001 oznacza D01 (odczyt)
Kiedy PIC wysyła adres D0 lub D1 do zapisu lub odczytu, następujące dane powinny być odczytywane lub zapisywane w kolejności. Kolejność ta została przedstawiona w poniższej tabeli. Zatem pierwsze dane to s (00h), następnie minuty (01h), a następnie godziny (02h), a następnie dzień (03h) i do MSB temperatury.
Moduł RTC nie rozumie wartości dziesiętnych, komunikuje się tylko poprzez wartości BCD. Dlatego przed zapisaniem jakichkolwiek wartości do modułu RTC należy je przekonwertować na BCD, a także wartości otrzymane z modułu RTC będą w formacie BCD i należy je przekonwertować na dziesiętne, aby miały dla nas sens. Mając to na uwadze, stwórzmy wszystkie funkcje wymagane do korzystania z modułu RTC.
Funkcje BCD_2_DEC i DEC_2_BCD:
Pierwsze dwie funkcje byłyby używane do konwersji danych BCD na Decimal i Decimal Data na BCD, ponieważ moduł RTC obsługuje tylko BCD. Formuły do konwersji BCD na Decimal i BCD na Decimal to
Dziesiętny = (BCD >> 4) * 10 + (BCD i 0x0F) BCD = ((Dziesiętny / 10) << 4) + (Dziesiętny% 10)
Musimy tylko użyć tych dwóch formuł, aby utworzyć funkcję, która przyjmuje przeciwną jednostkę jako parametr i konwertuje ją do wymaganego formatu i zwraca ją, funkcję wykonującą to samo pokazano poniżej
int BCD_2_DEC (int to_convert) { return (to_convert >> 4) * 10 + (to_convert & 0x0F); } int DEC_2_BCD (int to_convert) { return ((to_convert / 10) << 4) + (to_convert% 10); }
Funkcja Set_Time_Date ():
Ta funkcja zapisze wartość czasu i daty z PIC do modułu RTC. Wartości czasu rzeczywistego i daty muszą być aktualizowane przez użytkownika w zmiennych sek, min, godzina, data, miesiąc i rok. Wartości te zostaną następnie przekonwertowane na BCD i zapisane w module RTC.
Jak omówiliśmy, aby zapisać wartość do modułu RTC, musimy przekazać adres D0 i napisać bit 0, aby zainicjować proces zapisu. Następnie możemy przesłać dane w kolejności pokazanej w powyższej tabeli.
void Set_Time_Date () { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_Write (DEC_2_BCD (s)); // aktualizacja sec I2C_Write (DEC_2_BCD (min)); // aktualizacja min I2C_Write (DEC_2_BCD (godzina)); // aktualizacja godziny I2C_Write (1); // zignoruj aktualizację dnia I2C_Write (DEC_2_BCD (data)); // data aktualizacji I2C_Write (DEC_2_BCD (miesiąc)); // aktualizacja miesiąca I2C_Write (DEC_2_BCD (rok)); // aktualizacja roku I2C_End (); }
Funkcja Update_Current_Date_Time ():
Ostatnią funkcją w bibliotece jest odczyt czasu i daty z modułu RTC i przekazanie ich do mikrokontrolera PIC. Ta funkcja jest podzielona na trzy segmenty, z których jeden inicjuje proces odczytu, a drugi odczytuje wartości i zapisuje je w zmiennych globalnych, takich jak sek, min, godzina, data, miesiąc i rok. Trzecim jest uznanie, że odczyt się powiódł.
Zauważ, że dla każdej akcji komunikacja I2C powinna zostać rozpoczęta i zakończona.
Aby odczytać wartości z RTC, musimy wysłać adres D0, po którym następuje 0. To spowoduje, że moduł RTC wyśle wszystkie posiadane wartości w kolejności pokazanej w tabeli powyżej. Możemy po prostu je przeczytać, przekonwertować je na Decimal i zapisać do zmiennych w tej samej kolejności.
Na koniec, po zakończeniu odczytu, moduł RTC wyśle bit potwierdzenia, który również należy odczytać i potwierdzić.
void Update_Current_Date_Time () { // START do odczytu I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_End (); // CZYTAJ I2C_Begin (); I2C_Write (0xD1); // Zainicjuj odczyt danych sec = BCD_2_DEC (I2C_Read (1)); min = BCD_2_DEC (I2C_Read (1)); godzina = BCD_2_DEC (I2C_Read (1)); I2C_Read (1); data = BCD_2_DEC (I2C_Read (1)); miesiąc = BCD_2_DEC (I2C_Read (1)); rok = BCD_2_DEC (I2C_Read (1)); I2C_End (); // KONIEC Czytanie I2C_Begin (); I2C_Write (0xD1); // Zainicjuj odczyt danych I2C_Read (1); I2C_End (); }
Symulacja:
Projekt można symulować za pomocą oprogramowania symulacyjnego Proteus. Wykonaj połączenia zgodnie ze schematem obwodu i załaduj plik szesnastkowy do sterownika PIC. Podczas symulacji zobaczysz dwa wyskakujące okienka oraz datę i godzinę wyświetlane na ekranie LCD, jak pokazano poniżej.
Mała na górze pokazuje aktualny czas i datę wewnątrz modułu RTC, a drugie wyskakujące okienko to debugger I2C. Jest to doskonałe narzędzie do sprawdzania, jakie dane są faktycznie przekazywane i wychodzące, błąd I2C.
Wyświetl godzinę i datę na wyświetlaczu LCD:
Gdy twój sprzęt będzie gotowy, a kod zostanie pobrany jako plik ZIP przez podany link, otwórz program za pomocą MPLABX IDE. Musisz najpierw uruchomić IDE i użyć opcji open project i przejrzeć zawartość pliku ZIP i otworzyć folder.X.
Po prostu sprawdź, czy program się kompiluje i prześlij kod do swojego sprzętu za pomocą PicKit3. Zaraz po załadowaniu programu powinieneś zobaczyć komunikat wprowadzający, a następnie powinna wyświetlić się godzina i data, jak pokazano poniżej.
Jeśli nic nie widać na wyświetlaczu LCD, sprawdź połączenia i upewnij się, że poziom kontrastu jest ustawiony prawidłowo, zmieniając potencjometr. W ten sposób możesz wyświetlać godzinę i datę we wszystkich projektach mikrokontrolera PIC i używać tego jako zegara cyfrowego. Mam nadzieję, że nauczyłeś się czegoś nowego i podobał Ci się ten samouczek. Jeśli napotkałeś jakiś problem, opublikuj je w komentarzach poniżej lub na forach w celu uzyskania pomocy technicznej.
Pobierz pełny program PIC dla tego projektu z plikami nagłówkowymi stąd i sprawdź wszystkie nasze samouczki PIC tutaj.