1. Cel lekcji i co dziś zrobimy
To jest Twoje pierwsze praktyczne ćwiczenie w asemblerze 8051: zapalanie diody LED. Brzmi prosto, ale w tej jednej czynności kryją się absolutne podstawy pracy z mikrokontrolerem: porty I/O, zapis do rejestrów SFR, adresowanie bitów i pętla programu.
- nauczysz się, jak ustawić stan pinu portu (np. P1.0),
- zrozumiesz różnicę między zapisem bitowym i bajtowym,
- poznasz instrukcje: MOV, SETB, CLR, SJMP,
- zrobisz mini-powtórkę z systemu szesnastkowego i zapisu liczb.
2. Szybka powtórka: system binarny i szesnastkowy
Mikrokontroler jest 8-bitowy – większość danych to bajty (8 bitów). Porty P0–P3 też są 8-bitowe, czyli jeden port to 8 linii: np. P1.0…P1.7.
2.1. Jak czytać zapis szesnastkowy?
Zapis hex (szesnastkowy) rozpoznasz po literze h na końcu (w asemblerze 8051). Przykłady:
| Binarnie (8 bitów) | Hex | Dziesiętnie | Znaczenie dla portu |
|---|---|---|---|
| 0000 0000 | 00h | 0 | wszystkie piny = 0 |
| 1111 1111 | 0FFh | 255 | wszystkie piny = 1 |
| 0000 0001 | 01h | 1 | tylko bit 0 = 1 (np. P1.0) |
| 1000 0000 | 80h | 128 | tylko bit 7 = 1 (np. P1.7) |
| 0001 0000 | 10h | 16 | tylko bit 4 = 1 (np. P1.4) |
2.2. „Bit” kontra „bajt”
- Bitowo: sterujesz jednym pinem, np. SETB P1.0 (ustaw 1 na P1.0).
- Bajtowo: ustawiasz cały port naraz, np. MOV P1, #0FFh (ustaw 1 na wszystkich pinach P1).
3. Jak jest podłączona dioda w EdSim51?
W EdSim51 masz gotowe diody LED podłączone do portu (zwykle do P1). W zależności od symulatora/ustawień, LED może być „aktywna stanem niskim” (świeci dla 0) albo „aktywna stanem wysokim” (świeci dla 1).
1.png (zrzut/pogląd panelu LED i informacji, do którego portu są podłączone).
4. Program 1: Zapal jedną diodę (P1.0)
Najprostszy możliwy program w asemblerze 8051 robi dwie rzeczy:
- ustawia stan pinu (np. P1.0),
- zatrzymuje się w pętli nieskończonej, żeby efekt był widoczny.
4.1. Kod (wersja startowa)
; ========================================= ; Lekcja 3 – Program 1: LED ON na P1.0 ; ========================================= ORG 0000h ; początek programu (wektor resetu) ; 1) Ustaw pin P1.0 w stan 0 (LED ON – połączenie katodą do pinu, active-low) CLR P1.0 ; 2) Pętla nieskończona – program „stoi” LOOP: SJMP LOOP END
4.2. Co oznaczają te linie?
- ORG 0000h – mówimy asemblerowi: „wstaw kod od adresu 0000h” (tam startuje CPU po resecie).
- CLR P1.0 – ustaw bit P1.0 = 0 (LED ON przy połączeniu katodą do pinu).
- SJMP LOOP – skok krótki do etykiety LOOP (pętla nieskończona).
- END – koniec pliku dla asemblera.
5. Program 2: Zgaś diodę (P1.0)
Analogicznie możemy wymusić stan wysoki na pinie (LED zgaśnie przy logice active-low):
; Program 2: LED OFF na P1.0 ORG 0000h SETB P1.0 ; ustaw bit P1.0 = 1 (LED OFF przy aktywacji stanem niskim) HERE: SJMP HERE END
6. Program 3: Ustaw cały port naraz (P1 = FFh / 00h)
Zestawienie pokazuje, które piny portów P0–P3 są przypisane do LED, klawiatury, przełączników, ADC, DAC i pozostałych elementów symulatora.
Czasem zamiast sterować pojedynczym bitem, wygodniej jest ustawić cały port. Wtedy używasz MOV z wartością natychmiastową (#).
; Program 3: Wszystkie LED ON/OFF (na całym porcie P1) ORG 0000h MOV P1, #00h ; LED ON: ustaw wszystkie bity portu P1 na 0 (aktywne 0) ; MOV P1, #0FFh ; LED OFF: ustaw wszystkie bity na 1 STOP: SJMP STOP END
6.1. Co oznacza znak # ?
W asemblerze 8051 znak # oznacza: „to jest wartość, a nie adres”. Czyli MOV P1, #0FFh to dosłownie „wpisz liczbę FFh do rejestru portu P1”.
7. Program 4: Miganie LED (pętla + opóźnienie)
Teraz zrobimy klasykę: LED ma migać. Do tego potrzebujemy:
- zmiany stanu pinu (SETB/CLR),
- opóźnienia programowego (prosta pętla zliczająca),
- pętli głównej (powtarzanie).
; ========================================= ; Program 4: Miganie LED na P1.0 ; ========================================= ORG 0000h MAIN: CLR P1.0 ; LED ON (aktywne 0) ACALL DELAY SETB P1.0 ; LED OFF ACALL DELAY SJMP MAIN ; ----------------------------------------- ; Proste opóźnienie: pętla zliczająca ; Używamy rejestru R7 jako licznika. ; ----------------------------------------- DELAY: MOV R7, #200 ; wartość startowa (możesz zmieniać) D1: DJNZ R7, D1 ; dekrementuj i skacz, dopóki R7 != 0 RET END
7.1. Jak działa DJNZ?
Instrukcja DJNZ (Decrement and Jump if Not Zero):
- zmniejsza rejestr o 1,
- jeśli wynik nie jest równy 0 – skacze do etykiety,
- jeśli wynik = 0 – idzie dalej (tu: wykonuje RET).
8. EdSim51 krok po kroku: jak to uruchomić?
- Otwórz EdSim51 i przejdź do edytora kodu (asm).
- Wklej program (np. „Program 4: Miganie LED”).
- Złóż kod (Assemble) – jeśli są błędy, popraw literówki w etykietach lub dyrektywach.
- Uruchom (Run) albo wykonuj krokowo (Step), obserwując P1 i diody LED.
- Jeśli dioda działa „odwrotnie” (inne podłączenie), zamień SETB i CLR.
9. Najczęstsze błędy (i szybkie naprawy)
- LED nie świeci: sprawdź, czy sterujesz właściwym portem (P1 vs P2), i czy logika nie jest odwrócona.
- Program „nic nie robi”: upewnij się, że masz pętlę (np. SJMP MAIN) – w mikrokontrolerach program nie kończy się jak w C++.
- Błąd asemblera: sprawdź etykiety (muszą być spójne) i czy masz ORG 0000h oraz END.
- Miganie za szybkie/za wolne: zmień wartość w MOV R7, #200 (większa = wolniej).
10. Zadania dla ucznia (na ocenę lub do ćwiczeń)
-
Zmień program tak, aby świeciła dioda P1.3 zamiast P1.0.
Pamiętaj: LED jest active-low, więc „zapal” = ustaw 0 (CLR). -
Ustaw cały port P1 na 0AAh (czyli 1010 1010) i sprawdź, które LED się świecą.
Wypisz, które bity mają 0 – to one zapalają LED przy katodzie do pinu. -
Zrób miganie, ale z inną proporcją: LED ma świecić długo, a gasnąć krótko (np. 3× dłużej ON niż OFF).
ON = stan 0 na pinie, OFF = stan 1 na pinie. -
(Dla chętnych) Zrób „przesuwające się światło”: zapal kolejno P1.0, P1.1, P1.2… P1.7.
W danej chwili tylko jeden bit ma być 0 (żeby świeciła tylko jedna LED).