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.

moduly-284x300 Zegar binarny

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.

pcb-270x300 Zegar binarny

Rys.2. Projekt PCB.

 

4. Podzespoły urządzenia.

rozmieszczenie_podzespolow-270x300 Zegar binarny

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

zegar_binarny-288x300 Zegar binarny

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.

PIC16F87-300x144 Zegar binarny

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.

ds1307-300x195 Zegar binarny

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.

zasilanie Zegar binarny

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:

Linki:

Noty katalogowe:

  • 2N3904 – tranzystor bipolarny.
  • PIC16F87 – mikrokontroler.
  • DS1307 – zegar czasu rzeczywistego.