02-2005_039-042.pdf
(
742 KB
)
Pobierz
ep_02_039-042.indd
Zegar szachowy
Zegar szachowy
AVT-378
Na łamach Elektroniki
Praktycznej wielokrotnie
już mogliśmy spotkać opisy
przeróżnych zegarów. Były
wszelkiego rodzaju timery,
budziki, stopery, zegary cyfrowe
oraz analogowe, jednym słowem
wszystko co tylko można sobie
wymarzyć. W niniejszym artykule
pojawi się opis kolejnego licznika
czasu – zegara szachowego.
Rekomendacje:
projekt polecany jest tym
miłośnikom szachów, którzy
chcieliby własnoręcznie wykonać
zegar aby uatrakcyjnić rozgrywki i
dodać do nich szczyptę emocji.
Kolejnym układem przeznaczo-
nym do odliczania czasu publiko-
wanym w Elektronice Praktycznej
jest zegar szachowy. W niniejszym
artykule zostanie opisany układ
posiadający wszystkie funkcje tra-
dycyjnych zegarów tego typu, któ-
ry został rozszerzony o dodatkowe
opcje, jak np.: możliwość gry na
tzw. „przewagi czasowe”, czy też
zliczanie całkowitego czasu gry nie-
zależnie dla obu graczy.
Na rynku zegarów szachowych
wersje elektroniczne ustępują miej-
sca swoim „wskazówkowym” od-
powiednikom (jedno z takich wła-
śnie rozwiązań można zobaczyć na
fot. 1
). Jednak w domowym warsz-
tacie elektronika hobbysty dużo ła-
twiej jest wykonać zegar cyfrowy
niż wskazówkowy.
Typowy zegar składa się
z dwóch identycznych mecha-
nizmów zamkniętych razem we
wspólnej obudowie, każdy z nich
odmierza czas indywidualnie dla
każdego z graczy. Przed rozpoczę-
ciem rozgrywki zostaje ustalony
limit czasu, jeżeli gracz nie zdąży
z wykonaniem ruchu w ustalonym
czasie - automatycznie przegrywa
grę. Zegar odlicza w dół od zada-
nej wartości i jednocześnie wyświe-
tla czas pozostały do końca tury.
Po wykonaniu ruchu gracz wciska
przycisk umieszczony nad „swo-
im zegarem”, który powoduje za-
trzymanie i wyzerowanie własnego
licznika oraz jednoczesny początek
odliczania czasu dla przeciwnika.
Prezentowany w artykule układ
zegara można podzielić na dwa za-
sadnicze bloki: sterownik, którego
schemat znajduje się na
rys. 2
oraz
moduł wyświetlaczy (schemat na
rys. 3
). Sterowanie wyświetlaczem
odbywa się z wykorzystaniem mul-
tipleksowania, co pozwoliło do mi-
nimum ograniczyć liczbę niezbęd-
nych połączeń między płytkami.
Jako dwukropki zostały wykorzysta-
ne cztery diody świecące o średnicy
soczewki 1,8 mm połączone parami
równolegle (D1+D2 oraz D3+D4),
które sterowane są za pomocą
3-stykowego złącza J3.
Moduł sterownika z pozoru może
wydawać się skomplikowany, jed-
nak rzeczywistość jest nieco prost-
sza. Przede wszystkim można go
podzielić na kilka mniejszych grup:
zasilacz (kondensatory C5...C8 oraz
stabilizator IC3), bufor segmentów
(oporniki R1...R7 oraz układ IC2),
bufor „wspólnych anod” (rezystory
R8...R15 wraz z tranzystorami T3...
T10), bufor dwukropków (elemen-
ty R17...R20 oraz T1 i T2) oraz na
mikrokontroler wraz z niezbędnymi
Fot. 1. Tradycyjny zegar szachowy
Elektronika Praktyczna 2/2005
39
P R O J E K T Y
Zegar szachowy
Rys. 2. Sterownik cyfrowego zegara szachowego
do jego pracy elementami (IC1, X1,
C1...C3). Postaram się teraz pokrót-
ce omówić każdy z wymienionych
bloków w kolejności, w jakiej były
wymieniane.
Zasilacz całego układu został
zbudowany w oparciu o bardzo
popularny układ 7805. Zastosowanie
scalonego stabilizatora pozwoliło
rozszerzyć granice, między którymi
powinna znajdować się wartość
napięcia zasilającego. Kondensa-
tory C4...C8 wygładzają to napięcie
zapewniając poprawną pracę mi-
krokontrolera. Kolejnym blokiem
jest bufor segmentów wyświetlaczy,
składający się z rezystorów ograni-
czających prąd pojedynczej diody
oraz układu ULN2003. Zastosowa-
nie oporników o wartości 180 V
sprawiło, że wyświetlane cyfry są
nieco ciemniejsze (efekt multiplek-
sowania), jednak ryzyko uszkodze-
nia wyświetlacza podczas testowa-
nia programu jest minimalne, gdyż
przez diody nie popłynie prąd
większy niż 28 mA.
Następnym opisywanym przeze
mnie elementem sterownika jest bu-
for wspólnych anod wyświetlaczy.
Część ta składa się z ośmiu tranzy-
storów PNP oraz rezystorów o war-
tości 3,3 kV, których zadaniem jest
ograniczenie prądu bazy tranzysto-
rów T3...T10. Podanie stanu ni-
skiego na bazę tranzystora za po-
średnictwem odpowiedniego oporni-
ka powoduje podłączenie wybranego
wyświetlacza do plusa zasilania.
Kolejny układ, będący ostatnią
już częścią składową sterownika, ma
za zadanie zasilić dwukropki. Został
on zrealizowany w typowy sposób na
dwóch tranzystorach: T1, T2 wraz
z rezystorami R17...R20. Dwa z tych
oporników (R19 i R20) ograniczają
prąd diod, natomiast pozostałe dwa
są niezbędne do wymuszenia stanu
wysokiego na bazach tranzystorów.
Za odświeżanie zawartości wy-
świetlacza odpowiedzialna jest funk-
cja
Multiplexing
(
list. 1
), która została
„podczepiona” pod przerwanie pocho-
dzące od licznika T1. Bezpośrednio
po przepełnieniu się licznika i wy-
generowaniu przerwania, do rejestru
TH1 zapisywana jest wartość B8h,
co powoduje ustawienie częstotliwości
odświeżania na około 50 Hz. W celu
jej zwiększenia należy zmienić tę war-
tość na odpowiednio większą. Każde
przepełnienie timera generuje przerwa-
nie, a procesor wykonuje funkcję
Mul-
tiplexing
za każdym razem wyświetla-
jąc kolejną cyfrę, od lewej do prawej
strony. Numer aktualnie wyświetlanej
cyfry przechowywany jest w zmiennej
active_display
. Przed wyświetleniem
nowego znaku, wszystkie wyświe-
tlacze są wygaszane, a następnie po
ustawieniu danej na „porcie segmen-
tów” zostaje podane zasilanie na ano-
dę odpowiedniej pozycji. Taki sposób
sterowania pozwala uniknąć sytuacji,
w której na jednej pozycji wyświetlane
są dwie cyfry, z czego jedna znacznie
słabiej od drugiej.
Kolejną ważną, z punktu widzenia
działania programu, funkcją jest
Clock
(kod na
list. 2
), której zadaniem jest
zliczanie sekund od chwili urucho-
mienia timera nr 0. Mikrokontroler
zaczyna wykonywać instrukcje za-
warte w ciele funkcji w momencie
otrzymania przerwania od licznika T0.
Timer ten został ustawiony w tryb 2,
co oznacza, że pracuje jako licznik
8-bitowy z automatycznym przeła-
Program sterujący
Program sterujący pracą zegara
został napisany w języku C i skom-
pilowany przy użyciu darmowego
kompilatora SDCC (
http://sdcc.sour-
ceforge.net
). Opisywanie szczegółowo
całego programu sterującego pracą
mikrokontrolera w tej części artyku-
łu byłoby dość kiepskim pomysłem,
dlatego też skupię się jedynie na
najważniejszych fragmentach kodu.
Na początek najlepiej zerknąć na
schemat blokowy algorytmu, który
został przedstawiony na
rys. 4
.
W pierwszym etapie ustawiane są
odpowiednie parametry układu
przerwań oraz timerów takie, jak:
włączenie obsługi przerwań, ustaw-
nie licznika 0 w tryb 2, a licznika 1
w tryb 0, itp. Przygotowanie portów
procesora sprowadza się głównie
do wygaszenia wyświetlaczy wraz
z dwukropkami oraz podania logicz-
nej jedynki na wyprowadzenia kla-
wiatury. Na tym etapie programu
bardzo pomocne okazały się dyrek-
tywy „define”, dzięki którym kod
stał się bardziej przejrzysty.
40
Elektronika Praktyczna 2/2005
Zegar szachowy
List. 1.
void Multiplexing () interrupt TF1_VECTOR
// multipleksowanie „podczepione” pod prze-
rwanie T0
{
TH1 = 0xE2;
// zaladuj nowa wartosc do
licznika
segment_port = 0;
// wylacz wyswietlana cyfre
if ((powered_display & 3) && (powered_di-
splay & 4)) // jezeli wyswietlacz ma
cokolwiek wyswietlic...
{
switch (powered_display & 3)
// dokonaj identyfikacji tylko
pierwszych 3 bitow
{
case 1:
if (active_display > 3) active_display
= 0; //tylko lewa czesc wyswietlacza
break;
case 2:
if (active_display > 7) active_display
= 4; //tylko prawa czesc wyswietlacza
break;
case 3:
if (active_display > 7) active_di-
splay = 0; //odswiezaj wszystkie osiem
pozycji
break;
}
display_port = display[active_display];
// ustaw zasilanie segmentow dla nowej cyfry
segment_port = buffer[active_display];
// wlacz zasilnie kolejnego wyswietlacza
++active_display;
// zwieksz numer wyswietlacza
}
}
Warto także poświęcić nieco
uwagi obsłudze klawiatury, podczas
ustawiania początkowych parame-
trów zegara, realizowanej przez
funkcję
Settings
, której fragmenty
zamieszczono na
list. 3
. Można
rzec, że całe jej wnętrze to jedna
wielka pętla, która wykonuje się
tak długo, aż nie zostanie naciśnie-
ty przycisk
mode_button
służący
do wejścia/wyjścia z trybu usta-
wień. Do tego czasu procesor cały
czas sprawdza stan pozostałych
klawiszy, czy przypadkiem któryś
nie został wciśnięty. Jeżeli np.: zo-
stał naciśnięty klawisz
mode_button
procesor zwiększy stan odpowied-
niej zmiennej, pilnując jednocze-
śnie by nie osiągnęła ona niedo-
zwolonej wartości. Jeżeli natomiast
wciśnięto przycisk
mode_button
program przejdzie w drugą pętlę,
tym razem jednak oczekując na
zwolnienie styków. Gdyby zrezy-
gnować z oczekiwania na zwolnie-
nie klawisza, procesor mógłby się
bardzo łatwo zapętlić, uznając wci-
śnięcie klawisza jednocześnie jako
znak do opuszczenia i ponownego
wejścia w tryb ustawień. Wywoła-
nia
WaitMs (250)
odpowiadają za
tzw. powtarzanie klawisza oraz za-
pobiegają zbyt szybkiemu zwiększa-
niu się stanów liczników w sytuacji
gdy dany klawisz został wciśnięty
i przytrzymany.
Funkcja
KeyScan
wywoływana
jest bezpośrednio z głównej pę-
tli programu, a jej zadaniem jest
między innymi obsługa klawiszy
końca tury podczas normalnej pra-
cy zegara. Dodatkowo wspomniana
przed chwilą główna pętla progra-
mu zawiera szereg instrukcji prze-
znaczonych do obliczania aktualnej
wartości czasu. Tak obliczony czas,
inaczej dla każdego trybu pracy,
jest następnie przekształcany z licz-
by sekund na postać
h:m:s
i um-
ieszczany w buforze wyświetlacza,
z którego już zostanie bezpośrednio
wyświetlony przy najbliższym prze-
rwaniu licznika T1.
który gracz rozpocznie partię; 1 jest
przypisana do lewej części wyświe-
tlacza, zaś 2 do prawej. Pozostałe
4 cyfry reprezentują wartość czasu
niezbędną podczas pracy w trybie
1 i 2. Zegar może odmierzać czas
gry pracując w jednym z 3 dostęp-
nych trybów. W pierwszym z nich
czas jest odliczany w dół od zadanej
wartości, drugi tryb to gra na tzw.
List. 2.
void Clock () interrupt TF0_VECTOR
// sekundnik „podczepiony” pod przerwanie T1
{
++clock_temp; //
zwieksz stan licznika przerwan timera
switch (clock_temp)
{
case 1:
if (powered_colon & 1) colon_left = 1;
// wlacz lewy dwukropek
if (powered_colon & 2) colon_right = 1;
// wlacz prawy dwukropek
if (powered_display & 8) powered_di-
splay |= 4; // wlacz wyswietlacze jezeli
wlaczono miganie
break;
case 1800:
if (powered_colon & 1) colon_left = 0;
if (powered_colon & 2) colon_right = 0;
if (powered_display & 8) powered_di-
splay &= 251; // wylacz wyswietlacze
jezeli wlaczono miganie
break;
case 3600:
// wyzeruj licznik przerwan gdy
osiagnie 3600
clock_temp = 0;
++seconds_counted;
// zwieksz o jeden licznik odliczonych sekund
break;
}
}
dowaniem. Przy częstotliwości rezo-
natora 11,0592 MHz timer generuje
przerwanie dokładnie 3600 razy na
sekundę, dlatego też niezbędne było
wprowadzenie pomocniczej zmiennej
clock_temp
, która pełni rolę licznika
przerwań modulo 3600, a w momen-
cie przepełnienia zwiększa o 1 licznik
sekund. W funkcji dodatkowo zaimple-
mentowano miganie dwukropków oraz
wyświetlacza. O ile dwukropek powi-
nien migać z częstotliwością 1 Hz, to
nic nie stoi na przeszkodzie by np.:
„koniec czasu” był sygnalizowany mi-
ganiem wyświetlaczy z większą czę-
stotliwością. W takim przypadku na-
leży jedynie dopisać potrzebne nam
warunki do instrukcji
switch
przy
odpowiednich wartościach zmien-
nej
clock_temp
(np.: 900 i 2700 dla
2 Hz).
Obsługa zegara
Bezpośrednio po podłączeniu na-
pięcia zasilającego zaszyty w pamięci
procesora program rozpocznie swo-
je działanie, czego dowodem po-
winno być 6 cyfr pokazanych na
wyświetlaczu. Pierwsza, patrząc od
lewej strony, cyfra informuje o spo-
sobie odmierzania czasu wskazując
jednocześnie na tryb pracy zegara.
Następna cyfra informuje nas o tym,
Rys. 3. Schemat elektryczny wyświe-
tlacza cyfrowego zegara szachowe-
go
Elektronika Praktyczna 2/2005
41
Zegar szachowy
wciśnięcie odpowiedniego dla danego
gracza przycisku końca tury. Następ-
nie za pomocą klawiszy
minutes_but-
ton
oraz
seconds_button
nastawiamy
odpowiednio dobrany czas (nie jest
to wymagane przy pracy w trybie 3).
Kiedy już wszystko zostało ustawio-
ne i gracze są gotowi do rozpoczęcia
partii, wystarczy nacisnąć przycisk
settings_button
, a zegar automatycznie
rozpocznie odmierzanie czasu.
List. 3.
void Settings ()
{
[...]
while (settings_button)
// wykonuj petle dopoki nie wcisnieto ponow-
nie guzika
{
if (!mode_button)
// obsluz przycisk zmiany trybu pracy zegara
{
if (++clock_mode == MODES_NUMBER)
clock_mode = 0; // zwieksz i jesli „prze-
pelniono”, to wyzeruj
buffer[0] = digits[clock_mode + 1];
// pokaz nowa wartosc na wyswietlaczu
WaitMs (250);
}
if (button_left)
// jezeli wcisnieto lewy przy-
cisk konca tury
{
player_turn = 0;
// zmien rozpoczynajacego gra-
cza na pierwszego
buffer[2] = 0x06;
// wyswietl odswiezona wartosc
numeru gracza
}
if (button_right)
// jezeli wcisnieto prawy przycisk konca tury
{
player_turn = 1;
// zmien rozpoczynajacego
gracza na drugiego
buffer[2] = 0x5B;
// wyswietl odswiezona wartosc
numeru gracza
}
if (!minutes_button)
{
if (++initial_time.m == 60) initial_
time.m = 0; // zwieksz licznik minut i
wyzeruj jezeli osignie 60
LoadBuffer (4, initial_time.m);
// pokaz nowa wartosc minut na wyswietlaczu
WaitMs (250);
// oporznienie powtarzania
klawisza
}
if (!seconds_button)
{
if (++initial_time.s == 60) initial_
time.s = 0; // zwieksz licnzik sekund i
wyzeruj jezeli osignie 60
LoadBuffer (6, initial_time.s);
WaitMs (250);
}
}
WaitMs (10);
// poczekaj z powodu stykow
wlacznika
while (!settings_button);
// czekaj az przycisk zostanie zwolniony
[...]
}
Rys. 4. Algorytm działania programu
zegara cyfrowego
Montaż i uruchomienie
Układ zegara zmontowano na
dwóch osobnych płytkach obwodu
drukowanego (sterownik -
rys. 5
oraz wyświetlacz -
rys. 6
). Montaż
elementów powinien rozpocząć się
od elementów najmniejszych, a za-
kończyć na zainstalowaniu proce-
sora w podstawce oraz połączeniu
płytek ze sobą. Połączenie takie naj-
wygodniej jest wykonać srebrzanką,
jednak nic nie stoi na przeszko-
dzie by wykorzystać inny materiał,
jak np. popularny miedziany drut
„telefoniczny”. Jeżeli wszystko zo-
stało poprawnie zmontowane, to
po podaniu napięcia zasilania moż-
na przystąpić do zaprogramowania
procesora o ile nie zostało to wy-
konane wcześniej. Tak zmontowany
w całość układ zegara jest gotowy
do pracy i powinien „startować”
zaraz po podaniu napięcia zasilania
na złącze J11.
Marcin Osiniak
przewagi czasowe, w której zegar pil-
nuje by różnica całkowitych czasów
gry każdego z graczy nie przekroczy-
ła nastawionej wartości. W trybie 3
zegar pełni rolę licznika czasu, od-
mierzając całkowity czas ruchów dla
każdego gracza. Przy takiej pracy
nastawiona wartość czasu nie jest
brana pod uwagę. Do wyboru sposo-
bu odmierzania czasu służy
przycisk
mode_button
, którego każdorazowe
naciśnięcie powoduje przejście na
następny w kolejności tryb pracy. Je-
żeli chcemy aby grę rozpoczynał za-
wodnik, którego wyświetlacz znajduje
się z prawej strony wystarczy, że bę-
dąc w ustawieniach, naciśniemy jego
przycisk końca tury. Jeżeli wszystko
się udało, na wyświetlaczu powinien
się zmienić numer gracza z 1 na 2.
Można wielokrotnie zmieniać numer
rozpoczynającego zawodnika przez
Rys. 5. Schemat montażowy płytki drukowanej sterownika zegara szachowego
WYKAZ ELEMENTÓW
Rezystory
R1...R7: 180
V
R8...R15, R17, R18: 3,3 k
V
R16: 10 k
V
R19, R20: 150
V
Kondensatory
C1, C2: 33 pF
C3: 1
m
F/16 V
C4, C6: 100
m
F
C5, C7, C8: 100 nF
Półprzewodniki
IC1: AT89C51
IC2: ULN2003
IC3: 7805
T1, T2: BC548
T3...T10: BC557
X1: 11,0592 MHz
D1...D8: SA56-11EWA
LD1...LD4: dioda LED 1,8 mm
Inne
J2...J7: goldpin 1x2
J10: goldpin 1x5
J11: gniazdo zasilania
Rys. 6. Schemat montażowy płytki drukowanej wyświetlacza cyfrowego zegara
szachowego
42
Elektronika Praktyczna 2/2005
Plik z chomika:
decha9191
Inne pliki z tego folderu:
02-2005_010-015.pdf
(880 KB)
02-2005_024-027.pdf
(3043 KB)
02-2005_017-023.pdf
(869 KB)
02-2005_035-038.pdf
(754 KB)
02-2005_028-032.pdf
(651 KB)
Inne foldery tego chomika:
01
03
04
05
06
Zgłoś jeśli
naruszono regulamin