Zegar binarny
1. Cele.
Celem projektu było wykonanie zegara wyświetlającego czas rzeczywisty w formie binarnej.
Z uwagi na to iż zegar będzie znajdował się w gablocie bez dostępu do stałego źródła zasilania a obecność osób przewidywana jest tylko w ciągu dnia wymagane jest by wyłączyć wyświetlacz w godzinach od 18:00 do 7:00.
Zegar ma posiadać wyprowadzenie uruchamiające w ciągu dnia inne urządzenia znajdujące się w gablocie a wyłączające je w godzinach nocnych.
Projekt został wykonany do zastosowań dydaktycznych.
Projekt urządzenia.
Zegar przedstawia godzinę oraz minuty w formie binarnej. W tym celu został zaprojektowany wyświetlacz zbudowany z ośmiu LED. Sześć LED zostało uszeregowanych w jednym rzędzie i odpowiada za wyświetlenie wartości binarnej na sześciu bitach. Maksymalna liczba jaką można zaprezentować na sześciu bitach wynosi 63 (dec), czyli 111111 (bin). Zatem w zupełności wystarcza do prezentacji godzin z zakresu 0-24 i minut 0-59. Pozostałe dwie LED pełnią funkcję informacyjną. Zapalenie pierwszej z nich oznacza iż prezentowane są godziny, natomiast druga powiadamia iż wyświetlane są minuty. Zapalenie obydwu diod informuje o prezentacji sekund.
Prezentacja czasu jest wykonywana rotacyjne w kolejności: sekundy, minuty a następnie godziny.
Działaniem zegara zarządza mikrokontroler PIC16F87. Odczytuje on za pośrednictwem magistrali I2C aktualny czas z zegara DS1307, konwertuje na formę binarną i przedstawia go zapalając odpowiednie LED.
Ustawienie czasu wykonywane jest dwoma przyciskami sterującymi obsługiwanymi przez program mikrokontrolera. Po dokonaniu korekty czasu zapisywany jest on do zegara DS1307.
Rys.1. Moduły urządzenia.
Projekt PCB.
Rozmiar PCB wynosi 92mm na 80mm, montaż elementów wykonany jest w technologii przewlekanej (THT). Płyta ma jedną warstwę sygnałową, należy wykonać jeden mostek oznaczony kolorem niebieskim. Płytka została udostępniona w fabryce PCBWay gdzie można zamówić jej wykonanie pod tym linkiem.
Rys.2. Projekt PCB.
4. Podzespoły urządzenia.
Rys.3. Rozmieszczenie podzespołów na PCB.
Tab. Lista podzespołów
Oznaczenie | Uwagi |
U1 | PIC16F87 |
U2 | DS1307 |
U3 | LM7805CT |
C1, C2 | 22pF |
C3 | 10uF |
C4 | 1uF |
D1 – D8 | LED czerwony |
Q1, Q2 | 2N3904 |
X1 | kwarc 4MHz |
X2 | kwarc 32,768kHz |
R1-R6 | 150 |
R7, R8 | 10k |
R9, R10, R11 | 10k |
R12, R13 | 4,7k |
BAT | Bateria 3V CR2032 do montażu na PCB |
S1, S2 | microswitch |
Rys.4. Wizualizacja projektu.
4.1. Mikrokontroler PIC16F87.
W projekcie użyto mikrokontrolera PIC16F87 w obudowie typu DIP18, taktowany jest on zegarem o częstotliwości 4MHz. Układ posiada następujące układy peryferyjne: 1-A/E/USART, 1-SSP(SPI/I2C). Pamięć programu mikrokontrolera wynosi 7KB.
Rys.5. Wyprowadzenia uC PIC16F87.
4.2. Zegar czasu rzeczywistego DS1307.
Układ scalony DS1307 jest zegarem czasu rzeczywistego. Mikrokontroler odczytuje aktualny czas z zegara za pośrednictwem magistrali I2C. W przypadku zaniku zewnętrznego zasilania, zegar automatycznie przełącza się na zasilanie awaryjne z baterii 3,2V.
Rys.6. Zegar czasu rzeczywistego DS1307.
4.3. Stabilizator.
Urządzenie zostało wyposażone w stabilizator zasilania LM7805CT zapewniający zabezpieczenie układu przed pojawieniem się napięć wyższych od dopuszczalnych dla jego podzespołów.
4.4. Gniazdo zasilania.
Rys.7. Polaryzacja zasilania
Do gniazda zasilania należy podłączyć akumulator lub zasilacz o napięciu nie mniejszym niż 7V oraz nie przekraczającym napięcia 13V (z uwagi na duże straty cieplne na LM7805CT). Napięcie niższe od 7V może zaburzyć pracę układu co objawia się niepoprawnym odczytem czasu z układu LM7805CT.
5. Obsługa urządzenia.
Urządzenie wymaga w trakcie pierwszego uruchomienia ustawienia minut oraz godziny.
By ustawić aktualny czas należy przytrzymać przycisk „SET” (S1) aż do chwili gdy zegar zasygnalizuje przejście w tryb ustawiania godzin poprzez kilkukrotne mignięcie diodami informacyjnymi a następnie zapaleniem diody „godziny” (D8).
Następnie zostają wyświetlone aktualnie ustawione minuty, które można zwiększać poprzez kliknięcia przycisku „+” (S2) aż do chwili ustawienia oczekiwanej wartości.
Zatwierdzenie ustawienia dokonywane jest poprzez kliknięcie przycisku „SET” (S1).
Urządzenie sygnalizuje przejście w stan ustawienia godzin poprzez kilkukrotne mignięcie diodami informacyjnymi a następie zapaleniem diody „godziny” (D7).
Zostaje wyświetlona aktualnie ustawiona godzina, którą można zmienić poprzez kliknięcia przycisku „+” (S2) aż do uzyskania żądanej wartości.
Zatwierdzenie ustawienia wykonywane jest po kliknięciu przycisku „SET” (S1).
Sekundy zostają wyzerowane w chwili zapisania ustawień.
6. Program.
Program został napisany w języku C dla kompilatora CCS, źródło programu dostępne jest do pobrania w repozytorium
http://repository.noweenergie.org/Repo/pic/zegar_binarny/src
Wgranie programu do mikrokontrolera może zostać wykonane za pomocą programatora JDM
6.1. Rozpoczęcie programu – konfiguracja.
Kod rozpoczyna się od podłączenia pliku nagłówkowego zawierającego definicje mikrokontrolera PIC16F87.
Następnie został zdefiniowany zegar taktowany przez zewnętrzny kwarc 4MHz.
Bity konfiguracyjne (fuse bit) zostały ustawione następująco:
- XT – zewnętrzny rezonator kwarcowy,
- NOWDT – wyłączenie systemu watchdog wbudowanego w mikrokontroler,
- MCLR – aktywowanie pinu „master clear” resetującego mikrokontroler (pin4),
- NOBROWNOUT – wyłączenie automatycznego resetu przy spadku napięcia,
- NOPROTECT – wyłączenie zabezpieczenia kodu przed odczytem.
#use delay(clock=4MHz)
#fuses XT, NOWDT, MCLR, NOBROWNOUT, NOPROTECT
Podłączenie zewnętrznych plików w których zawarte są procedury konwersji liczbowych i obsługi zewnętrznego zegara DS1307.
#include „conversion.c”
#include „ds1307.c”
Definicja pinów mikrokontrolera w celu łatwiejszej identyfikacji w kodzie
#define bit3 PIN_A0
#define bit2 PIN_A1
#define bit1 PIN_A2
#define on_time PIN_A3
#define on_mode PIN_A4
#define button_set PIN_B2
#define button_plus PIN_B3
#define bit5 PIN_B6
#define bit4 PIN_B7
#define bit6 PIN_B5
6.2. Zmienne globalne.
Zadeklarowano tablicę typu byte zawierającą trzy elementy. Tablica przechowuje aktualny czas w formacie: godziny, minuty, sekundy
byte t_real[] = {0, 0, 0};
6.3. Funkcje.
Następnie w źródle programu zostały umieszczone funkcje do których będą występowały często odwołania w głównej pętli programu.
6.3.1. Obsługa zegara RTC.
Funkcje odwołują się do zdefiniowanych w podłączonym pliku ds1307.c procedur obsługujących układ DS1307 poprzez magistralę I2C. Dodatkowo odczyt konwertowany jest za pomocą funkcji bcdToDec() i decToBcd() zdefiniowanych w pliku conversion.c
Odczyt zegara
void read_time()
{
t_real[2] = bcdToDec(read_ds1307 (0)); // read second
t_real[1] = bcdToDec(read_ds1307 (1)); // read minute
t_real[0] = bcdToDec(read_ds1307 (2)); // read hour
}
Zapis czasu do zegara
void set_time()
{
write_ds1307 (4, decToBcd(1)); //day
write_ds1307 (5, decToBcd(1)); //month
write_ds1307 (6, decToBcd(1)); //year
write_ds1307 (2, decToBcd(t_real[0])); //hour;
write_ds1307 (1, decToBcd(t_real[1])); //minute
write_ds1307 (0, decToBcd(t_real[2])); //second
}
6.3.2. Obsługa wyświetlacza.
Ustawienie danych
Funkcja ustawia stan na pinach mikrokontrolerach odpowiadający danej wartości, tak by była ona poprawnie zaprezentowana na bitach wyświetlacza.
void show(byte n){
delay_ms(2);
if (n & 1) Output_high(bit1);
else Output_low(bit1);
delay_ms(2);
n >>= 1;
if (n & 1) Output_high(bit2);
else Output_low(bit2);
delay_ms(2);
n >>= 1;
if (n & 1) Output_high(bit3);
else Output_low(bit3);
delay_ms(2);
n >>= 1;
if (n & 1) Output_high(bit4);
else Output_low(bit4);
delay_ms(2);
n >>= 1;
if (n & 1) Output_high(bit5);
else Output_low(bit5);
delay_ms(2);
n >>= 1;
if (n & 1) Output_high(bit6);
else Output_low(bit6);
delay_ms(2);
}
Wyczyszczenie wyświetlacza
void clear(){
delay_ms(10);
Output_low(on_mode);
Output_low(on_time);
Output_low(bit1);
Output_low(bit2);
Output_low(bit3);
Output_low(bit4);
Output_low(bit5);
Output_low(bit6);
delay_ms(10);
}
Miganie diodami informacyjnymi
void blink(){
for(int8 x=0;x<10;x++){
clear();
delay_ms(50);
Output_high(on_mode);
show(5);
delay_ms(50);
}
}
6.4. Funkcja Main.
Główna funkcja programu rozpoczyna się od odczekania 1 sekundy od podania zasilania do startu zegara.
delay_ms(1000);
Następnie inicjowany jest zegar DS1307 funcjami zdefiniowanymi w pliku ds1307.c
init_DS1307();
write_ds1307(0,read_ds1307(0) & 0x7F); // enable oscillator(bit 7 =0)
Następnie w niekończącej się pętli realizowane są funkcjonalności:
- ustawienia czasu,
- odczytu czasu z RTC,
- prezentacji czasu na wyświetlaczu.
6.4.1. Ustawienie czasu.
W przypadku naciśnięcia przycisku „SET” następuje zamiganie diodami informacyjnymi i przejście w stan ustawiania godzin i minut.
if (input(button_set) == true) {
blink();
delay_ms(500);
Wyczyszczenie ekranu i poinformowanie, że następuje programowanie minut.
clear();
Output_high(on_mode);
show(1);
Do chwili gdy nie został wciśnięty przycisk „SET” zegar oczekuje na wprowadzenie nowej wartości minut. Aktualne ustawienia są wyświetlane na ekranie a inkrementacja minut dokonywana jest po kliknięciu przycisku „+”.
delay_ms(1000);
//ustawienie minut
while (input(button_set) == false){
show_time(t_real[1]);
if (input(button_plus) == true){
if (t_real[1]<60){
t_real[1] = t_real[1] + 1;
}
else {
t_real[1] = 0;
}
}
delay_ms(300);
}
Po kliknięciu przycisku „SET” zegar informuje że następuje przejście do programowania godzin.
blink();
clear();
Output_high(on_mode);
show(4);
Do chwili gdy nie został wciśnięty przycisk „SET” zegar oczekuje na wprowadzenie nowej wartości minut. Aktualne ustawienia są wyświetlane na ekranie a inkrementacja minut dokonywana jest po kliknięciu przycisku „+”.
delay_ms(1000);
while (input(button_set) == false){
show_time(t_real[0]);
if (input(button_plus) == true){
if (t_real[0]<24){
t_real[0] = t_real[0] + 1;
}
else {
t_real[0] = 0;
}
}
delay_ms(300);
}
Po kliknięciu przycisku „SET” zegar informuje że czas został zprogramowany.
set_time();
blink();
}
Następuje zakończenie obsługi programowania czasu.
6.4.2. Odczyt czasu z RTC.
Odczyt czasu realizowany jest przez funkcję zdefiniowaną na początku kodu źródłowego (rozdział 6.3.1). Po wyczyszczeniu tablicy w której przechowywane są dane, zostają wczytane nowe.
t_real[0] = 0; //h
t_real[1] = 0; //m
t_real[2] = 0; //s
read_time();
6.4.3. Prezentacja czasu na wyświetlaczu.
Z uwagi na to iż zegar ma być włączony w godzinach od 7:00 do 18:00 następuje sprawdzenie tej zależności
if (t_real[0]>6 && t_real[0]<18){
W przypadku jej spełnienia, zgodnie z założeniami następuje podanie napięcia na pin B0 mikrokontrolera i włączenie urządzeń zewnętrznych, sterowanych zegarem.
Output_high(PIN_B0);
Następnie prezentowany jest czas na wyświetlaczu. Po jego wyczyszczeniu, zostaje wyświetlona informacja, że przedstawione będą sekundy.
clear();
Output_high(on_mode);
show(5);
delay_ms(1000);
Wyświetlenie sekund na wyświetlaczu
show_time(t_real[2]);
Output_high(on_time);
delay_ms(2000);
Informacja, że zegar będzie wyświetlał minuty
clear();
Output_high(on_mode);
show(1);
delay_ms(1000);
Wyświetlenie minut
show_time(t_real[1]);
Output_high(on_time);
delay_ms(2000);
Informacja o prezentacji godzin
clear();
Output_high(on_mode);
show(4);
delay_ms(1000);
show_time(t_real[0]);
Output_high(on_time);
delay_ms(2000);
}
W przypadku, gdy jest już po godzinie 18 a przed godziną 6, następuje wyłączenie urządzeń zewnętrznych sterowanych zegarem.
else{
Output_low(PIN_B0);
}
}
7. Odnośniki.
Pliki projektu:
- Repozytorium zawierające pliki projektu
- uC.hex – wsad z programem dla mikrokontrolera.
- Projekt PCB – do odczytu w programie DipTrace.
- Projekt PCB w formacie PDF
- Rozmieszczenie podzespołów na PCB w formacie PDF.
- Źródło programu
Linki:
- Płytka PCB zegara binarnego do zamówienia w PCBWay.
Noty katalogowe: