Ćwiczenia 06 - Elementy programowania w assemblerze, architektura 8051. 1. Wprowadzenie do oprogramowania MCU 8051 IDE W ramach ćwiczeń wykorzystamy środowisko MCU 8051 IDE, które jest dostępne do pobrania na stronie domowej 1. Rys.1. Logo środowiska MCU 8051 IDE. Tworzenie projektu w programie MCU8051 jest możliwe z poziomu interfejsu graficznego. Po instalacji2 i uruchomieniu środowiska MCU 8051 IDE należy stworzyć nowy projekt. Rys.2. Tworzenie nowego projektu. 1 Strona domowa projektu MCU 8051 IDE: http://www.moravia-microsystems.com/mcu-8051-ide/ (Stan z dnia 12-11-2014) 2 Przy instalacji wymagane są prawa administratora, jednakże możliwe jest stworzenie wersji portable przy pomocy odpowiedniego oprogramowania. 1 Następnie pojawia się okno z konfiguracją procesora, którego będziemy programować. Dla przykładu możemy nazwać projekt NowyProjekt, podać wybraną ścieżkę do folderu w którym mają zostać stworzone pliki projektu. Następnie możemy wybrać procesor np. o architekturze 8051. Dostępne są także inne architektury dla zainteresowanych. Ewentualnie możliwe dodatkowych zasobów. jest dodanie Rys.3. Okno tworzenia nowego projektu. Projekty są przechowywane w pliku przy wykorzystaniu języka XML o rozszerzeniu *.mcu8051ide . Pliki są kodowane w UTF-8, natomiast jak EOL (End of Line) używa się LF (Line Feed)3. Rys.4. Zbiorcze zestawienie okienek funkcyjnych w MCU 8051 IDE. źródło: Home Page MCU IDE 3 EOL Wiki, link: http://pl.wikipedia.org/wiki/Koniec_linii (Stan z dnia 14-01-2015) 2 Po zatwierdzeniu nasz nowy projekt jest już otwarty w środowisku, a także plik o rozszerzeniu *.asm w którym Projekt jest pusty domyślnie, więc możemy rozpocząć kodowanie programu za pomocą rozkazów. Przykład Pusty program z pętlą. Aby utworzyć pusty program z pętlą, należy wprowadzić poniższą instrukcję: 1 2 3 4 5 LJMP GO GO: ; instrukcje HALT: LJMP HALT Działanie programu rozpoczyna się od wykonania instrukcji skoku. Skok polega na przeskoczeniu w programie do miejsca o danej etykiecie (w tym przypadku jest to nazwa GO). Następnie program zapętla się w nieskończoność, ze względu na to, że ciągle przeskakuje do linii z rozkazem skoku do etykiety HALT. Rys.4. Widok projektu. Instrukcje które są poprzedzone znakiem ; to komentarze. Ogólnie bardzo na miejscu jest zachowanie następującego porządku w kodzie: ETYKIETA: NAZWA_ROZKAZU ARG1 ARG2 ;komentarz Dla wygody etykiety pisze się w osobnych liniach, choć nie jest to żadna zasada. 3 Aby uruchomić program, wybieramy Simulator>Start/Shutdown, lub używamy skrótu klawiszowego F2. Rys.5. Uruchamianie projektu. Możemy również skorzystać z panelu w dolnej części okna. Ikona Rakiety uruchamia symulację działania programu. Działanie natomiast możemy zobaczyć w sposób ciągły, wybierając animację, lub w sposób krokowy, uruchamiając każdy kolejny cykl na kliknięcie przycisku kroku. Do podstawowych funkcji oprogramowania MCU 8051 IDE, oprócz kompilowania programów napisanych w assemblerze lub języku C, możemy zaliczyć przede wszystkim wygodny edytor kodów, który poprzez funkcje auto uzupełniania i kolorowanie składni wspomaga pisanie kodu i poprawia jego przejrzystość. Ponadto dostępny jest szeroki wachlarz dodatków, m.in. symulatora, dzięki czemu możemy wygodnie podglądać wartości adresów i flag podczas prowadzenia symulacji wykonania programu, w systemach liczbowych binarnym, ósemkowym, dziesiętnym i szesnastkowym. Rys.6. Symulator. 2. Arytmetyka liczb W ramach ćwiczeń zostaną wykorzystane rozkazy: ADD, MOV, MUL, SUBB, INC, DEC, DIV, z którymi należy się zapoznać. Rejestry R0,R1...są 8 bitowe, przyjmują wartości od 0 do 255 – nie większe. Wprowadzenie większej wartości powoduje błąd. Przykłady: a) Inkrementuje wartość 1 do 2 i znowu itd. b) Ustawia 1 i póxniej liczy po kolei co 1. a) LJMP GO GO: mov R1, #01d INC R1 LJMP GO b) LJMP GO mov R1, #01d GO: INC R1 LJMP GO Zad.1. Umieść w pamięci liczby, a następnie dodaj podane liczby. Wynik zapisz w R0: 4 a) 14+6 b) 26+17 LJMP GO GO: mov R1, #26d mov R2, #17d mov A, R1 ADD A, R2 HALT: LJMP HALT c) 31+47 d) 240+34 Rozwiązanie przykładowe Zad.1. a). Umieszczamy liczby 14 i 6 w komórkach pamięci R1 i R2: MOV MOV R1,#14d R2,#6d Zwróćmy uwagę, że wprowadziliśmy liczby w postaci dziesiętnej, dzięki literce d na końcu. Innym sposobem jest wprowadzenie w postaci binarnej #1110b lub szesnastkowej #0Eh. W pamięci domyślnie mamy podgląd na dwubitowy szesnastkowy zapis. Przy szesnastkowym formacie należy także pamiętać, aby nie rozpoczynać liczby od symbolu litery (tj. nie wprowadzać #E). Następnie przenosimy jedną z liczb do akumulatora podstawowego, a następnie wydajemy rozkaz dodawania: MOV ADD A,R1 A,R2 wynik jest przechowywany w akumulatorze. W pierwszej instrukcji możemy także podać adres komórki pamięci #01h zamiast etykiety R1. W przypadku większych liczb, jeżeli dodane liczby przekroczą zakres 8 bitów binarnych, przepełnienie jest przenoszone do akumulatora pomocniczego, oraz zostaje zapalona flaga OV (Overflow). Po czym wykonujemy rozkaz dodawania i zapisujemy liczbę wynikową w komórce R0 adresu pamięci: MOV A,01h 5 Zad.2 Mnożenie liczb. Dane umieść w pamięci w komórkach R4 i R5, natomiast wynik zapisz pod adresem R7. Co się stanie, jeżeli wynik nie mieści się w akumulatorze? a) 7*9 b) 10*21 c) 21*31 d) 27*41 e)24*34 z wykroczeniem wyniku poza zakres 18h *22h Zad.3. Odejmowanie liczb. Wykonaj poniższe działania: a) 30-4 b) 10-14 c) 81-26 d) 250-77 Zad.4. Operacje inkrementacji i dekrementacji. a) Zapisz do akumulatora liczbę 250, a następnie pomniejsz ją dwukrotnie. b) Zapisz do głównego akumulatora liczbę 3, a do drugiego liczbę 11, a następnie powiększ o dwa każdą z nich. 6 Zad.5. Wykonaj dzielenie liczb: a) 12/3 b) 32/8 c) 31/2, Gdzie są zapisane informacje o całościach a gdzie o resztach? – wynik w akumulatorze, reszta wB Zad.6. Wykonaj poniższe działania wykorzystując jak najmniejszą liczbę rejestrów. Przed operacjami zapisz dane w pamięci. a) (41+3)/2 + 21*3 – 3 =82 LJMp GO GO: MOV R0, #41d MOV R1,#3d MOV R2, #21d MOV A,R0 ADD A,R1 Mov b,#2d Div Ab Mov R0,A Mov A,r2 Mov b,r1 Mul ab ADD A,r0 Subb A,R1 HALT: LJMP HALT b) (21 - 11)/5 - ( 32/8 - 2) c) 31*3 + 170/5 - 3*(50 - 43) d) (55 - 15 + 10)*3 - 5*(27 - 2) 3. Wykorzystanie Virtual Hardware Środowisko MCU 8051 IDE udostępnia szereg elementów dodatkowych, które możemy wykorzystać, takich jak: panel LED, wyświetlacz siedmiosegmentowy czy multiplekser LED i nie tylko. 7 Rys.7. Panel LED podłączony do portu P0. Rys.8. Wyświetlacz siedmiosegmentowy podłączony do porty P3. Rys.9. Wyświetlacz macierzowy LED z podłączoną jedną diodą do pierwszego bitu portu P3. Zad.1. Napisz program, który zapali jedna diodę na wybranym panelu ledowym. Pamiętaj o podłączeniu diody do wybranej linii wybranego portu. Wykorzystaj rozkaz CPL negujący wartość odpowiedniego bitu. Zad.2. Napisz program, który na Panelu LED (panel z ośmioma diodami led) będzie zapalał kolejne diody od lewej do prawej. Pamiętaj o podłączeniu diod do odpowiednich portów. Należy zapętlić rozwiązanie. Zad.3. Napisz program, który zapali pierwszą diodę na panelu led i będzie tj. przesuwał zapaloną diodę na kolejne miejsce. Gdy zapali się ostatnia dioda, to kolejna, która zapali się po niej będzie diodą pierwszą. Zad.4. Napisz program, który będzie wyświetlał inne ciekawe układy na panelu led. Zad.5. Napisz program wyświetlający na cyfrowym panelu led (LED Display) liczbę 5. Wykorzystaj rozkaz MOV. 8 Zad.6. Napisz program wyświetlający kolejno cyfry 0,1,2,3,...,9,0,1,2,..... 4. Pseudo instrukcje, banki pamięci, STOST Pseudo instrukcje - instrukcje własne assemblera Dyrektywy: EQU, ORG, DB ORG - pozwala na określenie w od którego miejsca w pamięci będą lokowane instrukcje programu , np. ORG 100H spowoduje iż od tej pory instrukcje będą zapisywane od miejsca adresu 100H. Jednakże umieszczanie tego na samym początku nie jest dobrym pomysłem, gdyż podczas wykonywania programu nie będą widoczne instrukcje, należy wykonać skok do miejsca instrukcji. Dla przykładu możemy zmodyfikować program z Zad.1.a), którego instrukcje są umieszczone od adresu 100h: ORG LJMP ORG LJMP 0H START 100H START MOV MOV MOV ADD MOV R1,#14d R2,#6d A,R1 A,R2 R0,A LJMP HALT START: HALT: EQU - instrukcja pozwala na przypisywanie pewnym etykietom określonego adresu pamięci np. D7BM EQU 7FH spowoduje przypisanie etykiety do pamięci 7FH. Od tej pory możemy odwoływać się do etykiety D7BM zamiast do konkretnego adresu pamięci. DB - pozwala na przypisanie zbioru wartości w pamięci programu. Banki rejestrów W architekturze 8051 mamy dostępne cztery banki pamięci. Dostęp jest ustawiany przez bity RS0 i RS1: RS1 0 RS0 0 Rejestr 0 Adres 0x00 - 0x07 9 0 1 1 1 0 1 1 2 3 0x08 - 0x0F 0x10 - 0x17 0x18 - 0x1F Obsługa struktury danych - STOS Stos udostępnia operacje: PUSH - przekazywanie wartości na stos POP - zdejmowanie wartości ze stosu (dla zaoszczędzenia cykli, wartość w pamięci zostaje, ale stos jej nie pamięta) MOV MOV PUSH PUSH POP POP P0,#0FH P1,#0EH P0 P1 A B ;umieść pod P0 wartość 0FH ;umieść pod P1 wartość 0EH ;umieść na stosie wartość portu P0 ;umieść na stosie wartość portu P1 ;zdejmij ze stosu wartość i zapisz pod A ;zdejmij ze stosu wartość i zapisz pod B Zad.1.* Wykorzystaj stos do wyznaczenia wartości wyrażenia ONP. a) 100 50 - 10 / 25 10 % 2 + 4 * + b) 22 5 / 23 6 % 5 * + 10 5 3 - / c)5 4 + 3 * 13 5 % 7 3 / * + 13 - 10