22.09.2013 Views

EdW 2003/08 - Elportal

EdW 2003/08 - Elportal

EdW 2003/08 - Elportal

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

50<br />

2673<br />

Do czego to służy?<br />

Gdy budujemy system mikroprocesorowy,<br />

który w założeniach ma być obsługiwany<br />

przez człowieka, do przekazywania mu informacji<br />

zwykle używamy klawiatur. Są to klawiatury<br />

dołączone wprost do wyprowadzeń<br />

mikroprocesora i masy lub plusa zasilania lub<br />

też matrycowe. W obu przypadkach zajmują<br />

one niemało wyprowadzeń układu, co często<br />

jest poważnym problemem. Zwłaszcza<br />

w 89C2051, 90S2313 lub miniaturowych<br />

AVR-ach (np. 90S2343, 90S1200). Niekiedy<br />

brakuje nam wyprowadzeń. Prezentowany<br />

układ rozwiązuje powyższe problemy, gdy<br />

potrzebna jest klawiatura o ośmiu lub mniej<br />

przyciskach. Do jego połączenia z procesorem<br />

wystarczy jedno wyprowadzenie. Układ<br />

na swoim wyjściu wytwarza przebieg prostokątny<br />

niosący informację o numerze wciśniętego<br />

przycisku. Jest on łatwy do zdekodowania<br />

za pomocą dowolnego procesora. Ogromną<br />

zaletą układu jest jego bardzo niska cena<br />

oraz to, że w spoczynku w ogóle nie pobiera<br />

prądu, z wyjątkiem liczonych w nanoamperach<br />

prądów polaryzacji wejść CMOS i różnych<br />

prądów upływu. Pomiar tego prądu za<br />

pomocą mikroamperomierza cyfrowego<br />

o rozdzielczości 1µA nie spowodował jakiejkolwiek<br />

reakcji miernika, nawet na tej najmniej<br />

znaczącej pozycji – a więc prąd pobierany<br />

w spoczynku jest dużo mniejszy od<br />

1µA! Pobór w trakcie pracy wynosi ok.<br />

650µA i może być zmniejszony, jeśli zajdzie<br />

taka potrzeba poprzez zwiększenie wartości<br />

rezystorów R2,R3 i R6, które są w modelu<br />

stosunkowo małe. Cechy te pozwalają na zasilanie<br />

bateryjne. I tu ujawnia się kolejne zastosowanie<br />

opisywanego modułu – dodając<br />

jakikolwiek generator częstotliwości nośnej<br />

(choćby na 4047 lub 555 CMOS), możemy<br />

zbudować taniutki i prosty pilot zdalnego<br />

<br />

Klawiatura do mikrokontrolera,<br />

czyli osiem przycisków w jednym<br />

sterowania, przeznaczony do współpracy<br />

z mikrokontrolerem. Kolejną zaletą jest wyjście<br />

typu otwarty kolektor.<br />

Jak to działa?<br />

Schemat ideowy przedstawiony jest na rysunku<br />

1. Jak widać, całość zrealizowałem<br />

zużyciem dwóch prostych układów CMOS<br />

i garstki elementów. W stanie spoczynku<br />

wszystkie przyciski są rozwarte, U1 jest wyzerowany<br />

i na jego wyjściu Q0 występuje<br />

stan wysoki. Tranzystor T2 jest zatkany a generator<br />

z bramką U2A nie pracuje. Na nóżce<br />

11 U2 jest stan niski i T1 jest zatkany. Wciśnięcie<br />

któregokolwiek z przycisków spowoduje<br />

podanie stanu niskiego na wejście RST<br />

układu U1 oraz otwarcie T2. Drgania występujące<br />

na początku nie będą przeszkadzać,<br />

gdyż obwód opóźniający R4C2 nie pozwoli<br />

na uruchomienie generatora z bramką<br />

U2A, zanim drgania te nie ustąpią. Gdy już<br />

tak się stanie, generator ten zaczyna pracować,<br />

wytwarzając przebieg prostokątny o częstotliwości<br />

ok. 1kHz. Wraz z wystąpieniem<br />

pierwszego zbocza narastającego stan wysoki<br />

zniknie z wyjścia Q0 U1, bramka U2B otworzy<br />

bramkę U2C i na wyjściu układu (kolektor<br />

T1) pojawi się zanegowany przebieg<br />

znóżki 3 U2 – za stan wysoki uznaję tu stan<br />

zatkania T1, wszak jego kolektor będzie zawsze<br />

podciągnięty do plusa zasilania sterowanego<br />

układu mikroprocesorowego.<br />

Przyjmijmy na początek następującą umowę:<br />

słowem impuls będę określał połowę<br />

okresu generatora, czyli występowanie tam<br />

Rys. 1 Schemat ideowy<br />

Elektronika dla Wszystkich


stanu wysokiego lub niskiego. Nie chodzi<br />

jednak o połowę czasu, gdyż przebieg wytwarzany<br />

przez prościutki generator na U2A wcale<br />

nie ma wypełnienia 50%, ale to nic nie<br />

przeszkadza. Tak więc 1 okres ma 2 impulsy,<br />

1,5 okresu to 3 impulsy itd.. Załóżmy przykładowo,<br />

że wciśnięto przycisk S3 oznaczony<br />

numerem 2. Pierwsze narastające zbocze<br />

przebiegu generatora U2A spowoduje pojawienie<br />

się stanu wysokiego na Q1 U2 oraz<br />

natychmiastowe wystąpienie na wyjściu stanu<br />

niskiego. Po wygenerowaniu 2 impulsów<br />

stan wysoki przejdzie na wyjście Q2, po 4 impulsach<br />

pojawi się na Q3. Po wytworzeniu<br />

piątego impulsu układ zacznie generować<br />

szósty, ale po jego zakończeniu stan wysoki<br />

pojawi się na wyjściu Q4, do którego dołączony<br />

jest zwarty przycisk S3. Spowoduje to<br />

natychmiastowe wyzerowanie U1 i zamknięcie<br />

bramki U2C. Na wyjściu układu pojawi<br />

się stan wysoki (zatkany T1) na czas trwania<br />

1 okresu, czyli kolejnych 2 impulsów. Ponieważ<br />

podczas generowania impulsu numer 6<br />

(jak i każdego parzystego) na wyjściu również<br />

był stan wysoki, to w rezultacie po wystąpieniu<br />

5 impulsów pojawi się tam długi<br />

stan wysoki o czasie trwania 3 kolejnych impulsów<br />

(szósty impuls zleje się z dwoma następnymi).<br />

Dalsze trzymanie S3 znów spowoduje<br />

wystąpienie 5 krótkich impulsów i jednego<br />

długiego itd. Puszczenie przycisku natychmiast<br />

resetuje U1 i po chwili wyłącza generator.<br />

Jeśli ktoś, zamiast S3, wciśnie np. S4<br />

(numer 3), to układ wytworzy przebieg,<br />

w którym pomiędzy dwoma impulsami długimi<br />

będzie 7 krótkich (o 1 okres więcej – to<br />

oczywiste), z których każdy trwa ok. 3 razy<br />

krócej niż długi. Dla przycisku numer 1 będą<br />

to 3 krótkie impulsy, a dla numer 0 – tylko 1.<br />

Mam nadzieję, że dostrzegacie już ogólną zależność:<br />

po wciśnięciu przycisku numer<br />

N (0...7) układ generuje przebieg,<br />

w którym pomiędzy dwoma długimi impulsami<br />

jest 2N+1 krótkich. Pomocą będzie<br />

rysunek 2, na którym przedstawiłem przebiegi<br />

na wyjściu układu po wciśnięciu kilku wybranych<br />

przycisków na tle przebiegu z nóżki<br />

3 U2. Strzałki pokazują momenty, w których<br />

resetowany jest U1. Przebiegi takie są łatwe<br />

do zdekodowania przez mikroprocesor – aby<br />

otrzymać numer przycisku, wystarczy policzyć,<br />

ile krótkich impulsów występuje pomiędzy<br />

dwoma długimi, odjąć 1 i podzielić<br />

przez 2. Ze względu na to, że w układzie występuje<br />

prościutki generator z jedną bramką,<br />

dobrze jest do dekodowania brać nie pierwszą,<br />

ale drugą lub trzecią serię impulsów –<br />

w pierwszej mogą występować impulsy<br />

o mniej jednolitych czasach niż w kolejnych<br />

seriach. Warto też sprawdzić, czy po długim<br />

impulsie kończącym analizowaną serię występuje<br />

kolejny krótki impuls, rozpoczynający<br />

serię następną. Zapobiegnie to błędom występującym<br />

podczas ekstremalnie krótkich<br />

naciśnięć przycisków, kiedy to mogłoby dojść<br />

Elektronika dla Wszystkich<br />

do sytuacji, w której analizowana seria przerwana<br />

byłabywpołowie przez puszczenie<br />

przycisku – dotyczy to zwłaszcza szybkich<br />

styków popularnych microswitchów.<br />

Przykładową, wypróbowaną w praktyce na<br />

2051, procedurę realizującą powyższe założenia<br />

w języku C przedstawia Listing 1. Funkcja<br />

Wait_for_long, jak sama nazwa wskazuje,<br />

czeka na długi impuls. Zwraca 0, gdy był to<br />

„dobry” impuls, czyli taki, po którym wciąż<br />

nadchodzą krótkie impulsy; zwraca 1, jeśli impuls<br />

ten trwa zbyt długo – jest wynikiem puszczenia<br />

przycisku. Za argument przyjmuje<br />

wskaźnik do zmiennej w której umieszcza<br />

wynik, czyli liczbę krótkich impulsów jakie<br />

wystąpiły od momentu wywołania tej funkcji<br />

do najbliższego długiego impulsu. W funkcji<br />

main jest przykład wykorzystania: pierwsze<br />

wywołanie Wait_for_long służy zignorowaniu<br />

pierwszej serii, po drugiej w zmiennej numer<br />

jest numer wciśniętego przycisku (0...7). Po<br />

wykorzystaniu tej wartości do określonego celu<br />

program czeka aż zwróci ona 1 – tym samym<br />

czeka na puszczenie przycisku. Zauważcie,<br />

jak uniwersalna jest ta funkcja i ile informacji<br />

można z niej uzyskać. Oczywiście to<br />

tylko przykład i kto chce może napisać swoją<br />

własną na dowolny procesor. Moja napisana<br />

jest dla procesora ’51 z kwarcem 11,059MHz.<br />

Przerobienie jej na inny typ (np. AVR) sprowadza<br />

się do zmiany realizacji opóźnienia<br />

(Delay) zależnie od konkretnego typu i zegara.<br />

Opóźnienie to powinno być kilkanaście...kilkadziesiąt<br />

razy krótsze od czasu trwania<br />

krótkiego impulsu, który dla wartości elementów<br />

jak na schemacie jest rzędu<br />

500µs (podkreślam – rzędu). Oprócz tego należy<br />

wtedy dobrać liczby określające długość<br />

określające minimalną długość impulsu długiego<br />

i za długiego (u mnie są to 40 i 80).<br />

Rys. 2 Przebiegi wyjściowe<br />

Montaż i uruchomienie<br />

Schemat montażowy przedstawiony został<br />

na rysunku 3. Montaż jest typowy i nie wymaga<br />

komentarza. Zaczynamy od zworek<br />

a kończymy na tranzystorach i układach<br />

scalonych (warto zastosować podstawki).<br />

Miejsca do podłączenia przycisków oznaczono<br />

ich numerami, pod jakimi będą dekodowane<br />

w programie. Po zmontowaniu ze sprawnych<br />

elementów układ od razu działa poprawnie.<br />

Do jego sprawdzenia przyda się jakikolwiek<br />

analizator stanów logicznych. W moim<br />

przypadku był to najzwyklejszy tranzystor<br />

NPN podłączony do portu drukarkowego<br />

R E K L A M A · R E K L A M A · R E K L A M A · R E K L A M A<br />

51


i darmowy programik ściągnięty z sieci.<br />

Przebiegi na wyjściu powinny być takie jak<br />

na rysunku 2. Oprócz programu z listingu 1<br />

na stronie <strong>EdW</strong> (w dziale FTP) znajdziecie<br />

prosty program (źródło i *.bin), który wyświetla<br />

numer wciśniętego przycisku na wyświetlaczu<br />

LCD (interfejs HD44780). Może<br />

on służyć do przetestowania układu. Jednak ze<br />

względu na duży rozrzut progów przełączania<br />

bramek w różnych egzemplarzach kostek 4093<br />

może się zdarzyć, że choć układ będzie wytwarzał<br />

przebiegi o prawidłowym kształcie oraz<br />

wartości elementów będą takie jak na rysunku<br />

1, to czasy impulsów będą się bardzo różniły od<br />

tych w modelu. Na wyświetlaczu będzie się<br />

wtedy notorycznie pojawiał napis Error!!!! lub<br />

jakieś „głupoty”. Sporadyczne pojawianie się<br />

tego napisu nie świadczy o błędzie w układzie,<br />

lecz o wystąpieniu przekłamań, które w rzeczywistym<br />

świecie się zdarzają. Chodzi o to, aby<br />

właściwie na nie zareagować i nie uznać błędnej<br />

transmisji za właściwą. Najprościej jest ją<br />

po prostu zignorować. Jeżeli jednak napis ten<br />

pojawia się często, to należy zmierzyć czasy<br />

analizatorem i zmienić liczby 40 i 80 w funkcji<br />

Wait_for_long na odpowiednie. Jeśli zaś chodzi<br />

o samą stabilność tego generatora, to choć<br />

jest ona słaba, tutaj w zupełności wystarczy.<br />

Rys. 3 Schemat montażowy<br />

Wykaz elementów<br />

Rezystory<br />

R1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .100kΩ<br />

R2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .220kΩ<br />

R3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .22kΩ<br />

R4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .470kΩ<br />

R5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1MΩ<br />

R6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10kΩ<br />

Kondensatory:<br />

C1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .10nF MKT<br />

C2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .220nF MKT<br />

C3 . . . . . . . . . . . . . . . . . . . . . . . . . . . .100nF ceramiczny<br />

Półprzewodniki:<br />

U1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4017<br />

U2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4093<br />

T1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .BC548B<br />

T2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .BC558B<br />

Inne:<br />

S1-S8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

Przyciski zwierne, typ zależny od konkretnego zastosowania<br />

(nie wchodzą w skład kitu AVT).<br />

52<br />

Komplet podzespołów z płytką<br />

jest dostępny w sieci handlowej AVT<br />

jako kit szkolny AVT-2673<br />

Listing 1. Funkcja dekodująca<br />

#include <br />

#define in P3_2<br />

unsigned char Wait_for_long(unsigned char* num)<br />

{<br />

_bit last;<br />

_data unsigned char licznik,stan,i;<br />

}<br />

*num=0;<br />

stan=0;<br />

licznik=0;<br />

in=1;<br />

last=in;<br />

while(1)<br />

{<br />

i=1;<br />

while(i--); // DELAY<br />

licznik++;<br />

if(licznik>40)<br />

stan=1;<br />

if(licznik>80)<br />

return 1; // zły długi<br />

}<br />

in=1;<br />

if(in!=last)<br />

{<br />

if(stan)<br />

return 0; // dobry długi<br />

else<br />

{<br />

last=in;<br />

licznik=0;<br />

(*num)++;<br />

}<br />

}<br />

// Przykład wykorzystania tej funkcji<br />

main()<br />

{<br />

_data unsigned char numer,err;<br />

}<br />

}<br />

while(1)<br />

{<br />

in=1;<br />

while(in); // czeka na poczatek<br />

while(!in); // ignorujemy pierwszy impuls<br />

err=Wait_for_long(&numer); // ignorujemy ten numer<br />

err=Wait_for_long(&numer); // ważny numer<br />

// wykorzystanie zmiennej numer<br />

// + prosta ochrona przed błędami<br />

if(!err && numer>=1; // numer=numer/2<br />

// .... tu wykorzystujemy zmienną numer<br />

}<br />

else<br />

{<br />

// reakcja na błąd<br />

}<br />

// czeka na puszczenie przycisku<br />

while(!Wait_for_long(&numer));<br />

Częstotliwość musiałaby się rozjechać dwukrotnie,<br />

żeby wystąpiły błędy, a do tego w typowych<br />

warunkach pracy nie dojdzie. Jest ona<br />

natomiast mocno zależna od napięcia zasilania<br />

– wspomniane liczby trzeba dobrać przy<br />

takim napięciu, przy jakim układ ma pracować<br />

docelowo. Ostatecznie można napisać<br />

ulepszoną, bardziej uniwersalną funkcję, która<br />

nie będzie miała tych liczb wpisanych „na<br />

sztywno”. Będzie mierzyć krótkie impulsy<br />

i czekać na wystąpienie długiego impulsu<br />

o nie ściśle określonym czasie, ale rzeczywi-<br />

ście ponad 2-krotnie dłuższego od krótkich.<br />

Uniezależni to nas od rozrzutów i innych niestabilności<br />

– wszystko w rękach programistów.<br />

Wszystkie stałe czasowe można dobrać<br />

wedle uznania. Gotowy moduł wstawiamy do<br />

urządzenia z mikrokontrolerem, gdzie brakuje<br />

nam wyprowadzeń i problem mamy z głowy.<br />

Interesująco wygląda możliwość dołączenia<br />

do naszej klawiaturki generatora (np. 36kHz)<br />

i budowa prostego pilota IRED.<br />

Arkadiusz Antoniak<br />

hal9900@poczta.onet.pl<br />

Elektronika dla Wszystkich

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!