Poniżej przedstawiam przykładowy, który ma za zadanie wysyłać i odbierać dane przez UART. Program jest napisany w bascomie jako wastawki asemblerowe.
Proble tkwi w tym, że gdy następuje przerwanie z RI, to wskaźnik stosu jest identyczny na poczatku i na końcu, więc po przejściu procedury przerwania, następuje odrazu powrót z przerwania. Natomiast gdy wysyłane są dane, po przejściu procedury przerwania, wskaźnik stosu jest o 2 jednostki wyższy niż powinien. Efektem tego jest to, że nie następuje wyjście z przerwania odrazu, tylko powrót do początku procedury i dopieru po wykonaiu tej pętelki następuje powrót.
Mogę oczywiście dekremetować dwukrotnie wskaźnik stosu podczas procedury wysyłania (w załączonym kodzie jest to umieszczone jako komentarz) w samym przerwaniu, ale nie wiem czy nie zdejmę ze stosu waznych informacji. Może mi ktoś wytłumaczy dlaczego tak się dzieje?

Pozdrawiam i czekam na podpowiedzi
$sim
$crystal = 11059200
$baud = 9600
$large
'deklaracja zmiennych
Dim R7_ As Byte
Dim R6_ As Byte
Dim R5_ As Byte
Dim R4_ As Byte
Dim R3_ As Byte
Dim Ser1 As Byte
Dim Ser2 As Byte
Dim Zwloka As Byte 'zwloka na wysylanie
Dim Temp As Byte
Dim Kod1 As Byte ' bajt tymczasowy
Dim Kod2 As Byte
Dim Fbajt As Bit 'flaga odbioru RS-a
Dim Kontrola As Bit
On Serial Czytaj Nosave
Scon = 80 ' zalaczenie portu szeregowego
mov tmod,#32 'ustawienie typu dzialania licznika
mov pcon, #128 'ustawienie szybkosci na 9600
mov th1,#253 'zaladowanie licznika rs
setb tcon.6 'uruchomienie ukladu licznikowego T1
mov ip,#0 'ustalenie prioryteru przerwania
setb ie.7 'zalaczenie ukladu przerwan
setb ie.4 ' zalaczenie przerwania pochodzacego z rs-a
'Ustawienie zmiennych
mov {ser1},#&h12
mov {ser2},#&h22
'Program glowny
$asm
Poczatek:
mov a,{ser1}
add a ,{ser2}
mov {zwloka},a
Oczekuj: 'oczekiwanie na odbior bajtu
jnb fbajt,Oczekuj 'oczekiwanie w petli
clr fbajt 'skasowanie flagi
mov a,{temp} 'skopiowanie bajtu do akumulatora
cpl a ' zanegowanie
cjne a,{zwloka}, skok1 ' porownanie numeru seryjnego
ajmp wyslanie
Skok1:
ajmp koniec
Wyslanie:
add a, #&h03 ' zwiekszenie czasu zwloki o czas
mov {zwloka},a
mov a,#&hF0
acall wyslij
mov a,{ser1}
mov {kod1},a 'wyslanie klucza 1
mov sbuf, a
mov a,{ser2}
add a,{zwloka} 'wyslanie klucza 2
mov {kod2},a
acall wyslij
Koniec:
nop
ajmp koniec
Wyslij:
mov sbuf,a
ret
$end Asm
Czytaj:
$asm
push psw
push acc
jnb scon.0, read1 'jezeli to nie byla flaga odbioru, wyjdz z przerwania
clr scon.0
jb scon.0, *+0 ' jeżeli to byla flaga odbiotu to ją zresetuj
mov A,sbuf
mov {temp},a
setb fbajt
ajmp wyjdz
Read1:
jnb scon.1, wyjdz 'jezeli to nie byla flaga nadawania, idz dalej
clr scon.1 'jezeli to byla flaga nadawania to ją zresetuj
jb scon.1, *+0
'dec sp ' opcjonalne dekrementowanie wskaźnika stosu
'dec sp
Wyjdz:
pop psw
pop acc
$end Asm
Return