ORG 0 ; Początek programu MOV TMOD, #01h ; Ustawienie Timera 0 w trybie 1 (16-bitowy) MOV TH0, #3Ch ; Ustawienie początkowego stanu dla przerwania co 0.5 Hz MOV TL0, #0B0h SETB TR0 ; Uruchomienie timera 0 SETB EA ; Włączenie globalnego przerwania SETB ET0 ; Włączenie przerwania dla Timera 0 MOV P1, #0 ; Inicjalizacja wyświetlacza na 0 MOV R0, #0 ; Rejestr R0 jako licznik ; --- Przerwanie Timera 0 --- ORG 0Bh TIMER0_ISR: JNB P3.0, COUNT_UP ; Jeśli przycisk 1 naciśnięty, licz w górę JNB P3.1, COUNT_DOWN ; Jeśli przycisk 2 naciśnięty, licz w dół JNB P3.2, STOP ; Jeśli przycisk 3 naciśnięty, zatrzymaj licznik SJMP EXIT_ISR COUNT_UP: INC R0 ; Zwiększ licznik CJNE R0, #10, DISPLAY MOV R0, #0 ; Reset przy 10 DISPLAY: MOV A, R0 ; Prześlij zawartość licznika na wyświetlacz MOV P1, A SJMP EXIT_ISR COUNT_DOWN: DEC R0 ; Zmniejsz licznik CJNE R0, #-1, DISPLAY_DOWN MOV R0, #10 ; Reset przy 0 DISPLAY_DOWN: MOV A, R0 MOV P1, A SJMP EXIT_ISR STOP: ; Bez zmian - zatrzymanie licznika SJMP EXIT_ISR EXIT_ISR: MOV TH0, #3Ch ; Reset Timera do wartości początkowej MOV TL0, #0B0h RETI ; Zakończenie przerwania Oto wyjaśnienie tych rejestrów i bitów sterujących, które są typowe dla mikrokontrolerów z rodziny 8051: 1. TMOD (Timer Mode Control) – rejestr trybu pracy timerów: o Określa tryb działania dwóch timerów (Timer 0 i Timer 1) w mikrokontrolerze. o Każdy timer może działać w kilku trybach (0, 1, 2, 3), np. w trybie 1 (16-bitowy licznik). o Wartość 01h dla TMOD oznacza, że Timer 0 działa w trybie 1, czyli jako 16-bitowy licznik. 2. TH0 (Timer High Byte for Timer 0) – starszy bajt licznika dla Timera 0: o Timer 0 składa się z dwóch bajtów: TH0 i TL0. o TH0 przechowuje górne 8 bitów wartości licznika, który jest używany do generowania opóźnień lub przerwań. o Wartość ta jest ładowana przy starcie timera lub przy każdym przerwaniu, aby ustawić interwał czasowy. 3. TL0 (Timer Low Byte for Timer 0) – młodszy bajt licznika dla Timera 0: o TL0 przechowuje dolne 8 bitów licznika. o Timer 0 jest 16-bitowym licznikiem, a więc TH0 i TL0 współpracują, by uzyskać pełen 16-bitowy licznik. 4. TR0 (Timer Run Control for Timer 0) – bit sterujący włączeniem Timera 0: o Jest to bit kontrolujący start timera; ustawienie TR0 = 1 uruchamia Timer 0. o Zerowanie tego bitu (TR0 = 0) zatrzymuje Timer 0. 5. EA (Enable All Interrupts) – globalne włączenie przerwań: o Jest to bit kontrolujący globalne włączenie przerwań w systemie. o Ustawienie EA = 1 włącza przerwania, natomiast EA = 0 wyłącza wszystkie przerwania. 6. ET0 (Enable Timer 0 Interrupt) – włączenie przerwań od Timera 0: o Jest to bit, który włącza lub wyłącza przerwania związane z Timerem 0. o Gdy ET0 = 1, przerwania od Timera 0 są włączone. • MOV – instrukcja kopiowania wartości: • MOV A, R0 – kopiuje wartość z rejestru R0 do akumulatora (rejestru A). • MOV P1, A – kopiuje wartość z akumulatora (A) do portu P1, co może np. wyświetlać wartość na wyświetlaczu lub ustawiać sygnały wyjściowe. • MOV TMOD, #01h – ustawia tryb pracy timerów. # oznacza liczbę bezpośrednią, tutaj 01h oznacza, że Timer 0 pracuje w trybie 1 (16-bitowy licznik). • MOV TH0, #3Ch i MOV TL0, #0B0h – zapisują wartości 3C i B0 do górnego i dolnego bajtu Timera 0, co ustawia czas trwania przerwania (interwał). • SETB – ustawienie bitu na wartość 1: • SETB TR0 – ustawia bit TR0 na 1, co uruchamia Timer 0. • SETB EA – ustawia bit globalny EA na 1, co włącza wszystkie przerwania. • SETB ET0 – ustawia bit ET0 na 1, co włącza przerwania od Timera 0. • JNB – skok, jeśli bit jest wyzerowany: • JNB P3.0, COUNT_UP – sprawdza bit na porcie P3.0 (stan przycisku 1); jeśli jest 0 (przycisk wciśnięty), wykonuje skok do etykiety COUNT_UP. • JNB P3.1, COUNT_DOWN – podobnie, sprawdza P3.1 (przycisk 2) i skacze do COUNT_DOWN, jeśli przycisk jest wciśnięty. • JNB P3.2, STOP – sprawdza P3.2 (przycisk 3) i skacze do STOP, jeśli przycisk jest wciśnięty. • SJMP – skok krótkodystansowy: • SJMP EXIT_ISR – wykonuje skok do etykiety EXIT_ISR, co jest prostą metodą na szybkie przejście do innej części kodu w obrębie 256 bajtów. • SJMP DISPLAY – wykonuje skok do etykiety DISPLAY, gdzie liczba z licznika jest przesyłana na wyświetlacz. • INC – inkrementacja (zwiększenie wartości o 1): • INC R0 – zwiększa wartość w rejestrze R0 o 1. Jest to licznik zliczający od 0 do 10 w górę. • DEC – dekrementacja (zmniejszenie wartości o 1): • DEC R0 – zmniejsza wartość w rejestrze R0 o 1. Wykorzystywane do liczenia od 10 do 0 w dół. • CJNE (Compare and Jump if Not Equal) – porównanie i skok, jeśli wartości są różne: • CJNE R0, #10, DISPLAY – porównuje wartość w R0 z 10. Jeśli R0 jest różne od 10, wykonuje skok do etykiety DISPLAY. Jeśli równe, przechodzi do kolejnej instrukcji. • CJNE R0, #-1, DISPLAY_DOWN – podobnie, porównuje R0 z -1. Jeśli różne od -1, skacze do DISPLAY_DOWN. • RETI – zakończenie przerwania (Return from Interrupt): • RETI – kończy obsługę przerwania i wraca do głównego programu, pozwalając na dalsze wywołania przerwań.