Ćwiczenie nr 1: TEMAT: Sterowanie 7
Transkrypt
Ćwiczenie nr 1: TEMAT: Sterowanie 7
POLITECHNIKA CZĘSTOCHOWSKA, WYDZIAŁ INŻYNIERII MECHANICZNEJ I INFORMATYKI KATEDRA INŻYNIERII KOMPUTEROWEJ Laboratorium Systemów Mikroprocesorowych TEMAT: Ćwiczenie nr 1: Sterowanie 7-segmentowym wyświetlaczem LED oraz odczytywanie stanu przycisków. Sterowanie portami mikrokontrolera SAB80C537 1.Wiadomości podstawowe Port mikrokontrolera to grupa wyprowadzeń (w mikrokontrolerach 8-bitowych jest ich najczęściej osiem) mogących służyć do wysyłania lub odbierania sygnałów przez mikrokontroler do urządzeń zewnętrznych. Porty mogą być: - wejściowe, do których podłączona jest klawiatura, przetwornik analogowo-cyfrowy lub inne sygnały wejściowe, - wyjściowy – wysyłający sygnały na zewnątrz np. na wyświetlacz LED, - wejściowo/wyjściowy – konfigurowalny przez użytkownika poprzez specjalne rejestry. W mikrokontrolerze SAB80C537 portami wejściowymi są porty P7 i P8. Służą one między innymi do odczytu wartości analogowych poprzez wbudowany przetwornik analogowo-cyfrowy. Pozostałe porty mogą natomiast zostać wykorzystywane zarówno jako porty wejściowe jak i wyjściowe. Warunkiem pracy portu jako wejściowy jest ustawienia stanu jego wyjść w stan wysoki (wpisanie jedynki na każdą z jego linii). Stanu pracy jako wyjście nie trzeba deklarować. Po uruchomieniu kontrolera domyślnym stanem pracy wszystkich portów jest stan pracy jako wejście. 2.Instrukcje ustawiające stan portów Ustawienie linii portu wyjściowego na żądany sygnał jest możliwe na dwa sposoby: A. indywidualne ustawianie każdej z ośmiu linii portu instrukcjami CLR bit, SETB bit, MOV bit,C, np.: - CLR P1.3 - ustawienie stanu linii trzeciej portu P1 na zero (stan niski) - SETB P1.7 – ustawienie stanu linii siódmej portu P1 na jeden (stan wysoki) - MOV P2.0,C - ustawienie linii 0 portu P2 zgodnie ze stanem bitu C (bitu przeniesienia) B. grupowe ustawianie stanu wszystkich linii jedną instrukcją MOV port,rejestr np: - MOV P1,A – przesłanie zawartości rejestru A (akumulatora) na port P1, - MOV P2,R7 – przesłanie zawartości uniwersalnego rejestru R7 na port P2. (w tym przypadku stan wszystkich ośmiu linii wskazanego portu ustawiona zostanie zgodnie z zawartością 8 bitów wskazanego rejestru) 3.Instrukcje testujące (odczytujące) stan portów Odczyt stanu linii portów możliwy jest podobnie jak zapis na dwa sposoby: A. indywidualne odczytanie wybranej linii portu do wskaźnika przepelnienia C np: - MOV C,P1.3 - odczyt stanu trzeciej linii portu P1 do wskaźnika C. B. Grupowe odczytanie wszystkich ośmiu linii portu do wybranego rejestru instrukcją MOV rejestr, port np.: - MOV A,P1 – przesłanie stanu całego portu P1 (wszystkich ośmiu linii) do rejestru A (akumulatora), - MOV R7,P2 – przesłanie stanu całego portu P2 (wszystkich ośmiu linii) do rejestru R7 (w tym przypadku stan wszystkich ośmiu bitów wskazanego rejestru ustawiona zostanie zgodnie z zawartością 8 linii wskazanego portu) Jednak najczęściej wykorzystywane są instrukcje testujące stan portów i wykonujące od razu odpowiednie działanie (np. skok do wskazanej procedury jeśli stan wybranej linii portu przyjmie określaną wartość), są to instrukcje: - JB bit, etykieta – skok do określonego miejsca w programie (etykieta) jeśli wybrany bit jest ustawiony (na wybranej linii portu występuje stan wysoki), - JNB bit, etykieta – j.w. ale skok zostanie wykonany gdy wybrany bit jest skasowany (na wybranej linii portu występuje stan niski). np. JNB P7.3, klawisz3_wcisniety - skoczy do etykiety klawisz3_wcisniety jeśli stan linii trzeciej portu P7 będzie niski, w przeciwnym przypadku skok nie zostanie wykonany i program będzie kontynuował pracę. 4. Przykłady Przykład 1. Do 8 linii portu P1 podpiętych jest osiem segmentów wyświetlacza 7-segmentowego LED. Ustawienie wybranej linii portu w stan wysoki powoduje zapalenie odpowiedniego segmentu, przy stanie niskim wybrany segment jest zgaszony. Należy ustawić tak linie portu aby wyświetlacz pokazywał cyfrę siedem. Przyporządkowanie odpowiednich linii portu do segmentów oraz możliwe do uzyskania znaki na takim wyświetlaczu pokazuje rysunek: Uwaga! Przyporządkowanie świecących segmentów do poszczególnych linii może być inne (należy to sprawdzić doświadczalnie), odwrotny może być również sposób sterowania segmentu – segment może świecić się przy poziomie logicznym wysokim lub niskim na odpowiedniej linii portu. 0 0 0 0 0 1 1 1 bity: 7 6 5 4 3 2 1 0 Rozwiązanie: Linie 0,1,2 portu P1 należy ustawić w stan wysoki, pozostałe linie w stan niski. Można tego dokonać instrukcjami: MOV A, #00000111B ;B oznacza zapis binarny MOV P1, A Przykład 2. Do linii 0 portu P1 podpięty jest klawisz w ten sposób, że jego wciśniecie powoduje ustawienie stanu niskiego na tej linii. Napisać program zwiększający zawartość zmiennej LICZNIK o jeden gdy nastąpi wciśnięcie klawisza. Rozwiązanie: Ponieważ linia portu pracowała będzie jako wejście powinna mieć być ustawiona na stan wysoki, np. poprzez instrukcję SETB P1.0. Do testowania stanu portu wykorzystamy instrukcję JNB bit, etykieta. Sekwencja instrukcji realizująca zadanie wyglądała będzie następująco: SETB P1.0 ;ustawienie linii portu na wejście poprzez podanie stanu wysokiego na tą linię PETLA: JNB P1.0, KLAWISZ_WCISNIETY ;skok gdy klawisz wciśnięty JMP PETLA ;powtarzaj sprawdzanie klawisza przez cały czas KLAWISZ_WCISNIETY: MOV A, LICZNIK ;przepisanie zawartości zmiennej LICZNIK do A ADD A,#1 ;kontroler potrafi dodawać liczby tylko do akumulatora A MOV LICZNIK, A ;przepisanie zwiększonej zawartości akumulatora z powrotem do ;zmiennej LICZNIK ;zawartość zmiennej została zwiększona więc można powrócić do programu głównego JMP PETLA Powyższy program ma pewną wadę. Wciśnięcie i przytrzymanie klawisza powodowało będzie bardzo szybkie wielokrotne zwiększanie zawartości zmiennej a nie jednorazowe zwiększenie w reakcji na jednokrotne wciśnięcie klawisza (jak byśmy chcieli). Dzieje się tak dlatego, iż program nie oczekuje na puszczenie klawisza po zwiększeniu zmiennej tylko przystępuje do kolejnego sprawdzania. Poprawny program będzie więc wyglądał następująco: SETB P1.0 ;ustawienie linii portu na wejście poprzez podanie stanu wysokiego na tą linię PETLA: JNB P1.0, KLAWISZ_WCISNIETY ;skok gdy klawisz wciśnięty JMP PETLA ;powtarzaj sprawdzanie klawisza przez cały czas KLAWISZ_WCISNIETY: MOV A, LICZNIK ;przepisanie zawartości zmiennej LICZNIK do A ADD A,#1 ;kontroler potrafi dodawać liczby tylko do akumulatora A MOV LICZNIK, A ;przepisanie zwiększonej zawartości akumulatora z powrotem do ;zmiennej LICZNIK ;tutaj należy poczekać na puszczenie klawisza, ;czyli pojawienie się na linii P1.0 z powrotem stanu wysokiego KLAWISZ_CIAGLE_WCISNIETY: JNB P1.0, KLAWISZ_CIAGLE_WCISNIETY ;tutaj wiemy, że klawisz nie jest już wciśnięty ;zawartość zmiennej została zwiększona więc można powrócić do programu głównego JMP PETLA Uwaga – często mimo zastosowania w.w. zabezpieczenia występuje nadal zjawisko kilkukrotnego zwiększenia licznika przy jednokrotnym wciśnięciu klawisza co jest wynikiem tzw, „iskrzenia” klawiszy. Należy w takim przypadku zastosować kolejne zabezpieczenie. Po odczekaniu na puszczenie klawisza należy odczekać jeszcze kilkaset milisekund w celu „uspokojenia się” klawisza. Można to zrobić np. poprzez wywołanie procedury wykonującej kilka tysięcy razy instrukcję NOP. Instrukcja taka nie powoduję żadnego działania ale jej wykonanie zajmuje ok. 1us, dzięki czemu można odczekać wymagany czas. Procedura oczekująca może mieć postać: czekaj_200ms: PUSH ACC ;zachowanie zawartości akumulatora na stosie MOV A,#200 ;dwieście razy wywoła procedurę czekaj_1ms petla_200ms: LCALL czekaj_1ms DJNZ ACC,petla_200ms POP ACC ;odtworzenie zawartości akumulatora ze stosu RET ;koniec procedury czekaj_200ms czekaj_1ms: PUSH ACC ;zachowanie zawartości akumulatora na stosie petla_1ms: MOV A,#250 ;250 powtórzeń po ok. 4 mikrosekundy każde NOP NOP NOP DJNZ ACC,petla_1ms POP ACC ;odtworzenie zawartości akumulatora ze stosu RET ;koniec procedury czekaj_1ms 5. Program ćwiczenia 1. Sprawdzić sposób sterowania 7-segmentowego wyświetlacza LED (wyświetlacz podpięty jest do portu P1): przyporządkowanie segmentów do linii portu oraz czy wyświetlacz zapalony jest przy stanie wysokim czy niskim na porcie. Ułożyć tablicę opisującą wszystkie 16 możliwych do uzyskania cyfr hexadecymalnych. (Uwaga – sposób wyświetlania cyfr i liter powinien być zawarty w tablicy 16-bajtowej – każdy bajt to wartość określająca kształt jednego znaku) 2. Napisać podprogram wyświetlający na wyświetlaczu LED wybrany znak (cyfrę hexadecymalną - 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f.) o numerze wskazywanym przez zawartość akumulatora. 3. Napisać program, który w reakcji na klawisz 3 (port P5.2) zwiększa o jeden cyfrę (hexadecymalną) wyświetlaną na wyświetlaczu. Należy wykorzystać podprogram z punktu 2. Wciśnięcie klawisza powoduje ustawienie linii portu w stan niski. Uwaga! należy zastosować zabezpieczenie przed wielokrotnym zwiększaniem w reakcji na jednokrotne wciśnięcie klawisza. 4. Dodać do programu z punktu 2 reakcję na klawisze 1 i 2: - klawisz 1 (port P5.0) – zmniejszenie wyświetlanej wartości o jeden, - klawisz 2 (port P5.1) – zerowanie wyświetlanej wartości. Wnioski z ćwiczenia Opisać wykorzystany sposób sterowania wyświetlaczem LED, oraz odczytywania stanu przycisków. W jaki sposób zrealizowane zostało zabezpieczenie przed niepożądanymi wielokrotnymi zmianami w reakcji na pojedyncze wciśnięcie przycisku?