8051 !!!



Masz problem? Zapytaj na forum elektroda.pl z bramką pl.misc.elektronika!

Poprzedni Następny
Wiadomoœć
spis treści
From: "Juliusz" <chip_at_nospam_resurrection.com>
Subject: 8051 !!!
Date: 23 Mar 1998 02:36:35 GMT


Witam,

Mam problem z 89C51, a dokładniej z jedna procedura w asemblerze.
Program jest bardziej zlozony, ale dla przykładu niech będzie to proste.

Wyobraźmy sobie:

Mamy główną pętlę programu składającą się z dowolnej liczby dowolnych
rozkazów:


MAIN_LOOP: jb 012h, EWA
Mov A,#010h
Jmp IZA
EWA: mov A,#0F2h
Nop
.....
jmp MAIN_LOOP


---------------

Program w powyższej pętelce czeka sobie na jakieś zdarzenie.
Mamy włączone przerwania od timera T0

Np.

T0_SRV: Nop
Nop
Reti


-----------------

No właśnie i tu zaczyna się problem:

Przerwanie przerywa prace głównej pętli w dowolnym momencie odkładając PC
na stos, a PC zostaje zmodyfikowane tak aby skoczyć do T0_SRV
automatycznie.

Ale ja nie chcę aby po reti program wracał do miejsca gdzie przerwał główną
pętlę, ale JA CHCĘ aby po przerwaniu ZAWSZE wracał do początku pętli czyli
do MAIN_LOOP !!!! Ponieważ w pętli głównej i w przerwaniu jest wiele
instrukcji i na dodatek w pętli głównej jest testowanych kilka stanów
logicznych, które mogą się zmienić w trakcie trwania obsługi przerwania, a
ja nie chce aby stany te pomieszały się.

Proszę o informacje jak zadeklarować ten labelek MAIN_LOOP na sztywno pod
jakimś adresem abym mógł ręcznie zmodyfikować zawartość stosu, która będzie
zwrócona do rejestru PC przy wychodzeniu z przerwania. Jest tu jeszcze
problem taki, ze jeżeli deklaruję segment to robią się dziury w kodzie,
które są tylko tracone i miejsce zostaje puste.
Proszę o kawałek przykładowego kodu.

Juliusz



Poprzedni Następny
Wiadomoœć
spis treści
From: wze_at_nospam_univcomp.waw.pl (Marcin Hamerla)
Subject: Re: 8051 !!!
Date: Mon, 23 Mar 1998 06:29:19 GMT


On 23 Mar 1998 02:36:35 GMT, "Juliusz" <chip_at_nospam_resurrection.com> wrote:
Program w powyższej pętelce czeka sobie na jakieś zdarzenie.
Mamy włączone przerwania od timera T0

Proszę o informacje jak zadeklarować ten labelek MAIN_LOOP na sztywno pod
jakimś adresem abym mógł ręcznie zmodyfikować zawartość stosu, która będzie
zwrócona do rejestru PC przy wychodzeniu z przerwania. Jest tu jeszcze
problem taki, ze jeżeli deklaruję segment to robią się dziury w kodzie,
które są tylko tracone i miejsce zostaje puste.
Proszę o kawałek przykładowego kodu.

Nie musisz na sztywno ustawiać położenia MAIN_LOOP za pomocą
instrukcji ASEG i ORG, o co Ci, jak myślę, chodziło. Kompilator i
linker potrafią wyliczyć wartość adresu MAIN_LOOP:

T0_SRV: Nop
Nop
pop acc
pop acc
push #low MAIN_LOOP
push #high MAIN_LOOP
Reti

Nie pamiętam w tej chwili czy kolejność instrukcji push jest
poprawna.

Poprzedni Następny
Wiadomoœć
spis treści
From: "Jaroslaw Lis" <lis_at_nospam_papuga.ict.pwr.wroc.pl>
Subject: Re: 8051 !!!
Date: 23 Mar 1998 11:58:52 GMT


Juliusz <chip_at_nospam_resurrection.com> wrote:
Ale ja nie chcę aby po reti program wracał do miejsca gdzie przerwał główną
pętlę, ale JA CHCĘ aby po przerwaniu ZAWSZE wracał do początku pętli czyli
do MAIN_LOOP !!!! Ponieważ w pętli głównej i w przerwaniu jest wiele
instrukcji i na dodatek w pętli głównej jest testowanych kilka stanów
logicznych, które mogą się zmienić w trakcie trwania obsługi przerwania, a
ja nie chce aby stany te pomieszały się.
Proszę o informacje jak zadeklarować ten labelek MAIN_LOOP na sztywno pod
jakimś adresem abym mógł ręcznie zmodyfikować zawartość stosu, która będzie
zwrócona do rejestru PC przy wychodzeniu z przerwania.

W zaleznosci od assemblera sa zwykle operacje "LOW" i "HIGH" bajt adresu.
W szczegolnosci MAIN_LOOP/256 i MAIN_LOOP%256.
Wiec mozesz gdzies tam pchnac lub podmienic wartosc.

Ale ja Cie ostrzegam - ty wcale nie chcesz zeby program Ci wracal do glownej
petli :-)


J.

Poprzedni Następny
Wiadomoœć
spis treści
From: "Sylwester Łazar" <zsee_at_nospam_ids.poznan.pl>
Subject: Re: 8051 !!!
Date: 23 Mar 1998 22:17:46 GMT


Ale ja Cie ostrzegam - ty wcale nie chcesz zeby program Ci wracal do
glownej
petli :-)


Podpisuję się pod tym.
Dodatkowo proponuje cofnąć się do założeń i przemyśleć:
a) co jest ważniejsze:
- to co w POPie (Procedura Obsługi Przerwania)
- czy może to co w pętli głównej
bo może warto spróbować zamienić czynności. Tzn. stan sprawdzany w pętli
głównej mógłby wywoływać POP. A to co dotychczas powoduje wywołanie
POP sprawdzać w MAINie?
b) być może warto nadać więcej poziomów przerwań.
Z tego co pamiętam w 51 można w miarę swobodnie operować hierarchią
przerwań.
c) może jednak zapamiętać stan zmiennych na początku POP i odtworzyć przy
wyjściu?
d) a już na pewno warto słownie opisać sobie na kartce, ze spokojem co
właściwie chcemy osiągnąć.

Kiedy w grę wchodzi przerwanie, zawsze trzeba określić:
przerwanie.

to wszystko co mi się przypomniało.
Jeszcze tylko uwaga:
Jeśli używasz przerwań i testujesz metodą:
1) PISZĘ PROGRAM
2) KOMPILUJĘ I URUCHAMIAM
3) POPRAWIAM
4) GOTO 2)

to jeśli kontroler zachowuje się dziwnie, na ~90% POP ingeruje w program
główny!

Powodzenia.
Pozdrawiam,

--
Sylwester Łazar
electronics engineer
zsee_at_nospam_ids.poznan.pl


Poprzedni Następny
Wiadomoœć
spis treści
From: amart_at_nospam_pol.JUNKMAILPROTECTION.pl (Jaroslaw Cichorski Jr.)
Subject: Re: 8051 !!!
Date: Mon, 23 Mar 1998 18:23:09 GMT


"Juliusz" <chip_at_nospam_resurrection.com> wrote:

<snip>

Ale ja nie chcę aby po reti program wracał do miejsca gdzie przerwał główną
pętlę, ale JA CHCĘ aby po przerwaniu ZAWSZE wracał do początku pętli czyli
do MAIN_LOOP !!!! Ponieważ w pętli głównej i w przerwaniu jest wiele
instrukcji i na dodatek w pętli głównej jest testowanych kilka stanów
logicznych, które mogą się zmienić w trakcie trwania obsługi przerwania, a
ja nie chce aby stany te pomieszały się.

To (jak mi sie wydaje) nie jest dobry pomysl, przynajmniej jezeli w
trakcie przechodzenia przez ta petle testujesz kilka rzeczy i
podejmujesz jakies decyzje. Nie wiem jak w tym konkretnym przypadku
wyglada ten proces decyzyjny, ale uważam, ze nalezy go zakonczyc, a
nie przerywac go w nieokreslonym miejscu i rozpoczynac od nowa ( w
skrajnym przypadku w ogole go nie skonczysz !).

Raczej zaproponowalbym zabronic obslugi INT0 przed wejsciem do sekcji
krytycznej w MAIN_LOOP, a po zakonczeniu sekcji krytycznej zezwolic na
obsluge INT0, po czym zostawic procesorowi jeszcze jednego NOP'a czasu
na ew. podjecie decyzji co do obsluzenia przerwania, zanim zapetlisz
znow do MAIN_LOOP.

W szczegolnym przypadku, gdy sekcja krytyczna jest na tyle dluga, ze
zgubieniu moze ulec fakt pojawienie sie nieobsluzonego (-nych) INT0,
wtedy raczej proponowalbym przepisywac stan zmiennych, ktore
analizujemy w sekcji krytycznej i operowac na ich kopii. Wtedy na
pewno pojawienie sie i obsluzenie INT0 nie spowoduje 'pogubienia sie'
w sekcji krytycznej.

Poniewaz nie wiem nic wiecej o tym programie i o realizowanej funkcji
przez urzšdzenie, trudno mi cos wiecej doradzic.
Kazdy z tych wariantow ma swoje wady i zalety i wybranie ktoregos z
nich zalezy od wielu czynnikow (czestotliwosc przerwan i czas ich
obslugi, dlugosc sekcji krytycznej, ilosc analizowanych zmiennych,
reszta zadan do wykonania itp).

Pozdrawiam

--------
Jaroslaw Cichorski Jr.
e-mail amart_at_nospam_pol.JUNKMAILPROTECTION.pl
UWAGA Adres niewazny!
Prosze usunac JUNK MAIL PROTECTION. zeby otrzymac prawidlowy adres.
Kto to jest General Failure i dlaczego czyta z mojego dysku twardego ?


Poprzedni Następny
Wiadomoœć
spis treści
From: "Juliusz" <juliusz_at_nospam_wyscigi.multi-ip.com.pl>
Subject: Re: 8051 !!!
Date: 31 Mar 1998 06:20:33 GMT


Dzieki za pomoc

Okazalo sie, ze po kilku dniach przemyslalem sprawe i nie trzeba wracac
nigdzie na poczatek petli. Wstawilem kilka drobnych warunkowych skokow i
przepisuje porty w taki sposob:

najpierw wszystko leci do rejestrow tymczasowych
np:
mov R6,P1
i dalej cale stado CJNE...JNB, JB itd....
....

a potem blyskawicznie do wlasciwych jak powyzsze petle puszcza dalej....

mov TCON,#00000000b; Zatrzymanie timera T0
mov R5,R6
itd......
mov TCON,#00010000b; Ponowny start T0

nawet jezeli przerwanie wyskoczy w polowie analizy kaskady CJNE itd. to i
tak dane beda brane z poprzedniego pelnego przelecenia. A czasu jest mnogo
i ta petla lata setki razy pomiedzy przerwaniami i to z zegarem 20MHz wiec
jedno przelecenie mniej i tak nic nie robi :)))))))))
Uwzglednilem ta strate czasu - te kilkanascie cykli w tym co wkladam do TL0
i TH0 i dziala. I jestem pewien, ze przerwanie nie wystapi w tym czasie !!!
A i analiza danych - dosc rozbudowana bedzie pelna.

Pan Jarek Lis i inni koledzy mieli racje - dzieki !!!!

Juliusz


================

Juliusz <chip_at_nospam_resurrection.com> napisał(a) w artykule
<01bd5603$d683e2a0$c60d75c3_at_nospam_juliusz>...
Witam,

Mam problem z 89C51, a dokładniej z jedna procedura w asemblerze.
Program jest bardziej zlozony, ale dla przykładu niech będzie to proste.

Wyobraźmy sobie:

Mamy główną pętlę programu składającą się z dowolnej liczby dowolnych
rozkazów:


MAIN_LOOP: jb 012h, EWA
Mov A,#010h
Jmp IZA
EWA: mov A,#0F2h
Nop
.....
jmp MAIN_LOOP


---------------

Program w powyższej pętelce czeka sobie na jakieś zdarzenie.
Mamy włączone przerwania od timera T0

Np.

T0_SRV: Nop
Nop
Reti


-----------------

No właśnie i tu zaczyna się problem:

Przerwanie przerywa prace głównej pętli w dowolnym momencie odkładając PC
na stos, a PC zostaje zmodyfikowane tak aby skoczyć do T0_SRV
automatycznie.

Ale ja nie chcę aby po reti program wracał do miejsca gdzie przerwał
główną
pętlę, ale JA CHCĘ aby po przerwaniu ZAWSZE wracał do początku pętli
czyli
do MAIN_LOOP !!!! Ponieważ w pętli głównej i w przerwaniu jest wiele
instrukcji i na dodatek w pętli głównej jest testowanych kilka stanów
logicznych, które mogą się zmienić w trakcie trwania obsługi przerwania,
a
ja nie chce aby stany te pomieszały się.

Proszę o informacje jak zadeklarować ten labelek MAIN_LOOP na sztywno pod
jakimś adresem abym mógł ręcznie zmodyfikować zawartość stosu, która
będzie
zwrócona do rejestru PC przy wychodzeniu z przerwania. Jest tu jeszcze
problem taki, ze jeżeli deklaruję segment to robią się dziury w kodzie,
które są tylko tracone i miejsce zostaje puste.
Proszę o kawałek przykładowego kodu.

Juliusz