|
|
mikrokontrolery.net |
|||||||||||||||||||||||||||||
|
Programowanie mikrokontrolerów 8051 w języku C - część 2 W drugiej części kursu programowania zapoznamy się z obsługą klawiatury.W tym celu musimy podłączyć do układu z poprzedniej części kursu, do portu P3, 8 przycisków w sposób pokazany na ponizszym rysunku :
Klawiatura ta działa w następujący sposób : po naciśnięciu przycisku wyprowadzenie portu, do którego jest podłączony przycisk, jest zwierane do masy, co wymysza na wyprowadzeniu portu stan niski. Port musi zawierać wewnętrzne rezystory podciągajęce linie portu do szyny zasilającej. W przeciwnym razie będziumy musieli dołączyć zewnętrzne rezystory podciągające. W typowych mikrokontrolerach rodziny 8051 rezystory te są wbudowane w każdy port, za wyjątkiem portu P0 a także w bardzo popularnym AT89C2051 za wyjątkiem linii P1.0 i P1.1. Tak wiec przed podłączeniem klawiatury nalezy się upewnić, że port do którego chcemy podłaczyc klawiaturę posada rezystory podciągające. Pierwszy program wykorzystujący klawiaturę jest bardzo prosty i zamieszczony poniżej :
Cały program opiera się w zasadzie na nieustannym przepisywaniu stanu linii portu P3 do portu P0. Efektem tego jest zapalanie odpowiedniej diody LED po naciśnięciu dowolnego przycisku. Zauważmy, że naciśniecie przycisku wywołuje wymuszenie na odpowiednim wyprowadzeniu portu P3 stanu niskiego, a zapalenie diody LED jest spowodowane ustawieniem na odpowiednim wyprowadzeniu portu P0 również stanu niskiego. Dzięki temu możemy po prostu przepisać stan linii portu P3 do portu P0, bez zadnych dodatkowych zabiegów. Jest to zrealizowane przez instrukcję :
Nie są wymagane żadne dodatkowe zmienne pośredniczące w przesyłaniu danych z portu P3 do portu P0. Instrukcja warunkowa if
Jesli warunek ma wartość true (prawda) to wykonywana jest instrukcja, w przeciwnym razie instrukcja nie będzie wykonana. Przykład zastosowania instrukcji warunkowe if jest pokazany poniżej :
Zapis P3_0 odpowiada zapisowi P3.0, czyli określa pin 0 portu P3. Przyjrzyjmy sie teraz dokładniej instrukcji if :
W nawiasach okrągłych po słowie if umieszczono warunek. Warunkiem musi być wyrażenie zwracające wartość logiczną, czyli prawda lub fałsz. W naszym przykładzie dokonujemy sprawdzenia, czy wyprowadzenie P3.0 jest w stanie niskim. Jeśli tak, to oznacza to, że naciśnięty został przycisk podłączony do tego wyprowadzenia. Należy podjąć wtedy odpowiednie działanie, czyli ustawić wyprowadzenie P0.0 w stan niski. Początkujących adeptów programowania w jezyku C może zadziwić znak "==", czyli operator porównania. Jest on inny niż w językach Basic lub Pascal i z początku bardzo łatwo się myli z operatorem przypisania "=". Instrukcja if może także wyglądać następująco:
Słowo else (w przeciwnym przypadku) umieszczone przed instrukcja2 mówi, że instrukcja2 zostanie wykonana tylko wtedy, gdy warunek instrukcji if będzie niespełniony, czyli będzie wartości false. W sytuacji, gdy w przypadku spełnienia danego warunku wykonanych ma być kilka instrukcji, to należy blok tych instrukcji ująć w nawiasy klamrowe {}:
Instrucka iteracyjna for
inicjalizacja zmiennej licznikowej - jest
to przypisanie do zmiennej licznikowej jej wartości początkowej W przykładowym programie wykorzystamy pętlę for do wygenerowania pewnego opóźnienia. Funkcja generująca opóźnienie (a raczej przerwę w wykonywaniu programu) jest bardzo przydatna przy współpracy mikrokontrolera z wolniejszymi układami peryferyjnymi, gdzie trzeba czekać np. na zakończenie pomiaru, itp. W naszym programie wykorzystamy funkcję opóźniającą do generowania prostego efektu świetlnego na diodach LED. Kod programu przedstawiony jest poniżej :
Po raz pierwszy stworzyliśmy własną funkcję. Zgodnie z tym, co napisałęm w pierwszej części kursu, funkcja czekaj nie zwraca zadnej wartości (void) i wymaga jednego parametru typu unsigned char (liczba 8-bitowa bez znaku). Parametrem tym będzie żadana przez nas długość opóźnienia (mniej-więcej w milisekundach). Przyjrzyjmy sie pierwszej pętli for :
Brakuje tutaj części inicjalizacji zmiennej licznikowej, ponieważ tą zmienną jest parametr przekazywany do funkcji. Gdybyśmy w tym miejscy zainicjalizowali zmienną x, to przekazywany parametr zostałby zamazany. W pętli for może brakować dowolnego elementu - może nawet pętla for wyglądać następująco :
W takim przypadku pętla ta będzie wykonywana bez końca. Nasza funkcja opóźniająca składa się z trzech zagnieżdzonych
pętli for. Wwyniku tego łączny czas wykonywania tych pętli jest iloczynem
powtórzeń każdej pętli. Dokłądny czas opóźnienia trudno jest określić, ponieważ
ze wzgledu na rózne techniki optymalizacji kodu przez kompilator nie jest
znany dokłądny czas wykonywania jednej pętli. Można co prawda odczytać z pliku
*.asm generowanego przez kompilator jakie instrukcje zostały uzyte do realizacji
tych pętli i określić dokładny czas ich wykonania, ale nie mamy gwarancji,
że po zmianie bądź warunku pętli, badź wartości początkowych oraz końcowych
kompilator nie zastosuje innego kodu. Tak więc generowanie opóźnień za pomocą
pętli jest przydatne tylko przy generowniu przyblizonych opóźnień. Do odmierzania
dokładnych odcinków czasu należy zastosować wewnętrzne timery mikrokontrolera.
|
|||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
|
(c) 2004-2008 Radosław Kwiecień |