czwartek, 23 października 2014

Zegar RTC oparty o DS1307

Zegar czasu rzeczywistego jest spotykany w praktycznie każdym urządzeniu. Dzięki zastosowaniu bateryjki, która podtrzymuje proces odmierzania czasu możemy go nastawić praktycznie raz na zawsze. Po odłączeniu urządzenia od zasilania i ponownym go włączeniu jesteśmy zawsze "na czasie". Układ DS1307 komunikuje się z mikroprocesorem po magistrali I2C. Do chipu wymagane jest podłączenie tak zwanego kwarcu zegarkowego o częstotliwości 32.768kHz. Niżej mały podgląd standardowej aplikacji tego układu:
Na rysunku widać na liniach SDA i SCL interfejsu I2C rezystory podciągające zwykle o wartości 4,7k. Warto zwrócić uwagę na bateryjkę, gdy będziemy ją wsadzać w gniazdo, żeby nie pomylić polaryzacji, chociaż przyznam się szczerze, że kiedyś fazie testów podłączyłem ją odwrotnie, układ wydaje się być na to odporny. 

Na długie lata wystarczy bateryjka taka jaka można spotkać na płytach głównych komputerów PC, czyli CR2032 o napięciu 3V. Tutaj pełny datasheet układu DS1307: http://datasheets.maximintegrated.com/en/ds/DS1307.pdf. Odnajdziemy w nim informacje w jaki sposób się z nim komunikować. Dowiemy się tam, że tryb write następuje po wybraniu adresu 11010000 a tryb read po wybraniu 11010001 co daje odpowiednio liczby 208 i 209. Później już po kolei możemy wpisywać lub odczytywać dane z zegara takie jak sekundy, minuty, godziny, dni, dni tygodnia, miesiące, lata itd. Możemy ustawic czas 12 lub 24-godzinny. Domyślnie jest to 24h. Układ sam koryguje lata przestępne więc nie musimy się niczym przejmować po tym jak ustawimy raz na początku godzinę i datę. Skoro bateria będzie trzymać kilka lat proponuję, aby najpierw wrzucić program który ustawia datę, a później program tylko do odczytu danych z DS1307. Tak więc ustawmy zegar !

$regfile = "m16def.dat"
$crystal = 4000000
$baud = 9600

Config Sda = Porta.2
Config Scl = Porta.1

Dim Sekundy As Byte
Dim Minuty As Byte
Dim Godziny As Byte
Dim Dzien As Byte
Dim Dzientyg As Byte
Dim Miesiac As Byte
Dim Rok As Byte

Sekundy = 0
Minuty = 24
Godziny = 16
Dzien = 4
Dzientyg = 23
Miesiac = 10
Rok = 14

Sekundy = Makebcd(sekundy)
Minuty = Makebcd(minuty)
Godziny = Makebcd(godziny)
Dzien = Makebcd(dzien)
Dzientyg = Makebcd(dzientyg)
Miesiac = Makebcd(miesiac)
Rok = Makebcd(rok)


I2cstart
I2cwbyte 208
I2cwbyte 0
I2cwbyte Sekundy
I2cwbyte Minuty
I2cwbyte Godziny
I2cwbyte Dzien
I2cwbyte Dzientyg
I2cwbyte Miesiac
I2cwbyte Rok
I2cstop

Wait 4
Printbin 12
Print "Zegar RTC"
Print "ustawiono zegar"

Do
Loop
End
 Teraz gdy zegar mamy już ustawiony wczytujemy program do odczytu i wyświetlania godziny, daty i dnia tygodnia. Użyłem wyświetlacza z poprzedniego wpisu na blogu, czyli VFD sterowany poprzez UART. Poniżej kod programu:
$regfile = "m16def.dat"
$crystal = 4000000
$baud = 9600

Config Sda = Porta.2
Config Scl = Porta.1

Dim Sekundy As Byte
Dim Minuty As Byte
Dim Godziny As Byte
Dim Dzien As Byte
Dim Dzientyg As Byte
Dim Miesiac As Byte
Dim Rok As Byte

Dim Ssekundy As String * 2
Dim Sminuty As String * 2
Dim Sgodziny As String * 2
Dim Sdzien As String * 3
Dim Sdzientyg As String * 2
Dim Smiesiac As String * 2
Dim Srok As String * 2

Dim Petla As Word

Wait 4
Printbin 12
Print "Zegar RTC"
Print "Krzysztof MLR"
Wait 2
Printbin 12

Do

Incr Petla
If Petla = 20000 Then

I2cstart
I2cwbyte 208
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte 209
I2crbyte Sekundy , Ack
I2crbyte Minuty , Ack
I2crbyte Godziny , Ack
I2crbyte Dzien , Ack
I2crbyte Dzientyg , Ack
I2crbyte Miesiac , Ack
I2crbyte Rok , Nack
I2cstop

Sekundy = Makedec(sekundy)
Minuty = Makedec(minuty)
Godziny = Makedec(godziny)
Dzien = Makedec(dzien)
Dzientyg = Makedec(dzientyg)
Miesiac = Makedec(miesiac)
Rok = Makedec(rok)

Ssekundy = Str(sekundy)
Sminuty = Str(minuty)
Sgodziny = Str(godziny)
Sdzientyg = Str(dzientyg)
Smiesiac = Str(miesiac)
Srok = Str(rok)


Ssekundy = Format(ssekundy , "00")
Sminuty = Format(sminuty , "00")
Sgodziny = Format(sgodziny , "00")
Sdzientyg = Format(sdzientyg , "00")
Smiesiac = Format(smiesiac , "00")
Srok = Format(srok , "00")

If Dzien = 1 Then Sdzien = "Pon"
If Dzien = 2 Then Sdzien = "Wto"
If Dzien = 3 Then Sdzien = "Sro"
If Dzien = 4 Then Sdzien = "Czw"
If Dzien = 5 Then Sdzien = "Pia"
If Dzien = 6 Then Sdzien = "Sob"
If Dzien = 7 Then Sdzien = "Nie"


Print "ZegarRTC         " ; Sdzien;
Print Sgodziny ; ":" ; Sminuty ; ":" ; Ssekundy ; "  " ; Sdzientyg ; "." ; Smiesiac ; ".20" ; Rok;

Petla = 0

End If
Loop
End
  Teraz można się cieszyć funkcjonalnym zegarem. W kodzie programu użyłem kilka razy funkcji STR oraz FORMAT aby wygodniej wyświetlać informacje na wyświetlaczu, chodzi o to żeby liczby jak i nazwy dni miały stałą liczbe znaków, przykładowo zamiast 1.4.2014 będzie wyświetlać się zawsze 01.04.2014. Warto także wspomnieć, że funkcja PRINT bez znaku średnika na końcu zawsze wysyła na końcu znak CR (carriage return) co w niektórych przypadkach jest wręcz złośliwe, zwłaszcza, gdy chcemy wyświetlić znak na 20 (ostatnim) miejscu linii wyświetlacza. Efekt można podziwiać poniżej:
 

4 komentarze:

  1. No ja się niestety na tych rzeczach nie znam, więc nie będę w stanie budować samodzielnie takich urządzeń. Dla mnie zresztą najbardziej liczy się to, aby mieć jak najniższe rachunki za prąd. W takim wypadku doszłam do wniosku, żeby przejść do https://poprostuenergia.pl/ i jestem zdania, że to był bardzo mądry wybór.

    OdpowiedzUsuń
  2. Zobacz sobie ofertę tej firmy siłowniki hydrauliczne produkcja. jakość jej usług jest na najwyższym poziomie. Jestem pewna, że oferta ci się spodoba. Sama mam zamiar nawiązać współpracę z tą firmą.

    OdpowiedzUsuń
  3. W każdym urządzeniu elektronicznym znajdują się także obwody drukowane czyli płytki PCB. Czy można je samodzielnie wykonać? Proste obwody jeszcze jak najbardziej ale do profesjonalnych urządzeń to już trzeba zgłaszać się do fachowców. Tacy producenci jak https://tspcb.pl/ są w stanie wykonać płytkę pcb zgodnie z każdym projektem i oczekiwaniami klienta. Mają ku temu możliwości maszynowe i doświadczony zespół fachowców w zespole.

    OdpowiedzUsuń