logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Przerwania 89c2051 .asm. Pytania dot. obsługi przerwań.

ekspert100 31 Lip 2006 13:02 2809 15
  • #1 2866501
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    Przerwania 89c2051 .asm

    Witam !!!
    pytanie dotyczy w zasadzie obsługi przerwań programu w .asm

    Program oparty na
    od T0 pomiar czasu-(timer)
    od T1 wyświetlanie wyniku wyświetlacz led7seg
    sekwencyjnie na port p1

    moje pytanie to:
    - czy po zgłoszeniu każdego z tych
    przerwań mam zapisywać na stos psw;acc;cy
    - czy przy zakończeniu każdego z tych
    przerwań stosować instrukcję reti
    - jak powinen wyglądać rejestr ip
    - oraz fizycznie w jakiej kolejności umieścić
    - podprogramy obsługi przerwań oraz program główny


    a pomiar ma być wykonywany przy zgłoszeniu przerwania t0

    prosze o opinie i uwagi, pozdrawiam....
  • Pomocny post
    #2 2866674
    Dyrek
    Poziom 16  
    Posty: 129
    Pomógł: 21
    Ocena: 1
    Zachowanie psw i acc przy wejściu do przerwania i odzyskanie przy wyjściu jest prawie zawsze konieczne, napewno gdy używasz ich w przerwaniach.

    Instrukcje reti zawsze się stosuje na końcu przerwania inaczej z niego nie wyjdzie (na stosie pozostanie adres powrotny i za którymś razem procek "pójdzie w maliny" ).

    Rejestru Ip chyba nie trzeba zmieniać chyba ze zależy Ci na kolejności wywoływania przerwań od liczników (to zależy co one robią)

    A kolejność podprogramów przerwań i programu głównego w sumie jest dowolna, ja zazwyczaj podprogramy umieszczam na początku.

    pozdrawiam
  • #3 2866979
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    Jeszcze jedna niejasność
    załóżmy ze program startuje od adresu
    000h
    wykonuje program
    na końcu jest wpisane
    end
    czy napotykając na intrukcję end powraca na sam początek
    do adresu 000h

    A ret jest instrukcją błędną na końcu przerwania
    bo widzałem coś takiego że dla jednego przerwania było reti
    a dla drugiego przerwania ret .

    pozdrawiam!!!
  • Pomocny post
    #4 2867419
    Dyrek
    Poziom 16  
    Posty: 129
    Pomógł: 21
    Ocena: 1
    END jest tylko znacznikiem dla kompilatora i nie powoduje skoku na początek programu, musisz to zrobic za pomocą rozkazu SJMP, AJMP lub LJMP w zależności jak długi masz program.
    A co do instrukcji RETI i RET nie jestem pewien ale chyba chodzi o priorytety - jeśli zakończysz jedno przerwanie o wyższym priorytecie instrukcją RET to przerwanie o niższym priorytecie się nie wywoła bo procek stwierdzi że wyższe przerwanie się jeszcze nie zakończyło. Może się mylę, no ale bez powodu konstruktorzy by nie rozgraniczali tego, w końcu chyba nie jest ciężko dostawic I :)

    A jeden z lepszych opisów rozkazów 8051 był w EDW http://www.edw.com.pl/index.php?module=ContentExpress&file=index&func=display&ceid=68&meid=20
    nie pamiętam ale może tam gdzieś pisali jaka jest różnica między RETI a RET

    pozdro.
  • #5 2867618
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    Najczęściej spotkałem się z tym w przerwaniu t1
    gdy program dokonywał obsługi wyświetlacza
    wtedy była instrukcja ret.
  • Pomocny post
    #6 2867951
    tprzemko
    Poziom 22  
    Posty: 413
    Pomógł: 54
    Ocena: 21
    Witam
    Proponuję jednak zapoznać się z kursem asemblera z EdW. Wyjdzie to na zdrowie. Instrukcja RET jest do powrotu z podprogramu do którego skaczemy LCALL, ACALL. NAtomiast z przerwania zawsze wychodzimy przez RETI. W obsługę przerwania wchodzimy zupełnie inaczej. Jak wystąpi warunek przerwania to procek automatycznie odkłada na stos adres powrotu (to miejsce w którym teraz jest) i skacze pod adres który ma podany w tablicy wektórów. I tyle. Po RETI zdejmuje ze stosu adres powrotu i wykonuje dalej przerwany program. Co do odkładania na stos wskaźników, rejestrów itp zależy od tego co chcesz zachować i z jakich zasobów korzystasz w przerwaniu.
    Pozdrawiam
  • Pomocny post
    #7 2869128
    Zaquadnik
    Poziom 27  
    Posty: 998
    Pomógł: 103
    Ocena: 25
    O ile pamiętam, właśnie wejście w procedurę obsługi przerwania spowoduje odłożenie na stos PC oraz PSW. Instrukcja reti zdejmie je ze stosu. Natomiast instrukcja ret zdejmuje tylko PC. O ACC musisz w każdym wypadku zatroszczyć się sam.
    Pozdrawiam :)
  • Pomocny post
    #8 2869338
    jj
    Poziom 19  
    Posty: 145
    Pomógł: 42
    Zaquadnik napisał:
    O ile pamiętam, właśnie wejście w procedurę obsługi przerwania spowoduje odłożenie na stos PC oraz PSW. Instrukcja reti zdejmie je ze stosu. Natomiast instrukcja ret zdejmuje tylko PC. O ACC musisz w każdym wypadku zatroszczyć się sam.
    Pozdrawiam :)


    Wejście w procedurę obsługi przerwania nie powoduje odłożena na stos rejestru PSW.

    Poniżej opis rozkazów RETI i RET zaczerpnięty z dokumentacji Atmela.

    Cytat:
    RETI
    Function:
    Return from interrupt
    Description:
    RETI pops the high- and low-order bytes of the PC successively from the stack and restores the interrupt logic to accept additional interrupts at the same priority level as the one just processed. The Stack Pointer is left decremented by two. No other registers are affected; the PSW is not automatically restored to its pre-interrupt status. Program execution continues at the resulting address, which is generally the instruction immediately after the point at which the interrupt request was detected. If a lower- or same-level interrupt was pending when the RETI instruction is executed, that one instruction is executed before the pending interrupt is processed.

    Cytat:
    RET
    Function:
    Return from subroutine
    Description:
    RET pops the high- and low-order bytes of the PC successively from the stack, decrementing the Stack Pointer by two. Program execution continues at the resulting address, generally the instruction immediately following an ACALL or LCALL. No flags are affected.


    Instrukcja RETI przywraca stan systemu przerwań jaki był przed wejściem w procedurę obsługi przerwania. Czyli zezwala na obsługę przerwań o tym samym priorytecie jak to które kończy.

    Pozdrawiam,
    Jacek
  • #9 2872998
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    $mod51 ;istotne dla kompilatora asm51 @@@@@

    ;przerwania t0 i t1

    pre0 equ 30h ; deklaracje komórek zmienne "set"
    pre1 equ 31h ; deklaracje komórek zmienne "des"
    prex equ 32h ; deklaracje komórek zmienne "jed"

    ax equ 40h ; deklaracje komórek zmienne 7seg "jed"
    xx equ 42h ; deklaracje komórek zmienne 7seg "des"
    yy equ 44h ; deklaracje komórek zmienne 7seg "set"


    sek equ 50h ; deklaracje komórek zmienne "sek"
    ms equ 52h ; deklaracje komórek zmienne "10ms"

    ;--------------------------------------------------------

    org 0000h ;początek wykonywania programu
    sjmp init ; skocz do początku programu głównego

    ;org 03h

    org 000bh
    sjmp time0


    org 001bh
    sjmp time1

    init:

    mov th0,#0feh ; zaladowanie licznika th
    mov tl0,#0bfh ; zaladowanie licznika tl

    mov th1,#0feh ; zaladowanie licznika th
    mov tl1,#0afh ; zaladowanie licznika tl

    mov tcon,#01010000b ; ustawienie timerów t0
    mov tmod,#00010001b ; timer 0 i t1 w tryb 2(16 bit) czasomierz m0 ,m1


    mov ie,#10001010b ; uaktywniamy przerwanie ea + et0,et1 od t0,t1

    setb et0 ;uaktywnienie przerwania z t0
    setb et1 ;uaktywnienie przerwania z t1
    setb ea ;globalne odblokowanie przerwań

    sjmp start ; skocz do początku programu głównego



    ;--------------------------------------------------------g
    start: ;właściwy początek pętli głównej programu



    inc prex ;+1
    mov a,prex
    mov p1,a ; przepisz zmienna na port p1

    cpl p3.7 ; neguj także port p3.7
    ;mov p1,a ; przepisz zmienna na port p1

    nop
    nop
    nop

    sjmp start ;petla


    time0: ; set konfiguracja t0 ---------------------------------#

    mov tmod,#00010001b ; timer 0 w tryb 2 ( 16 bit ) jako czasomierz m0
    ;mov tcon,#00000000b ; ustawienie timerów it0 -\__

    mov th0,#0feh ; zaladowanie licznika th
    mov tl0,#0bfh ; zaladowanie licznika tl
    push psw ;psw na stos
    push acc ;acc na stos


    setb et0 ;uaktywnienie przerwania z t0
    setb ea ;globalne odblokowanie przerwań
    setb tr0 ;start t0

    inc pre0 ;+1

    nop
    nop
    nop

    pop acc
    pop psw

    reti



    time1: ; set konfiguracja t1 ---------------------------------#

    mov tmod,#00010001b ; timer 0 i 1 w tryb 2 ( 16 bit )czasomierz m0
    ;mov tcon,#00000000b ; ustawienie timerów

    mov th1,#0feh ; zaladowanie licznika th
    mov tl1,#0afh ; zaladowanie licznika tl
    push psw ;psw na stos
    push acc ;acc na stos


    setb et1 ;uaktywnienie przerwania z t1
    setb ea ;globalne odblokowanie przerwań
    setb tr1 ;start t1

    inc pre1 ;+1

    nop
    nop
    nop

    pop acc
    pop psw


    reti

    end ;koniec *******************************************************

    Witam !!!

    tyle mi sie udało napisać
    timery pracują niezależnie

    teraz potrzebuje jeszcze dodać:

    porównanie komórki sek i new - jak różne to konwersja
    konwersja bin/dec + zapis do komórek wartości dec
    obsługe wyświetlacza led7seg multiplex na p1 HC4543
    z pobraniem wartości dec z komórek

    ale nie zabardzo wiem gdzie te podprogramy umieścić

    prosze o pomoc

    Pozdrawiam!!!
  • Pomocny post
    #10 2873214
    Dyrek
    Poziom 16  
    Posty: 129
    Pomógł: 21
    Ocena: 1
    Witam,
    Dużo rozkazów jest niepotrzebnych: ustawioanie pojedynczo bitów a potem przez zapis całego rejestru (rejestr IE), nie powtarza się konfigurowania liczników w przerwaniach jeśli zostały skonfigórowane na początku, to samo z aktywacją przerwań, więc po okrojeniu:

    $mod51 ;istotne dla kompilatora asm51
    
    pre0	equ	10h	;deklaracje komórek zmienne "set" 
    pre1	equ	11h	;deklaracje komórek zmienne "des" 
    prex	equ	12h	;deklaracje komórek zmienne "jed" 
    
    ax	equ	13h	;deklaracje komórek zmienne 7seg "jed" 
    xx	equ	14h	;deklaracje komórek zmienne 7seg "des" 
    yy	equ	15h	;deklaracje komórek zmienne 7seg "set" 
    
    sek	equ	50h	;deklaracje komórek zmienne "sek" 
    ms	equ	52h	;deklaracje komórek zmienne "10ms" 
    
    ;-------------------------------------------------------- 
    	org	0h	;początek wykonywania programu 
    	sjmp	init	;skocz do ustawień początkowych
    	;org	03h
    ;----------------
    	org 000bh 
    	sjmp	time0 
    ;---------obsługa przerwania T1-------------
    ;nie ma innych przerwań za tym więc można je umieścić tu
    ;bez konieczności skoków
    	org	001bh
    	mov	th1,#0feh	;zaladowanie licznika th 
    	mov	tl1,#0afh	;zaladowanie licznika tl 
    
    	push	psw	;psw na stos 
    	push	acc	;acc na stos 
    
    	inc	pre1	;+1 
    
    	pop	acc 
    	pop	psw 
    	reti 
    
    ;------ustawienia początkowe-----------
    init:
    	clr	ea
    	clr	rs0		;\
    	clr	rs1		; bank 0 rejestrów 
    	mov	sp,#50h	;wskaźnik stosu poza deklaracje zmiennych
    	mov	th0,#0feh	;zaladowanie licznika th 
    	mov	tl0,#0bfh	;zaladowanie licznika tl 
    
    	mov	th1,#0feh	;zaladowanie licznika th 
    	mov	tl1,#0afh	;zaladowanie licznika tl 
    
    	mov	tmod,#00010001b	;timer 0 i t1 w tryb 1(16 bit) czasomierz m0 ,m1 
    	mov	tcon,#01010000b	;uruchomienie timerów t0, t1 
    	mov	ie,#10001010b	;uaktywnienie przerwań ea + et0,et1 od t0,t1 
    
    ;--------pętla główna------------
    start:
    
    	inc	prex
    ;	mov	a,prex	;nie potrzebne bo można mov p1,prex
    	mov	p1,prex
    	cpl	p3.7		;neguj także port p3.7 
    
    	sjmp	start
    
    ;--------obsługa przerwania T0------------
    time0:
    
    	mov	th0,#0feh	;zaladowanie licznika th 
    	mov	tl0,#0bfh	;zaladowanie licznika tl
    
    	push	psw
    	push	acc
    
    	inc pre0 ;+1 
    
    
    	pop	acc 
    	pop	psw 
    
    	reti
    ;-----------------
    end 



    Wyświetlanie umieść w przerwaniu od T0 a konwersje w T1 albo odwrotnie :D
  • Pomocny post
    #11 2875726
    tprzemko
    Poziom 22  
    Posty: 413
    Pomógł: 54
    Ocena: 21
    Witam
    Jakoś nie bardzo mogę zkumać co to ma robić. W przerwaniach od timerów inkrementujesz rejestry i tyle. Co do wyświetlaczy to na peweno musisz umieścić ich obsługę w przerwaniu. Natomiast porównanie możesz sobie w programie głównym robić. Napisz sobie podprogamy które będą realizować poszczególne funkcje. W programie głównym będziesz sobie skakał do kolejnych zadań.
    Pozdrawiam
  • #12 2881919
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    inkrenentacja rejestrów to na razie test
    mam już sprawdzony podprogram do obsługi wyąwietlacza
    i zastanawiam sie gdzie go umiescić aby program był w miarę
    uniwersalny
    w deklaracjach mała zmiana jeszcze:

    RB0R0 EQU 44H ; deklaracje komórek zmienne 7seg "jed"
    RB0R1 EQU 46H ; deklaracje komórek zmienne 7seg "des"
    RB0R2 EQU 48H ; deklaracje komórek zmienne 7seg "set"

    ;----------------------------------------------------end deklar

    WYSWART:
    ;-----------------------------------------------#
    ;Cyfry są w komórkach RB0R0, RB0R1, RB0R2,

    MOV P1 , RB0R0 ;1 JED
    CLR P1.2
    MOV B , #30
    DJNZ B , $
    SETB P1.2
    MOV P1 , RB0R1 ;2 DES
    CLR P1.1
    MOV B , #30
    DJNZ B , $
    SETB P1.1
    MOV P1 , RB0R2 ;3 SED
    CLR P1.0
    MOV B , #30
    DJNZ B , $
    SETB P1.0


    AJMP WYSWART

    KOD7:
    ANL A,#0FH ;tabela kodów 0..15
    INC A ;pomiń rozkaz RET
    MOVC A,@A+PC ;pobierz kod
    RET

    KOD7SEG: ;Zadeklarowana tablica z kodami dla 74HCT4543

    ;ORGANIZACJA PINÓW NA 89C2051
    ;P1.4-A ;PINY 0123=1 LOG
    ;P1.5-B
    ;P1.6-C
    ;P1.7-D


    ;ORG PIN P0. 76543210
    DB 00FH ;kod znaku 0 ;00001111;015
    DB 01FH ;kod znaku 1 ;00011111;031
    DB 02FH ;kod znaku 2 ;00101111;047
    DB 03FH ;kod znaku 3 ;00111111;063
    DB 04FH ;kod znaku 4 ;01001111;079
    DB 05FH ;kod znaku 5 ;01011111;095
    DB 06FH ;kod znaku 6 ;01101111;111
    DB 07FH ;kod znaku 7 ;01111111;127
    DB 08FH ;kod znaku 8 ;10001111;143
    DB 09FH ;kod znaku 9 ;10011111;159

    pozdrawiam!!!
  • Pomocny post
    #13 2887204
    tprzemko
    Poziom 22  
    Posty: 413
    Pomógł: 54
    Ocena: 21
    Witam
    To co nam napisałeś jest fajne jak procesor w wolnym czasie niczym innym się nie zajmuje tylko obsługą wyśnietlacza. Więc jeśli chcesz uruchomić wyswietlanie w przerwaniu to:
    1) zakładamy z jaką częstotliwością ma się to wyświetlać
    2) teraz liczba wyświetlaczy razy to co w pkt 1
    3) tak ustawić Timer coby przerwanie tyle i pkt 2
    i w każdym przerwaniu obsługujesz jeden wyswietlacz.
    np:

    int_timx:                      ;przerwanie od timera
            inc        wyswietlacz
            cjne      wyświetlacz,#3,dalej
            mov      wyswietlacz,#0
    dalej:
            cjne      wyswietlacz,#0,nie0
                tutaj
                instrukcje dla 
                zapalenia 1 wyswietlacza
            reti
    nie0: cjne       wyswietlacz,#1,nie1
                tutaj
                instrukcje dla 
                zapalenia 2 wyswietlacza
            reti           
    nie1: cjne wyswietlacz,#2,nie2
                tutaj
                instrukcje dla 
                zapalenia 3 wyswietlacza
            reti
    nie2: reti


    To może być jedno z rozwiązań wyświetlania.
    Pozdrawiam
  • #14 2888857
    ekspert100
    Poziom 18  
    Posty: 541
    Pomógł: 32
    Ocena: 73
    Witam !!!

    Ok rozumiem że zgłoszenie od t0 ma startować pracę
    wyswietlacza wiec należało by jeszcze obliczyć wartości do ładowania
    liczników t0. W jaki sposób to obliczyć to optymalnie i kiedy powinny te liczniki startować, czy przy wyjściu z obsługi przerwania t0

    Pozdrawiam
  • Pomocny post
    #15 2890597
    tprzemko
    Poziom 22  
    Posty: 413
    Pomógł: 54
    Ocena: 21
    Witam
    Załóżmy że chcemy mieć 50Hz. Teraz trzy wyświetlacze to wychodzi przerwanie 150Hz czyli okres co 0,00666 itd sec. Teraz policz ile cykli przypada przy Twoim zegarku na taki czas. Teraz wystarczy podstawić dane do liczników Timera (pamiętaj że liczą one w górę). Wydaje mi się że ładniej jest przeładować liczniki Timerów przy wejściu do przerwania iż przy wychodzeniu chociaż jest to możliwe jeżeli znamy dokładną ilość cykli zegarowych programu obsługującego przerwanie.
    Pozdrawiam
  • Pomocny post
    #16 2890860
    Dyrek
    Poziom 16  
    Posty: 129
    Pomógł: 21
    Ocena: 1
    Nie wiem czy dobrze zrozumiałeś ideę wykożystania przepełnienia od licznika w tego typu wyświetlaniu, więc po kolei:
    - napewno wiesz że przy wyświetlaniu multipleksowym w danej chwili świeci tylko jedna cyfra, aby uzyskac efekt świecenia wszystkich trzeba kilkadziesiąt razy na sekundę zapalac kolejne cyfry. Częstotliwośc przerwań od licznika dobierasz właśnie według tego, np masz 3 cyfry więc należałoby każdą zaświecac min 30 razy na sekundę (teoretycznie mówią 25 ale najlepiej 50 x ) a więc 3*30=90 czyli licznik powinien się przepełniac ok 90 razy na sekundę, zaokrąglmy to do 100 :) (co 10ms). Licznik w standardowym 8051 przy kwarcu 12MHz maksymalnie może odliczac odcinki ok. 65ms (cały zakres 65536, jedno zliczenie trwa 1µs) zatem potrzeba nam 10 000 cykli licznika, zatem wartośc jaką należy wpisac do licznika obliczamy T0=65536-10000 --> T0=55536. A dla jeszcze większego bezpieczeństwa żeby nie migało daje przepełnienie 200 razy na sekundę (ale to juz sam policz uwzględniając że to był przykład dla kwarcu 12MHz). W każdym razie jeśli tym samym licznikiem nie odmierzasz czasu to wartości nie muszą byc tak dokładnie obliczane. Wracając do sposobu wyświetlania, po zgłoszeniu przerwania od licznika zapalasz kolejną cyfrę i wychodzisz z przerwania, cyfra świeci śię do nastepnego zgłoszenia się licznika gdzie ją gasisz a zapalasz następną i tak w kółko :)
    Natomiast licznik startujesz w programie głównym gdy już go skonfigórujesz na początku programu a tylko przeładowujesz tuż po zgłoszeniu się przerwania od tego licznika.
    U mnie dla wyświetlacza cztero-cyfrowego wygląda to mniej więcej tak:

    
    dl0	equ	20h
    dl1	equ	21h
    dl2	equ	22h
    dl3	equ	23h	;deklaracje rejestrów z cyfrą do wyświetlenia
    led	equ	24h	;rejestr z aktualnie zaświeconą cyfrą
    
    
    
    
    ;--przerwanie od licznika
    	mov	tl0,#wartosc_LOW
    	mov	th0,#wartosc_HIGH	;przeładowanie licznika
    
    	push	acc
    	push	psw
    
    ;--wyświetlenie LED--
    	mov	a,led
    	rr	a
    	mov	led,a
    
    	mov	p2,#0ffh		;wyłączenie wszystkich segm.
    
    	jnb	acc.0,nie0
    	mov	p0,dl0
    	sjmp	koniec
    nie0:
    	jnb	acc.1,nie1
    	mov	p0,dl1
    	sjmp	koniec
    nie1:
    	jnb	acc.2,nie2
    	mov	p0,dl2
    	sjmp	koniec
    nie2:
    	jnb	acc.3,koniec
    	mov	p0,dl3
    koniec:
    	mov	p2,led		;załączenie aktualnej cyfry
    ;--koniec wyświetlania LED--
    	pop	psw
    	pop	acc
    	reti
    ;--koniec przerwania od licznika--
    
    
    
    
    ;----program główny----
    ;konfigóracje początkowe
    ;konfigóracja licznika
    	mov	tl0,#wartosc_LOW
    	mov	th0,#wartosc_HIGH
    	mov	led,#10001000b	;jedynka aktywuje wyswietlacz
    ;start licznika
    ;dalsze instrukcje programu
    



    pozdrawiam

Podsumowanie tematu

✨ Dyskusja dotyczy obsługi przerwań w asemblerze dla mikrokontrolera 89C2051, ze szczególnym uwzględnieniem przerwań od timerów T0 i T1. Omówiono konieczność zachowania rejestrów PSW, ACC i CY na stosie przy wejściu do przerwania oraz stosowanie instrukcji RETI na końcu procedury obsługi przerwania, co jest niezbędne do poprawnego powrotu i zwolnienia systemu przerwań. Wyjaśniono różnicę między instrukcjami RET i RETI – RET służy do powrotu z podprogramów wywołanych LCALL/ACALL, natomiast RETI kończy obsługę przerwania i przywraca stan systemu przerwań. Rejestr IP (priorytetów przerwań) można konfigurować w zależności od potrzeb, aby ustalić kolejność obsługi przerwań. Kolejność umieszczania podprogramów przerwań i programu głównego jest dowolna, często podprogramy umieszcza się na początku kodu.

W zakresie implementacji wyświetlania na multipleksowanym wyświetlaczu 7-segmentowym sterowanym portem P1, zasugerowano obsługę wyświetlacza w przerwaniu od timera T1, które wywołuje cykliczne zapalanie kolejnych cyfr z częstotliwością zapewniającą efekt ciągłego świecenia (np. 50 Hz na cyfrę, co daje około 150 Hz przerwań dla trzech cyfr). Obliczanie wartości do załadowania liczników timerów opiera się na częstotliwości taktowania i wymaganym okresie przerwań, z zaleceniem przeładowywania liczników na początku obsługi przerwania. Przykładowo, dla kwarcu 12 MHz i przerwań co 10 ms, wartość do załadowania licznika T0 wynosi około 55536 (65536 - 10000).

Przedstawiono fragmenty kodu asemblera z deklaracjami zmiennych, organizacją wektorów przerwań (adresy 000Bh dla T0 i 001Bh dla T1), oraz przykładową implementacją wyświetlania i obsługi przerwań. Podkreślono, że konfiguracja timerów i przerwań powinna być wykonana raz na początku programu, a nie powtarzana w procedurach przerwań. Wskazano także na konieczność modularnego podejścia do programowania, z podprogramami realizującymi poszczególne funkcje i głównym programem sterującym logiką.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA