Cześć wszystkim!
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
Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięBascom '51 - O co chodzi z tym stosem???
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
O ile zdołałem się zorientować to procedura czytaj jest obsługiwana przez przerwanie z UART'a a musisz wiedzieć że procedura przerwania w asemblu powinna być zakończona rozkazem RETI (return interrupt) a w tym kodzie nie widzę go. Jest rozkaz RETURN ale nie wiadomo jakie procedury asm on wykonuje?
Spróbuj przed "$end Asm" wstawić komendę RETI
jeżeli wykonujesz procedury
push PSW
push ACC
to musisz je zdejmować
pop ACC
pop PSW
nie wiem może jeszcze są jakieś błędy,
Spróbuj przed "$end Asm" wstawić komendę RETI
jeżeli wykonujesz procedury
push PSW
push ACC
to musisz je zdejmować
pop ACC
pop PSW
nie wiem może jeszcze są jakieś błędy,
Ponieważ ten program to jedna wielka wstawka asemblerowa, to czy nie lepiej byłoby go napisać w całości w ASM? Nie wiadomo co ten Bascom dodaje od siebie. A skoro napisałeś te wstawki, to zanczy że rozumiesz asembler i potrafisz w nim programować. W asemblerze będziesz miał pełny obraz kodu wynikowego, a tutaj możemy sie tylko domyślać, co kompilator generuje. Proponuję, zdeasembluj wynikowego HEXa i przyjrzyj sie kodowi, może wychwycisz coś "podejrzanego".
Zaczerpnięte z instrukcji Bascom:Return to z pewnością po prostu RET.
You must return from the interrupt routine with the RETURN statement. You may have only one RETURN statement in your interrupt routine because the compiler restores the registers and generates a RETI instruction when it encounters a RETURN statement in the ISR.
Obejrzałem twój program na symulatorze Bascom. Działa bez zarzutu. Wywołuje przerwanie i wraca do miejsca wywołania. Więc o co chodzi? Jak sprawdzasz te wszystkie wymienione w poście tezy?Problem tkwi w tym, że gdy następuje przerwanie....
Maybe
Asemblera załączem się uczyć zaraz po tym jak troszkę poznałem bascoma i wolę programować w ASM, bo lubię wiedzieć co się dzieje w procku. Pozatym można dokładnie obliczyć ilości cykli zegarowych na każdą procedurę. Pozwalami to wydusić z procka "ostatnie soki", gdy potrzebuję sprawnego działania softu. Bascoma używam dlatego, bo ma obsługę LCD, I2C, symulator i parę innych bajerów, gdy potrzebuję zrobić coś na szybko, (nie koniecznie ergonomicznie) to główny program robię w ASM a peryferia w bascomie. Myślę, że to jest dobre połączenie, pozwalające nie namęczyć się a zrobic program w miarę sprawny.
W przedstawionym kodzie faktycznie zrobiłem błąd, dotyczący zdejmowania kolejnosci danych ze stosu, ale to i tak nie ma wpływu na mój problem.
Skoro u niektórych z Was w symulatorze wszystko jest OK, to może coś z moim bascomem jest nie tak? Robiłem Deasemblację i niczego podejrzanego nie znalazłem.
Nie mam żadnego symulatora kodu napisanego w ASM, może mi coś polecicie?
Jeszcze trochę " porzeźbię" w ASM i chyba się przesiądę na C, bo widzę że pokazują się coraz ciekawsze narzędzia dla tego języka.
Dzięki za posty
Pozdrowionka dla wszystkich
W przedstawionym kodzie faktycznie zrobiłem błąd, dotyczący zdejmowania kolejnosci danych ze stosu, ale to i tak nie ma wpływu na mój problem.
Skoro u niektórych z Was w symulatorze wszystko jest OK, to może coś z moim bascomem jest nie tak? Robiłem Deasemblację i niczego podejrzanego nie znalazłem.
Nie mam żadnego symulatora kodu napisanego w ASM, może mi coś polecicie?
Jeszcze trochę " porzeźbię" w ASM i chyba się przesiądę na C, bo widzę że pokazują się coraz ciekawsze narzędzia dla tego języka.
Dzięki za posty
Pozdrowionka dla wszystkich
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 50 gości