Ćwiczenie 1 Wędrujące światełko

Podobne dokumenty
Ćwiczenie 2. Siedmiosegmentowy wyświetlacz LED

Ćwiczenie 7 Matryca RGB

Instytut Teleinformatyki

petla:... ; etykieta określa adres w pamięci kodu (docelowe miejsce skoku) DJNZ R7, petla

Technika Mikroprocesorowa Laboratorium 5 Obsługa klawiatury

MIKROPROCESORY architektura i programowanie

MIKROPROCESORY architektura i programowanie

ad a) Konfiguracja licznika T1 Niech nasz program składa się z dwóch fragmentów kodu: inicjacja licznika T1 pętla główna

CYKL ROZKAZOWY = 1 lub 2(4) cykle maszynowe

Spis treœci. Co to jest mikrokontroler? Kody i liczby stosowane w systemach komputerowych. Podstawowe elementy logiczne

Przerwania w architekturze mikrokontrolera X51

Pracownia elektryczno-elektroniczna klasa IV

Struktura programu w asemblerze mikrokontrolera 8051

Instytut Teleinformatyki

architektura komputerów w 1 1

Obszar rejestrów specjalnych. Laboratorium Podstaw Techniki Mikroprocesorowej Instytut Mikroelektroniki i Optoelektroniki PW

Instytut Teleinformatyki

Programowanie mikrokontrolerów. 8 listopada 2007

2. Architektura mikrokontrolerów PIC16F8x... 13

SYSTEM PRZERWA Ń MCS 51

Hardware mikrokontrolera X51

Architektura systemów komputerowych Laboratorium 14 Symulator SMS32 Implementacja algorytmów

Ćwiczenie 6 Komunikacja z komputerem (łącze RS232)

Lista instrukcji procesora 8051 część 2 Skoki i wywołania podprogramów, operacje na stosie, operacje bitowe

Ćwiczenie 9 Częstościomierz oparty na µc 8051(8052)

Lista rozkazów mikrokontrolera 8051

Politechnika Warszawska

Architektura systemów komputerowych Laboratorium 7 Symulator SMS32 Stos, Tablice, Procedury

START: ; start programu od adresu 0100H ; zerowanie komórek od 01H do 07FH ( 1 dec dec)

Architektura mikrokontrolera MCS51

Programowanie mikrokontrolera 8051

Architektura mikrokontrolera MCS51

1.2 Schemat blokowy oraz opis sygnałów wejściowych i wyjściowych

Celem ćwiczenia jest zapoznanie z obsługą klawiatury sekwencyjnej i matrycowej w systemie DSM-51.

Ćwiczenie 3 Wyświetlacz ciekłokrystaliczny

TECHNIKA MIKROPROCESOROWA

Architektura komputerów

Metody obsługi zdarzeń

MOŻLIWOŚCI PROGRAMOWE MIKROPROCESORÓW

Laboratorium 1: Wprowadzenie do środowiska programowego. oraz podstawowe operacje na rejestrach i komórkach pamięci

Wstęp Architektura... 13

Zadanie Zaobserwuj zachowanie procesora i stosu podczas wykonywania następujących programów

Start Bity Bit Stop 1 Bit Par Rys. 1

LABORATORIUM. TIMERY w mikrokontrolerach MCS 51

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Programowanie Niskopoziomowe

Przerwania, polling, timery - wykład 9

Mikrokontroler ATmega32. Język symboliczny

Pośredniczy we współpracy pomiędzy procesorem a urządzeniem we/wy. W szczególności do jego zadań należy:

Mikrokontroler ATmega32. System przerwań Porty wejścia-wyjścia Układy czasowo-licznikowe

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Organizacja pamięci VRAM monitora znakowego. 1. Tryb pracy automatycznej

Instrukcja do ćwiczenia P4 Analiza semantyczna i generowanie kodu Język: Ada

Systemy wbudowane. Uniwersytet Łódzki Wydział Fizyki i Informatyki Stosowanej. Witold Kozłowski

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Systemy wbudowane. Wprowadzenie. Wprowadzenie. Mikrokontroler 8051 Budowa

UTK Można stwierdzić, że wszystkie działania i operacje zachodzące w systemie są sterowane bądź inicjowane przez mikroprocesor.

Pamięci EEPROM w systemach mikroprocesorowych, część 2

Wyświetlacz alfanumeryczny LCD zbudowany na sterowniku HD44780

Ćwiczenie 30. Techniki mikroprocesorowe Programowanie w języku Asembler mikrokontrolerów rodziny '51

Programowanie w językach asemblera i C

SYSTEMY MIKROPROCESOROWE W AUTOMATYCE. Projekt bariery świetlnej.

Przykładowe pytania DSP 1

Zerowanie mikroprocesora

Organizacja typowego mikroprocesora

Technika mikroprocesorowa I Studia niestacjonarne rok II Wykład 2

MIKROKONTROLERY I MIKROPROCESORY

Opis układów wykorzystanych w aplikacji

Architektura komputerów. Asembler procesorów rodziny x86

Instytut Teleinformatyki

4 Transmisja szeregowa na przykładzie komunikacji dwukierunkowej z komputerem PC, obsługa wyświetlacza LCD.

LABORATORIUM nr 2. Temat: Obsługa wyświetlacza siedmiosegmentowego LED

Szkolenia specjalistyczne

Programowanie Niskopoziomowe

Liczniki, rejestry lab. 08 Mikrokontrolery WSTĘP

Temat: System przerwań, liczniki i wyświetlacz w STRC51. Ćwiczenie 3.

Asembler - język maszynowy procesora

Aby w pełni przetestować układ o trzech wejściach IN_0, IN_1 i IN_2 chcemy wygenerować wszystkie możliwe kombinacje sygnałów wejściowych.

Lista rozkazów mikrokontrolera 8051 część pierwsza: instrukcje przesyłania danych, arytmetyczne i logiczne

Temat: System przerwań, liczniki i wyświetlacz w STRC51. Ćwiczenie 3.

Programowanie mikrokontrolerów. 5 grudnia 2007

Techniki mikroprocesorowe i systemy wbudowane

1. Cel ćwiczenia. 2. Podłączenia urządzeń zewnętrznych w sterowniku VersaMax Micro

Zygmunt Kubiak Instytut Informatyki Politechnika Poznańska

Adresowanie obiektów. Adresowanie bitów. Adresowanie bajtów i słów. Adresowanie bajtów i słów. Adresowanie timerów i liczników. Adresowanie timerów

LABORATORIUM UKŁADY WY Ś WIETLANIA INFORMACJI Z WY Ś WIETLACZAMI 7-SEGMENTOWYMI LED

TMiK Podstawy Techniki Mikroprocesorowej. Lidia Łukasiak

Kurs Podstawowy S7. Spis treści. Dzień 1

Mikroprocesor Operacje wejścia / wyjścia

4 Transmisja szeregowa, obsługa wyświetlacza LCD.

1. Wprowadzenie Programowanie mikrokontrolerów Sprzęt i oprogramowanie... 33

Logiczny model komputera i działanie procesora. Część 1.

Przedmiot : Programowanie w języku wewnętrznym. Ćwiczenie nr 4

Podstawy Informatyki Języki programowania c.d.

Ćwiczenie nr 3. Wyświetlanie i wczytywanie danych

Technika mikroprocesorowa I Wykład 2

Język C. Wykład 9: Mikrokontrolery cz.2. Łukasz Gaweł Chemia C pokój 307

Opis procedur asemblera AVR

Architektura komputerów

ARCHITEKTURA PROCESORA,

Transkrypt:

Ćwiczenie 1 Wędrujące światełko Program = Data structures + Algorithm -- Niklaus Wirth Warszawa, 2007-10-16

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -2-1. Cel ćwiczenia Celem ćwiczenia jest praktyczne zapoznanie się z wykorzystywanym w Laboratorium Systemem Uruchomieniowym a także ze Zintegrowanym Środowiskiem Uruchomieniowym Keil µvision 2. W części praktycznej należy zmodyfikować otrzymane programy w taki sposób, aby uzyskać efekt "wędrującego" światełka. 2. Część pierwsza - opóźnienie programowe 2.1. Początek programu Początek programu należy umieścić na początku pamięci programu pod adresem 0000H. Odpowiednia dyrektywa asemblera określająca adres początku programu to: cseg at 0000H Powoduje ona, że program użytkownika zostanie umieszczony w pamięci programu począwszy od adresu 0000H. UWAGA! Litera 'H' lub 'h' na końcu liczby oznacza, że stosowany jest zapis heksadecymalny. Litera 'B' lub 'b' oznacza zapis binarny. Jeżeli na końcu liczby nie ma informacji o zapisie, albo też występuje litera D lub d, liczba jest uważana za dziesiętną. Inne elementy programu, których początek wymaga umieszczenia pod określonym adresem pamięci programu to procedury obsługi przerwań. W przypadku klasycznego kontrolera 8052 adresy (tzw. wektory przerwań), pod którymi należy umieścić początki procedur obsługi przerwań są następujące: Tabela1. Adresy procedury obsługi przerwania w mikrokontrolerze 8052 Wektor przerwania Rodzaj przerwania 0003H Przerwanie zewnętrzne 0 (INT0) 000BH Przerwanie licznika T0 0013H Przerwanie zewnętrzne 1 (INT1) 001BH Przerwanie licznika T1 0023H Przerwanie portu szeregowego 002BH Przerwanie licznika T2 W programie użytkowym fragment programu odpowiadający za właściwe umieszczenie w pamięci programu początku programu i procedur obsługi przerwań wygląda następująco: cseg at 0000H ; po włączeniu napięcia zasilania lub zerowaniu (RESET) procesora wykonywanie programu rozpoczyna się od adresu 0000H jmp Start ; instrukcja skoku do rzeczywistego początku programu org 0003H ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 0003H 2

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -3- jmp INT0_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania zewnętrznego INT0 org 000BH ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 000BH jmp T0_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania licznika T0 org 0013H ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 0013H jmp INT1_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania zewnętrznego INT1 org 001BH ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 001BH jmp T1_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania licznika T1 org 0023H ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 0003H jmp RS_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania portu szeregowego org 002BH ; dyrektywa asemblera umieszczająca następujący po niej fragment programu pod adresem 002BH jmp T2_HANDLER ; skok do rzeczywistego początku procedury obsługi przerwania licznika T2 2.2. Konfiguracja mikrokontrolera C8051F060 Mikrokontroler C8051F060 zastosowany w systemie uruchomieniowym jest znacznie bardziej skomplikowany niż klasyczny układ 8051. Posiada m.in. watchdog, tj. licznik, który po przepełnieniu powoduje zerowanie procesora. Dzięki temu można zabezpieczyć system przed niewłaściwym działaniem np. w wyniku zakłócenia elektromagnetycznego. W ćwiczeniu watchdog nie jest nam potrzebny, dlatego wyłączamy go zapisując do rejestru specjalnego WDTCN odpowiednie wartości: mov mov WDTCN, #0DEH WDTCN, #0ADH UWAGA! Jeżeli przy zapisie heksadecymalnym liczby najstarszym znakiem jest litera, to musi być ona poprzedzona cyfrą 0. W przeciwnym przypadku asembler potraktuje liczbę jak symbol w powyższym przypadku jako symbol DEH, a potem ADH. UWAGA! Znak "#" oznacza, że do rejestru WDTCN zostaje wpisana wartość 0DEH (w przypadku pierwszej instrukcji). Gdybyśmy opuścili znak "#", czyli gdyby nasza instrukcja wyglądała następująco: mov WDTCN, 0DEH, to do rejestru specjalnego WDTCN zostałaby załadowana zawartość bajtu wewnętrznej pamięci danych o adresie 0DEH (byłaby to zawartość jakiegoś rejestru specjalnego. Wówczas drugi argument byłby także przypadkiem adresowania bezpośredniego). Innymi słowy #0DEH jest w tej instrukcji argumentem bezpośrednim, tzn. jest umieszczony w sposób jawny w treści rozkazu. 3

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -4- Rejestry specjalne w klasycznym układzie 8051 zajmują 128 bajtów. Mikrokontroler C8051 potrzebuje znacznie większej liczby rejestrów specjalnych, aby skonfigurować wszystkie zintegrowane urządzenia peryferyjne (liczniki, porty, przetworniki AC, CA, itd.). Kompatybilność programowa ze starszymi wersjami rodziny MCS51 narzuca ograniczenie liczby rejestrów specjalnych dostępnych jednocześnie do 128. W mikrokontrolerze C8051F060 wprowadzono zatem przełączanie stron SFR za pomocą rejestru SFRPAGE. Klasyczny układ 8051 ma tylko 4 porty (P0-P3). Aby możliwe było wykorzystanie portów P7 i P5 konieczne jest włączenie odpowiedniej strony rejestrów specjalnych za pomocą instrukcji: mov SFRPAGE, #CONFIG_PAGE Wartość CONFIG_PAGE (0FH) zdefiniowano w pliku nagłówkowym 8051F060.INC W mikrokontrolerze C8051F060 istnieją ograniczone możliwości przypisania pewnych funkcji (np. linie drugiego portu szeregowego lub interfejsu I2CBUS) do wybranego portu. Przypisania tego dokonuje się poprzez konfigurację krosownicy (crossbar). W naszym przypadku konfiguracja krosownicy ma następującą postać: mov XBR2, #040H 2.2. Inicjalizacja wskaźnika stosu Po włączeniu zasilania mikrokontrolera (RESET) wskaźnik stosu SP (rejestr specjalny SFR) ma wartość 07, czyli wskazuje na rejestr R7 w Banku 0 rejestrów. Ponieważ rejestry R będą nam potrzebne w programie jako rejestry robocze, przesuniemy początek stosu w inne, dogodniejsze miejsce. Najwygodniej będzie umieścić początek stosu na początku adresowanego bajtowo obszaru wewnętrznej pamięci danych, czyli pod adresem 30H. Aby dokonać inicjalizacji stosu najpierw zdefiniujemy symbol (definiowanie symbolicznych nazw stałych i zmiennych nie jest to konieczne, ale jest bardzo wygodne i eleganckie): TOS equ 30H ; Top Of Stack (wierzchołek stosu) Definicje symboli umieszcza się w pliku źródłowym powyżej dyrektywy cseg at 0000H UWAGA! wszystko to, co znajduje się w linii po średniku, to komentarz ignorowany w procesie asemblacji. W programie nadajemy wskaźnikowi stosu wartość symbolu TOS: mov SP, #TOS Stos jest specjalną strukturą danych typu LIFO (Last In First Out) obsługiwaną sprzętowo, występującą we wszystkich mikroprocesorach. Będzie nam on potrzebny co najmniej w trzech przypadkach: 4

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -5- przy wywoływaniu i powrocie z podprogramów do odkładania adresu powrotu przy wywoływaniu podprogramu instrukcją call i pobierania adresu powrotu przy kończeniu podprogramu instrukcją, przy obsłudze przerwań do odkładania adresu powrotu przy skoku do procedury obsługi przerwania i pobierania adresu powrotu przy kończeniu procedury obsługi przerwania instrukcją i, do tzw. przełączania kontekstu przejściowego odkładania zawartości rejestrów roboczych na stos (instrukcja push) w procedurze obsługi przerwania w celu ochrony ich zawartości, wykorzystania tych rejestrów dla realizacji procedury, odtworzenia oryginalnej zawartości rejestrów (instrukcja pop) przed powrotem z procedury. UWAGA! Należy pamiętać, że dane ze stosu pobiera się w odwrotnej kolejności niż zostały odłożone (LIFO). Dlatego też wewnątrz procedury liczba instrukcji odkładania danych na stos musi być dokładnie równa liczbie instrukcji zdejmowania ze stosu. Co więcej każda instrukcja zdejmowania danej ze stosu musi być poprzedzona instrukcją odkładania danej na stos. W przeciwnym razie w trakcie wychodzenia z procedury za pomocą instrukcji lub i zamiast adresu powrotu (odłożonego w trakcie wykonywania instrukcji call) ze stosu zostanie pobrana wartość, która spowoduje skok do przypadkowego miejsca w pamięci programu, a tym samy błędne działanie programu. Takie błędy są trudne do wykrycia. 2.4. Komunikacja z urządzeniami WE/WY (modułami peryferyjnymi) Urządzenia zewnętrzne podłączono do portów mikrokontrolera, które programista widzi jako odpowiednie rejestry specjalne (SFR special-function register). Diody LED obsługiwane w ćwiczeniu nr 1 podłączono do portu P7 poprzez 8-krotny przerzutnik 74HCT574 wyzwalany zboczem narastającym (port P7 obsługuje również wyświetlacz ciekłokrystaliczny, toteż potrzebna jest możliwość zapamiętania danych wysłanych do diod LED). W systemie uruchomieniowym diody te stanowią dodatkową (6-tą) pozycję wyświetlacza 7- segmentowego. Wybraną pozycję wyświetlacza steruje się (włącza/wyłącza) odpowiednim bitem portu P2 (w przypadku diod LED jest to bit P2.5). Zapamiętanie danych wysłanych do przerzutnika 74HCT574 następuje po pojawieniu się zbocza narastającego na wejściu sterującym (P5.6). Dioda jest wyłączana, jeżeli na odpowiadającym jej bicie portu P7 wystawimy 0, a włączana, jeżeli wystawimy 1. Program powinien być możliwie jak najbardziej czytelny, toteż zdefiniujemy następujące symbole (definicje symboli umieszcza się w pliku źródłowym powyżej dyrektywy cseg at 0000H): LEDs equ P2.5 ; bit aktywujący diody LED CK_D equ P5.6 ; sygnał sterujący przerzutnikiem D zapamiętującym dane dla diod LED Fragment programu włączający wszystkie diody LED wygląda następująco: clr LEDs ; uaktywnienie diod LED mov P7, #0FFH ; zapis danych dla LED do przerzutnika clr CK_D ; generacja dodatniego zbocza na wejściu sterującym setb CK_D ; przerzutnika (zapamiętanie danych w przerzutniku) Schemat elektryczny obwodu z diodami LED zamieszczono na rys. 1, uproszczone rozmieszczenie elementów na płytce drukowanej na rys. 2. 5

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -6- Rys. 1. Schemat elektryczny podłączenia wyświetlacza 7-segmentowego oraz diod LED. Rys. 2. Rozmieszczenie elementów na płytce Przypisanie linii portu P7 do poszczególnych diod przedstawiono w Tabeli 2. Tabela 2. Przypisanie linii portu P7 do poszczególnych diod Dioda Kolor Bit sterujący D1 niebieska P7.0 D2 niebieska P7.1 D3 czerwona P7.4 D4 czerwona P7.5 D5 zielona P7.6 D6 zielona P7.7 D7 żółta P7.2 D8 żółta P7.3 6

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -7-2.4. Algorytm Program startowy cyklicznie zapala i gasi wszystkie diody. Ponieważ mikrokontroler jest bardzo szybki w stosunku do czasu reakcji ludzkiego oka, pomiędzy kolejne operacje zapalania i gaszenia LED-ów należy wprowadzić opóźnienie, w przeciwnym razie ludzkie oko będzie widziało światło ciągłe, chociaż trochę mniej intensywne. Algorytm programu wygląda następująco: inicjalizacja, zapalenie diody, opóźnienie, zgaszenie diody, opóźnienie, itd. Opóźnienie, równe w przybliżeniu 460 ms, jest zrealizowane programowo z wykorzystaniem trzech rejestrów roboczych: R5, R6 i R7. Procedura (podprogram) poczekaj wygląda następująco: poczekaj: ; generacja opoznienia mov R5, #07H ; 2 cykle duze: mov R6, #0FFH ; 2 cykle srednie: mov R7, #0FFH ; 2 cykle male: djnz R7, male ; 3 cykle, jeżeli skok wykonywany, 2 cykle, jeżeli skok nie wykonywany djnz R6, srednie ; 3 cykle, jeżeli skok wykonywany, 2 cykle, jeżeli skok nie wykonywany djnz R5, duze ; 3 cykle, jeżeli skok wykonywany, 2 cykle, jeżeli skok nie wykonywany ; 5 cykli Wykonanie pętli male trwa 254 3 + 2 = 764 cykle (254 razy instrukcja djnz wykonuje skok, toteż czas trwania wynosi 3 cykle, za 255. razem skoku nie wykonuje, a jej wykonanie trwa dwa cykle. Wykonanie pętli srednie trwa (2 + 764 + 3)*254 + 2 + 764 +2 = 196 094 cykle (do czasu wykonania pętli male dodajemy czas wykonania instrukcji mov R7, #0FFH, tj. 2 cykle oraz instrukcji djnz R6, srednie, tj. 254 razy 3 cykle i raz 2 cykle). Wykonanie pętli duze trwa (2 + 196094 + 3) 6 + 2 + 196 094 + 2 = 1 372 692 cykle. Wykonanie całej procedury poczekaj trwa 588 296 + 2 (mov R5, #07H) + 5() + 4(call poczekaj) = 1 372 703 cykli. Domyślnie częstotliwość zegara systemowego jest 8-krotnie niższa niż częstotliwość oscylatora, czyli f zegar = 24,5MHz/8 3 MHz (1cykl = 1 takt zegara), czas opóźnienia wynosi ok. 460 ms. UWAGA! Występujące w powyższej procedurze symbole poczekaj, duze, srednie i male, zakończone dwukropkiem, to tzw. etykiety. W czasie asemblacji programu etykietom nadawana jest wartość adresu początku instrukcji występującej bezpośrednio po nich, tak więc np. etykiecie poczekaj nadawana jest wartość adresu pierwszego bajtu instrukcji mov R5,#07H. Etykiety umożliwiają symboliczne wskazywanie miejsca w programie źródłowym, zamiast podawania bezwzględnego adresu, co bardzo ułatwia pisanie programów i czyni je znacznie czytelniejszymi ( piszemy jmp poczekaj a nie jmp 1234, gdzie 1234 to adres pierwszego bajtu instrukcji mov R5,#07H). 2.5. Zakończenie programu Na końcu pliku źródłowego musi się znaleźć dyrektywa: end 7

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -8- UWAGA! Występujące w programie źródłowym dyrektywy, deklaracje stałych, zmiennych nie są instrukcjami procesora a informacjami dla programu ASEMBLER tłumaczącego program źródłowy na kod maszynowy. W szczególności dyrektywa end nie jest kodem instrukcji kończącej program (nie ma takiej instrukcji w liście rozkazowej mikroprocesorów) a informacją dla ASEMBLERA, że dana linia programu (zawierająca dyrektywę end) jest ostatnią linią tekstu programu. 2.7. Przebieg ćwiczenia Zespół otrzymuje gotowy program, który cyklicznie zapala i gasi wszystkie diody LED. Wydruk tekstu źródłowego znajduje się na końcu niniejszej instrukcji. wszystkie diody zapalone wszystkie diody zgaszone 2.6. Zadanie do wykonania: Zmodyfikować istniejący program tak, aby zapalona dioda "przesuwała" się najpierw od D1 do D7 w sposób pokazany na rys. 3a, a potem od D7 do D1 w sposób pokazany na rys. 3b. Rys. 3a. Sposób przesuwania zapalonej diody od D1 do D7 Rys. 3b. Sposób przesuwania zapalonej diody od D7 do D1 Sposób przypisania linii portu P7 do poszczególnych diod nie pozwala na realizację postawionego zadania za pomocą prostego algorytmu, np. obracania zawartości słowa sterującego diodami. Najprostszym sposobem realizacji zadania jest umieszczenie w pamięci programu tablicy zawierającej kolejne słowa sterujące stanem diod. Umieszczenie tablicy polega na umieszczeniu w odpowiednim miejscu programu etykiety (nazwa tablicy), podaniu dyrektywy db (define byte) oraz podaniu elementów tablicy rozdzielonych przecinkami. W 8

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -9- podanym poniżej przykładzie elementy tablicy nie muszą odpowiadać sekwencji pokazanej na rys. 3a i 3b. Tablica: db ; adres bazowy tablicy znaków 3FH, 25, 00110011b, X Dyrektywa db (define byte) inicjalizuje bajt/y w pamięci programu. Pierwszy zdefiniowany bajt jest umieszczony pod adresem Tablica, następny pod adresem o 1 większym, itd. Zapis X oznacza kod ASCII litery X Dostęp do tablicy danych umieszczonych w pamięci programu jest możliwy za pomocą instrukcji: movc A, @A+DPTR W wyniku wykonania tej instrukcji do akumulatora zostaje przesłana zawartość komórki pamięci programu o adresie równym sumie początkowej zawartości akumulatora oraz zawartości wskaźnika danych DPTR. Aby odwołać się do uprzednio zdefiniowanej tablicy znaków, trzeba nadać wartość początkową wskaźnikowi danych (adres początku tablicy): mov DPTR, #Tablica Jeżeli teraz chcemy pobrać do akumulatora, ze zdefiniowanej tablicy, wybrany element tablicy, to do akumulatora musimy wpisać jego numer (elementy liczone są od zera) i wykonać instrukcję: movc A, @A+DPTR Jeżeli przykładowo chcemy pobrać element X, to odpowiedni program będzie wyglądał nastepująco: mov DPTR, #Tablica mov A, #3 movc A, @A+DPTR Pobranie innych elementów tablicy wymaga odpowiedniej modyfikacji zawartości akumulatora lub wskaźnika danych (za pomocą instrukcji inc DPTR). UWAGA: tablicę znaków trzeba umieścić w takim miejscu programu, aby licznik rozkazów nie mógł przyjąć wartości odpowiadających adresom w obszarze tablicy znaków, gdyż oznaczałoby to, że pewien fragment tablicy zostanie potraktowany jako kolejna instrukcja do wykonania. Tablica może być umieszczona np. bezpośrednio po instrukcji bezwzględnego skoku (jmp) albo po instrukcji czy i. Program realizujący zadanie z wykorzystaniem opóźnienia programowego (c:\lab_tm\8051\ \przyklady\ diodki.a51) 9

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -10- $NOMOD51 #include <C8051F060.INC> ; DEFINICJE SYMBOLI aktywacja_backlight equ P5.3 ; obsluga podswietlenia LCD LEDs equ P2.5 ; aktywacja diod LED CK_D equ P5.6 ; obsluga bufora sterujacego diodami LED TOS equ 30H ; wierzcholek stosu zapal_wszystko equ 0FFH ; zapalenie wszystkich diod ; Umieszczenie poczatku programu pod adresem 0000H cseg AT 0000h ; Konfiguracja mikrokontrolera mov WDTCN, #0DEh ; wylaczenie watchdoga mov WDTCN, #0ADh ; wylaczenie watchdoga mov SFRPAGE, #CONFIG_PAGE ; wlaczenie odpowiedniej konfiguracji ; SFR-ow mov XBR2, #040h ; wlaczenie krosownicy ; PROGRAM GLOWNY ; inicjalizacja mov SP, #TOS ; inicjalizacja stosu clr aktywacja_backlight ; wylaczenie podswietlania LCD clr LEDs ; uaktywnienie diod LED mov A, #zapal_wszystko ; zaladowanie samych jedynek do akumulatora ; glowna petla programu miga: call zapis_led ; wywolanie procedury zapis_led call poczekaj ; wywolanie procedury poczekaj cpl A ; negacja akumulatora jmp miga ; skok do etykiety miga ;----------------------------------------------------------------------------------------------- ; PROCEDURY ;----------------------------------------------------------------------------------------------- zapis_led: ; wyslanie danych do diod LED mov P7, A nop ; 'no operation' - opoznienie nop clr CK_D ; obsluga bufora sterujacego diodami LED nop ; 'no operation' - opoznienie nop setb CK_D ;----------------------------------------------------------------------------------------------- poczekaj: ; generacja opoznienia 10

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -11- mov R5, #07H duze: mov R6, #0FFH srednie: mov R7, #0FFH male: djnz R7, male djnz R6, srednie djnz R5, duze ;------------------------------------------------------------------------------------------------- end ; dyrektywa informujaca, ze skończył się plik źródłowy 3. Część druga opóźnienie sprzętowe Celem drugiej części ćwiczenia jest zaprogramowanie mikrokontrolera 8051 tak, aby uzyskać efekt "wędrującego" światełka z odmierzaniem opóźnienia za pomocą wewnętrznego licznika T0 i wykorzystaniem systemu przerwań do obsługi tego licznika. W ćwiczeniu zostanie wykorzystane tylko jedno źródło przerwań - licznika T0. Zgodnie z dokumentacją 8051 początek procedury obsługi przerwania pochodzącego od licznika T0 musi być umieszczony pod adresem 000BH. org jmp 000BH Timer0_Int gdzie Timer0_Int to nazwa procedury (etykieta) obsługi przerwania (symbol definiowany przez programistę). Nie umieszcza się w tym miejscu całej procedury obsługi przerwania, gdyż "zakryłaby" ona adresy procedur obsługi przerwań zgłoszonych przez inne źródła. Licznik T0 może pracować w czterech trybach: tryb 0 - licznik 13-bitowy tryb 1 - licznik 16-bitowy tryb 2 - licznik 8-bitowy z automatycznym przeładowaniem (autoreload) tryb 3 - dwa niezależne liczniki 8-bitowe Do programowania trybu pracy służy rejestr specjalny (SFR) TMOD (niedostępny bitowo): GATE C/T M1 M0 GATE C/T M1 M0 1444442444443 1444442444443 licznik T1 licznik T0 Dla potrzeb niniejszego ćwiczenia licznik T0 powinien być 16-bitowym licznikiem (tryb 1 - M1 = 0, M0 = 1) impulsów zegarowych (czasomierzem - C/T = 0), bramkowanie sygnałem zewnętrznym nie może być stosowane (GATE = 0). W tej sytuacji słowo programujące licznik T0 jest następujące: 11

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -12- xxxx0001b gdzie x oznacza, że wartość bitu nie jest istotna Licznik T1 może być używany do taktowania portu szeregowego wykorzystywanego przez system uruchomieniowy do komunikacji z komputerem, dlatego najlepiej tak zaprogramowaće licznik T0, aby nie zmienić wartości czterech starszych bitów rejestru TMOD programujących licznik T1. Zostanie to zrealizowane następująco: T0_TMOD equ 01H ; definicja symbolu anl TMOD, #11110000B ; wyzerowanie młodszej części rejestru TMOD orl TMOD, #T0TMOD ; zaprogramowanie licznika T0 Z punktu widzenia programisty licznik T0 jest widoczny jako dwa 8-bitowe rejestry specjalne TH0 i TL0. Aby licznik odmierzał zadane opóźnienie, w rejestrach musi się znaleźć odpowiednia wartość początkowa. Domyślnie częstotliwość zliczania jest 12 razy niższa od częstotliwości zegara (oznacza to, że licznik zlicza co ok. 4µs). Przerwanie jest zgłaszane wtedy, gdy następuje zmiana zawartości licznika z wartości maksymalnej (0FFFFH=65535) na zero przepełnienie licznika. Maksymalne opóźnienie wynosi zatem ok. 262 ms (65536 4µs). W ćwiczeniu potrzebne jest opóźnienie ok. 400 ms. Zostanie ono zrealizowane w następujący sposób: licznik odliczy opóźnienie równe 4 ms, a zmiana stanu diod nastąpi po odliczeniu 100 przerwań. Opóźnienie licznika równe 4 ms oznacza ok. 1000 zliczeń, toteż wartość początkowa jest równa 65535-1000 + 1. Dodanie jedynki na końcu wynika stąd, że "przewinięcie" licznika do wartości równej zero wymaga dodatkowych 4µs. Załadowanie wartości początkowej może wyglądać następująco: T0_Reload equ 65536-1000 ; definicja symbolu Timer0_Reload: ; procedura inicjalizacji rejestru licznika T0 mov TH0, #High(T0_Reload) ; załaduj starszy bajt T0_Reload to TH0 mov TL0, #Low(T0_Reload) ; załaduj młodszy bajt T0_Reload to TL0 W tym celu odliczenia 100 przerwań należy zdefiniować bitowy wskaźnik (flagę), który poinformuje program główny, że zgłosiło się setne przerwanie. Potrzebny będzie również licznik liczby zgłoszonych przerwań: Ready bit 0 ; wskaźnik odmierzonego opóźnienia bit 20H.0 Del equ 7FH ; adres licznika liczby zgłaszanych przerwań DelReload equ 100 ; liczba przerwań do odliczenia Inicjalizacja licznika T0 wygląda następująco: Timer0_Init: ; wybranie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #TIMER01_PAGE ; skonfigurowanie licznika T0 w trybie 1 (16-bitowy) anl TMOD, #0F0H ; iloczyn logiczny zawartosci rejestru TMOD i stalej 0F0H orl TMOD, #T0_TMOD ; suma logiczna zawartosci rejestru TMOD i stalej ; T0_TMOD ; zapisanie wartosci poczatkowej licznika 12

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -13- call Timer0_Reload ; uruchomienie licznika setb TR0 ; nadanie wartosci 1 bitowi TR0 (TCON) ; przywrocenie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #CONFIG_PAGE Konieczne jest również uaktywnienie systemu przerwań setb ET0 ; aktywacja przerwania licznika T0 setb EA ; globalna aktywacja systemu przerwań Organizacja rozszerzenia opóźnienia jest następująca: wskaźnik Ready jest zerowany na początku programu, a do licznika zgłoszonych opóźnień podstawiana jest wartość 50: clr Ready ; wyzerowanie wskaźnika mov Del, #DelReload ; rozszerzenie opóźnienia W procedurze obsługi przerwania zawartość Del jest dekrementowana. Jeżeli w wyniku dekrementacji zawartość ta jest równa zeru, to znaczy, że zgłosiło się 50-te przerwanie, założone opóźnienie zostało zatem odmierzone. W tej sytuacji wskaźnik Ready jest ustawiany, a do komórki pamięci o adresie Del podstawiana jest ponownie wartość 50, aby odmierzyć kolejne opóźnienie. W całości procedura obsługi przerwania wygląda następująco: Timer0_Init: ; wybranie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #TIMER01_PAGE ; skonfigurowanie licznika T0 w trybie 1 (16-bitowy) anl TMOD, #0F0H ; iloczyn logiczny zawartosci rejestru TMOD ; i stalej 0F0H orl TMOD, #T0_TMOD ; suma logiczna zawartosci rejestru TMOD i stalej ; T0_TMOD ; zapisanie wartosci poczatkowej licznika call Timer0_Reload ; uruchomienie licznika setb TR0 ; nadanie wartosci 1 bitowi TR0 (TCON) ; przywrocenie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #CONFIG_PAGE W programie głównym testowany jest stan wskaźnika Ready. Zapalenie/zgaszenie diod następuje wtedy, gdy Ready ma wartość 1, po czym wskaźnik Ready jest zerowany. czeka: jnb Ready, czeka cpl A ; negacja zawartości akumulatora call zapis_led ; wywolanie procedury zapis_led clr Ready ; wyzerowanie flagi Ready jmp czeka 13

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -14- Zespół otrzymuje gotowy program, który cyklicznie zapala i gasi wszystkie diody LED jednocześnie. Zadanie do wykonania: Zmodyfikować program startowy tak, aby zapalona dioda "przesuwała" się podobnie jak w pierwszej części ćwiczenia. Program realizujący zadanie z odmierzaniem opóźnienia przy pomocy wewnętrznego licznika T0 i wykorzystaniem systemu przerwań do obsługi tego licznika (C:\TM_LAB\8051\ przyklady\diodki_int.a51) $NOMOD51 #include <C8051F060.INC> ; DEFINICJE SYMBOLI aktywacja_backlight equ P5.3 ; obsluga podswietlenia LCD LEDs equ P2.5 ; aktywacja diod LED CK_D equ P5.6 ; obsluga bufora sterujacego diodami LED TOS equ 30H ; wierzcholek stosu zapal_wszystko equ 0FFH ; zapalenie wszystkich diod ready bit 0 ; definicja flagi (20H.0) T0_TMOD equ 1H ; konfiguracja licznika T0 w trybie 1 (16-bitowy) T0_Reload equ 65536 1000 ; wartość poczatkowa licznika T0 Del equ 7FH ; zliczanie przerwan DelReload equ 100 ; liczba przerwan do zliczenia ; Umieszczenie poczatku programu pod adresem 0000H cseg AT 0000h jmp Poczatek ; skok do faktycznego poczatku programu ; Umieszczenie poczatku procedury obslugi przerwania licznika T0 pod adresem 0000BH org 000BH jmp Timer0_Int ; skok do faktycznego poczatku procedury obslugi ; przerwania licznika T0 ; konfiguracja mikrokontrolera Poczatek: mov WDTCN, #0DEh; wylaczenie watchdoga mov WDTCN, #0ADh; wylaczenie watchdoga mov SFRPAGE, #CONFIG_PAGE ;wlaczenie odpowiedniej ; konfiguracji SFR-ow mov XBR2, #040h ; wlaczenie krosownicy ; PROGRAM GLOWNY ; inicjalizacja mov SP, #TOS ; inicjalizacja stosu 14

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -15- clr aktywacja_backlight ; wylaczenie podswietlania LCD clr LEDs ; uaktywnienie diod LED mov A, #zapal_wszystko ; zaladowanie samych jedynek do akumulatora mov Del, #DelReload ; zaladuj liczbe przerwan do odliczenia clr Ready ; wyzerowanie flagi Ready (UWAGA! definicja symbolu jakim ; nazywana jest flaga nie powoduje nadania jej wartosci) call Timer0_Init ; wywolanie procedury konfiguracji licznika T0 ; aktywacja systemu przerwan setb ET0 ; uaktywnienie przerwania licznika T0 setb EA ; globalne uaktywnienie systemu przerwan ;------------------------------------------------------------------------------------------------------ ; glowna petla programu ;------------------------------------------------------------------------------------------------------ miga: jnb Ready, miga ; jezeli flaga Ready=0, nie rob nic cpl A ; negacja akumulatora call zapis_led ; wywolanie procedury zapis_led clr Ready ; wyzerowanie flagi Ready jmp miga ; skok do etykiety czeka ;----------------------------------------------------------------------------------------------- ; PROCEDURY ;----------------------------------------------------------------------------------------------- zapis_led: ; wyslanie danych do diod LED mov P7, A nop ; no operation - opoznienie nop clr CK_D ; obsluga bufora sterujacego diodami LED nop ; no operation - opoznienie nop setb CK_D ;----------------------------------------------------------------------------------------------- Timer0_Init: ; wybranie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #TIMER01_PAGE ; skonfigurowanie licznika T0 w trybie 1 (16-bitowy) anl TMOD, #0F0H ; iloczyn logiczny zawartosci rejestru TMOD i stalej 0F0H orl TMOD, #T0_TMOD ; suma logiczna zawartosci rejestru TMOD i stalej ; T0_TMOD ; zapisanie wartosci poczatkowej licznika call Timer0_Reload ; uruchomienie licznika setb TR0 ; nadanie wartosci 1 bitowi TR0 (TCON) ; przywrocenie odpowiedniej strony rejestrow specjalnych mov SFRPAGE, #CONFIG_PAGE ;--------------------------------------------------------------------------------------------------- 15

IMiO PW, LPTM, Ćwiczenie 1, Wędrujące światełko -16- Timer0_Reload: ; zapisanie poczatkowej wartosci rejestrow licznika mov TH0, #High(T0_Reload) ; zapis starszego bajtu stalej T0_Reload ; w rejestrze TH0 mov TL0, #Low(T0_Reload) ; zapis mlodszego bajtu stalej T0_Reload ; w rejestrze TL0 ;--------------------------------------------------------------------------------------------------- ; procedura obslugi przerwania licznika T0 Timer0_Int: mov SFRPAGE, #TIMER01_PAGE ; wybierz strone rejestrow specjalnych ; umozliwiajaca obsluge licznika T0 call Timer0_Reload ; zaladuj wartosc poczatkowa do licznika T0 mov SFRPAGE, #CONFIG_PAGE ; wroc do wlasciwej strony rejestrow ; specjalnych djnz Del, Timer0_Int_Exit ; jezeli nie odliczono zadanej liczby przerwan ; wyjdz z procedury mov Del, #DelReload ; zaladuj liczbe przerwan do odliczenia setb Ready ; ustaw flage Ready Timer0_Int_Exit: i ; wroc z procedury obslugi przerwania ;--------------------------------------------------------------------------------------------------- end 16