50
Elektronika dla Wszystkich
Do czego to służy?
Gdy budujemy system mikroprocesorowy,
który w założeniach ma być obsługiwany
przez człowieka, do przekazywania mu infor-
macji zwykle używamy klawiatur. Są to kla-
wiatury dołączone wprost do wyprowadzeń
mikroprocesora i masy lub plusa zasilania lub
też matrycowe. W obu przypadkach zajmują
one niemało wyprowadzeń układu, co często
jest poważnym problemem. Zwłaszcza
w 89C2051, 90S2313 lub miniaturowych
AVR-ach (np. 90S2343, 90S1200). Niekiedy
brakuje nam wyprowadzeń. Prezentowany
układ rozwiązuje powyższe problemy, gdy
potrzebna jest klawiatura o ośmiu lub mniej
przyciskach. Do jego połączenia z proceso-
rem wystarczy jedno wyprowadzenie. Układ
na swoim wyjściu wytwarza przebieg prosto-
kątny niosący informację o numerze wciśnię-
tego przycisku. Jest on łatwy do zdekodowa-
nia za pomocą dowolnego procesora. Ogrom-
ną zaletą układu jest jego bardzo niska cena
oraz to, że w spoczynku w ogóle nie pobiera
prądu, z wyjątkiem liczonych w nanoampe-
rach prądów polaryzacji wejść CMOS i róż-
nych prądów upływu. Pomiar tego prądu za
pomocą mikroamperomierza cyfrowego
o rozdzielczości 1
µA nie spowodował jakiej-
kolwiek reakcji miernika, nawet na tej naj-
mniej znaczącej pozycji – a więc prąd pobie-
rany w spoczynku jest dużo mniejszy od
1µA! Pobór w trakcie pracy wynosi ok.
650µA i może być zmniejszony, jeśli zajdzie
taka potrzeba poprzez zwiększenie wartości
rezystorów R2,R3 i R6, które są w modelu
stosunkowo małe. Cechy te pozwalają na za-
silanie bateryjne. I tu ujawnia się kolejne za-
stosowanie opisywanego modułu – dodając
jakikolwiek generator częstotliwości nośnej
(choćby na 4047 lub 555 CMOS), możemy
zbudować taniutki i prosty pilot zdalnego
sterowania, przeznaczony do współpracy
z mikrokontrolerem. Kolejną zaletą jest wyj-
ście typu otwarty kolektor.
Jak to działa?
Schemat ideowy przedstawiony jest na ry-
sunku 1. Jak widać, całość zrealizowałem
z użyciem dwóch prostych układów CMOS
i garstki elementów. W stanie spoczynku
wszystkie przyciski są rozwarte, U1 jest wy-
zerowany i na jego wyjściu Q0 występuje
stan wysoki. Tranzystor T2 jest zatkany a ge-
nerator z bramką U2A nie pracuje. Na nóżce
11 U2 jest stan niski i T1 jest zatkany. Wci-
śnięcie któregokolwiek z przycisków spowo-
duje podanie stanu niskiego na wejście RST
układu U1 oraz otwarcie T2. Drgania wystę-
pujące na początku nie będą przeszkadzać,
gdyż obwód opóźniający R4C2 nie pozwoli
na uruchomienie generatora z bramką
U2A, zanim drgania te nie ustąpią. Gdy już
tak się stanie, generator ten zaczyna praco-
wać, wytwarzając przebieg prostokątny o czę-
stotliwości ok. 1kHz. Wraz z wystąpieniem
pierwszego zbocza narastającego stan wysoki
zniknie z wyjścia Q0 U1, bramka U2B otwo-
rzy bramkę U2C i na wyjściu układu (kolek-
tor T1) pojawi się zanegowany przebieg
z nóżki 3 U2 – za stan wysoki uznaję tu stan
zatkania T1, wszak jego kolektor będzie za-
wsze podciągnięty do plusa zasilania stero-
wanego układu mikroprocesorowego.
Przyjmijmy na początek następującą umo-
wę: słowem impuls będę określał połowę
okresu generatora, czyli występowanie tam
2
2
6
6
7
7
3
3
+
+
+
K
K
l
l
a
a
w
w
i
i
a
a
t
t
u
u
r
r
a
a
d
d
o
o
m
m
i
i
k
k
r
r
o
o
k
k
o
o
n
n
t
t
r
r
o
o
l
l
e
e
r
r
a
a
,
,
c
c
z
z
y
y
l
l
i
i
o
o
s
s
i
i
e
e
m
m
p
p
r
r
z
z
y
y
c
c
i
i
s
s
k
k
ó
ó
w
w
w
w
j
j
e
e
d
d
n
n
y
y
m
m
Rys. 1 Schemat ideowy
stanu wysokiego lub niskiego. Nie chodzi
jednak o połowę czasu, gdyż przebieg wytwa-
rzany przez prościutki generator na U2A wca-
le nie ma wypełnienia 50%, ale to nic nie
przeszkadza. Tak więc 1 okres ma 2 impulsy,
1,5 okresu to 3 impulsy itd.. Załóżmy przy-
kładowo, że wciśnięto przycisk S3 oznaczony
numerem 2. Pierwsze narastające zbocze
przebiegu generatora U2A spowoduje poja-
wienie się stanu wysokiego na Q1 U2 oraz
natychmiastowe wystąpienie na wyjściu sta-
nu niskiego. Po wygenerowaniu 2 impulsów
stan wysoki przejdzie na wyjście Q2, po 4 im-
pulsach pojawi się na Q3. Po wytworzeniu
piątego impulsu układ zacznie generować
szósty, ale po jego zakończeniu stan wysoki
pojawi się na wyjściu Q4, do którego dołą-
czony jest zwarty przycisk S3. Spowoduje to
natychmiastowe wyzerowanie U1 i zamknię-
cie bramki U2C. Na wyjściu układu pojawi
się stan wysoki (zatkany T1) na czas trwania
1 okresu, czyli kolejnych 2 impulsów. Ponie-
waż podczas generowania impulsu numer 6
(jak i każdego parzystego) na wyjściu rów-
nież był stan wysoki, to w rezultacie po wy-
stąpieniu 5 impulsów pojawi się tam długi
stan wysoki o czasie trwania 3 kolejnych im-
pulsów (szósty impuls zleje się z dwoma na-
stępnymi). Dalsze trzymanie S3 znów spowo-
duje wystąpienie 5 krótkich impulsów i jed-
nego długiego itd. Puszczenie przycisku na-
tychmiast resetuje U1 i po chwili wyłącza ge-
nerator. Jeśli ktoś, zamiast S3, wciśnie np. S4
(numer 3), to układ wytworzy przebieg,
w którym pomiędzy dwoma impulsami długi-
mi będzie 7 krótkich (o 1 okres więcej – to
oczywiste), z których każdy trwa ok. 3 razy
krócej niż długi. Dla przycisku numer 1 będą
to 3 krótkie impulsy, a dla numer 0 – tylko 1.
Mam nadzieję, że dostrzegacie już ogólną za-
leżność: po wciśnięciu przycisku numer
N (0...7) układ generuje przebieg,
w którym pomiędzy dwoma długimi im-
pulsami jest 2N+1 krótkich. Pomocą będzie
rysunek 2, na którym przedstawiłem przebie-
gi na wyjściu układu po wciśnięciu kilku wy-
branych przycisków na tle przebiegu z nóżki
3 U2. Strzałki pokazują momenty, w których
resetowany jest U1. Przebiegi takie są łatwe
do zdekodowania przez mikroprocesor – aby
otrzymać numer przycisku, wystarczy poli-
czyć, ile krótkich impulsów występuje po-
między dwoma długimi, odjąć 1 i podzielić
przez 2. Ze względu na to, że w układzie wy-
stępuje prościutki generator z jedną bramką,
dobrze jest do dekodowania brać nie pierw-
szą, ale drugą lub trzecią serię impulsów –
w pierwszej mogą występować impulsy
o mniej jednolitych czasach niż w kolejnych
seriach. Warto też sprawdzić, czy po długim
impulsie kończącym analizowaną serię wy-
stępuje kolejny krótki impuls, rozpoczynają-
cy serię następną. Zapobiegnie to błędom wy-
stępującym podczas ekstremalnie krótkich
naciśnięć przycisków, kiedy to mogłoby dojść
do sytuacji, w której analizowana seria prze-
rwana byłaby w połowie przez puszczenie
przycisku – dotyczy to zwłaszcza szybkich
styków popularnych microswitchów.
Przykładową, wypróbowaną w praktyce na
2051, procedurę realizującą powyższe założe-
nia w języku C przedstawia Listing 1. Funk-
cja Wait_for_long, jak sama nazwa wskazuje,
czeka na długi impuls. Zwraca 0, gdy był to
„dobry” impuls, czyli taki, po którym wciąż
nadchodzą krótkie impulsy; zwraca 1, jeśli im-
puls ten trwa zbyt długo – jest wynikiem pu-
szczenia przycisku. Za argument przyjmuje
wskaźnik do zmiennej w której umieszcza
wynik, czyli liczbę krótkich impulsów jakie
wystąpiły od momentu wywołania tej funkcji
do najbliższego długiego impulsu. W funkcji
main jest przykład wykorzystania: pierwsze
wywołanie Wait_for_long służy zignorowaniu
pierwszej serii, po drugiej w zmiennej numer
jest numer wciśniętego przycisku (0...7). Po
wykorzystaniu tej wartości do określonego ce-
lu program czeka aż zwróci ona 1 – tym sa-
mym czeka na puszczenie przycisku. Zauważ-
cie, jak uniwersalna jest ta funkcja i ile infor-
macji można z niej uzyskać. Oczywiście to
tylko przykład i kto chce może napisać swoją
własną na dowolny procesor. Moja napisana
jest dla procesora ’51 z kwarcem 11,059MHz.
Przerobienie jej na inny typ (np. AVR) spro-
wadza się do zmiany realizacji opóźnienia
(Delay) zależnie od konkretnego typu i zega-
ra. Opóźnienie to powinno być kilkana-
ście...kilkadziesiąt razy krótsze od czasu trwa-
nia krótkiego impulsu, który dla wartości ele-
mentów jak na schemacie jest rzędu
500µs (podkreślam – rzędu). Oprócz tego na-
leży wtedy dobrać liczby określające długość
określające minimalną długość impulsu dłu-
giego i za długiego (u mnie są to 40 i 80).
Montaż i uruchomienie
Schemat montażowy przedstawiony został
na rysunku 3. Montaż jest typowy i nie wy-
maga komentarza. Zaczynamy od zworek
a kończymy na tranzystorach i układach
scalonych (warto zastosować podstawki).
Miejsca do podłączenia przycisków oznaczo-
no ich numerami, pod jakimi będą dekodowa-
ne w programie. Po zmontowaniu ze spraw-
nych elementów układ od razu działa popraw-
nie. Do jego sprawdzenia przyda się jakikol-
wiek analizator stanów logicznych. W moim
przypadku był to najzwyklejszy tranzystor
NPN podłączony do portu drukarkowego
51
Elektronika dla Wszystkich
Rys. 2 Przebiegi wyjściowe
REKLAMA · REKLAMA · REKLAMA · REKLAMA
i darmowy programik ściągnięty z sieci.
Przebiegi na wyjściu powinny być takie jak
na rysunku 2. Oprócz programu z listingu 1
na stronie EdW (w dziale FTP) znajdziecie
prosty program (źródło i *.bin), który wy-
świetla numer wciśniętego przycisku na wy-
świetlaczu LCD (interfejs HD44780). Może
on służyć do przetestowania układu. Jednak ze
względu na duży rozrzut progów przełączania
bramek w różnych egzemplarzach kostek 4093
może się zdarzyć, że choć układ będzie wytwa-
rzał przebiegi o prawidłowym kształcie oraz
wartości elementów będą takie jak na rysunku
1, to czasy impulsów będą się bardzo różniły od
tych w modelu. Na wyświetlaczu będzie się
wtedy notorycznie pojawiał napis Error!!!! lub
jakieś „głupoty”. Sporadyczne pojawianie się
tego napisu nie świadczy o błędzie w układzie,
lecz o wystąpieniu przekłamań, które w rzeczy-
wistym świecie się zdarzają. Chodzi o to, aby
właściwie na nie zareagować i nie uznać błęd-
nej transmisji za właściwą. Najprościej jest ją
po prostu zignorować. Jeżeli jednak napis ten
pojawia się często, to należy zmierzyć czasy
analizatorem i zmienić liczby 40 i 80 w funkcji
Wait_for_long na odpowiednie. Jeśli zaś chodzi
o samą stabilność tego generatora, to choć
jest ona słaba, tutaj w zupełności wystarczy.
Częstotliwość musiałaby się rozjechać dwu-
krotnie, żeby wystąpiły błędy, a do tego w ty-
powych warunkach pracy nie dojdzie. Jest ona
natomiast mocno zależna od napięcia zasila-
nia – wspomniane liczby trzeba dobrać przy
takim napięciu, przy jakim układ ma praco-
wać docelowo. Ostatecznie można napisać
ulepszoną, bardziej uniwersalną funkcję, która
nie będzie miała tych liczb wpisanych „na
sztywno”. Będzie mierzyć krótkie impulsy
i czekać na wystąpienie długiego impulsu
o nie ściśle określonym czasie, ale rzeczywi-
ście ponad 2-krotnie dłuższego od krótkich.
Uniezależni to nas od rozrzutów i innych nie-
stabilności – wszystko w rękach programi-
stów. Wszystkie stałe czasowe można dobrać
wedle uznania. Gotowy moduł wstawiamy do
urządzenia z mikrokontrolerem, gdzie brakuje
nam wyprowadzeń i problem mamy z głowy.
Interesująco wygląda możliwość dołączenia
do naszej klawiaturki generatora (np. 36kHz)
i budowa prostego pilota IRED.
Arkadiusz Antoniak
hal9900@poczta.onet.pl
52
Elektronika dla Wszystkich
Wykaz elementów
RReezzyyssttoorryy
R1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100kΩ
R2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .220kΩ
R3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22kΩ
R4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .470kΩ
R5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1MΩ
R6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10kΩ
KKoonnddeennssaattoorryy::
C1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10nF MKT
C2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .220nF MKT
C3 . . . . . . . . . . . . . . . . . . . . . . . . . . . .100nF ceramiczny
PPóółłpprrzzeewwooddnniikkii::
U1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4017
U2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4093
T1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .BC548B
T2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .BC558B
Inne:
S1-S8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Przyciski zwierne, typ zależny od konkretnego zastosowania
(nie wchodzą w skład kitu AVT).
KKoom
mpplleett ppooddzzeessppoołłóóww zz ppłłyyttkkąą
jjeesstt ddoossttęęppnnyy ww ssiieeccii hhaannddlloowweejj AAVVTT
jjaakkoo kkiitt sszzkkoollnnyy AAVVTT-22667733
Rys. 3 Schemat montażowy
Listing 1. Funkcja dekodująca
#include <regat8x2051.sfr>
#define in
P3_2
unsigned char Wait_for_long(unsigned char* num)
{
_bit last;
_data unsigned char licznik,stan,i;
*num=0;
stan=0;
licznik=0;
in=1;
last=in;
while(1)
{
i=1;
while(i--);
// DELAY
licznik++;
if(licznik>40)
stan=1;
if(licznik>80)
return 1;
// zły długi
in=1;
if(in!=last)
{
if(stan)
return 0;
// dobry długi
else
{
last=in;
licznik=0;
(*num)++;
}
}
}
}
// Przykład wykorzystania tej funkcji
main()
{
_data unsigned char numer,err;
while(1)
{
in=1;
while(in);
// czeka na poczatek
while(!in);
// ignorujemy pierwszy impuls
err=Wait_for_long(&numer);
// ignorujemy ten numer
err=Wait_for_long(&numer);
// ważny numer
// wykorzystanie zmiennej numer
// + prosta ochrona przed błędami
if(!err && numer<16)
{
numer--;
// -1
numer>>=1;
// numer=numer/2
// .... tu wykorzystujemy zmienną numer
}
else
{
// reakcja na błąd
}
// czeka na puszczenie przycisku
while(!Wait_for_long(&numer));
}
}