KS
Guest
Mon Dec 27, 2004 7:01 am
Witam,
Piszę program w Keil C dla 8051 i mam następujący problem.
Chcę co pewien czas wywoływać pewien fragment programu.
W tym celu ustawiłem timer T0, wstawiłem procedurę obsługi przerwania i w
tej procedurze umieszczam wywołania interesujących mnie funkcji.
Program jednak nie działa. Po umieszczeniu dyrektywy Pragma SRC w programie,
kompilator generuje plik asemblerowy który jak mi sie wydaje jest
tłumaczeniem programu w C.
W tym tłumaczeniu znalazłem prawdopodobna przyczynę tego że program nie
działa.
W procedurze obsługi przerwania od T0 wywołuję funkcje Task1(), kompilator
tłumaczy to na: Lcall Task1(i według mnie tak ma być).W Task1 wywołuję
funkcje Pomiar() ale kompilator tłumaczy to na LJMP Pomiar. A według mnie
powinien wstawić Lcall pomiar, bo przecież powinien wrócić do tego miejsca
po zakończeniu funkcji Pomiar.
Funkcja Pomiar ładuje rejestry Przetwornika ADC i krązy w pętli sprawdzając
czy został ustawiony znacznik końca przetwarzania AC. Znacznik ten jest
ustawiany w oddzielnej procedurze obsługi przerwania ADC.
Co może być przyczyną takiego działania kompilatora?
KS
Mister
Guest
Mon Dec 27, 2004 7:38 am
A w ilu miejscach wywołujesz f-cję pomiar? Jeżeli tylko w jednym to
kompilator dobrze to zrobił.
Raczej szukaj problemu u siebie a nie wiń Keila:-)
Mister
KS
Guest
Mon Dec 27, 2004 8:49 am
Wywołuję ją jeden raz, ale cyklicznie (cykliczne przerwanie od licznika).
Dlaczego dobrze? Po wykonaniu funkcji Pomiar progran powinien wrócić w do
procedury Task1.
KS
Użytkownik "Mister" <wojpie@wywal_to.poczta.onet.pl> napisał w wiadomości
news:cqoed8$5i2$1@nemesis.news.tpi.pl...
Quote:
A w ilu miejscach wywołujesz f-cję pomiar? Jeżeli tylko w jednym to
kompilator dobrze to zrobił.
Raczej szukaj problemu u siebie a nie wiń Keila:-)
Mister
peters
Guest
Mon Dec 27, 2004 9:54 am
Quote:
W procedurze obsługi przerwania od T0 wywołuję funkcje Task1(), kompilator
tłumaczy to na: Lcall Task1(i według mnie tak ma być).W Task1 wywołuję
funkcje Pomiar() ale kompilator tłumaczy to na LJMP Pomiar. A według mnie
powinien wstawić Lcall pomiar, bo przecież powinien wrócić do tego miejsca
po zakończeniu funkcji Pomiar.
A wywolanie Pomiar() nie jest ostatnia instrukcja w funkcji Task1() ?
Jesli jest -to wszystko OK. Zadzialala optymalizacja.
peters
P.S. Bledow szukaj u siebie. Mnie udowodnienie bledu Keilowi zajmuje czasem
dwa miesiace ciezkiej pracy,
upraszczania wlasnego programu tak aby nadal dzialal zle...
KS
Guest
Mon Dec 27, 2004 11:02 am
Pomiar jest ostatnią funkcja w Task1.
Przyznam że nie rozumię dlaczego kompilator nie wstawia tam Lcall Pomiar.
Ale jesli tak ma być, to gdzie może tkwic bład?
Jeśli funkcja Pomiar() jes twywoływana w funkcji głównej to wszystko jest ok
a jesli w funkcji INT_T0 to program pada.
KS
Użytkownik "peters" <peters@poczta.onet.pl> napisał w wiadomości
news:cqome9$838$1@nemesis.news.tpi.pl...
Quote:
W procedurze obsługi przerwania od T0 wywołuję funkcje Task1(),
kompilator
tłumaczy to na: Lcall Task1(i według mnie tak ma być).W Task1 wywołuję
funkcje Pomiar() ale kompilator tłumaczy to na LJMP Pomiar. A według
mnie
powinien wstawić Lcall pomiar, bo przecież powinien wrócić do tego
miejsca
po zakończeniu funkcji Pomiar.
A wywolanie Pomiar() nie jest ostatnia instrukcja w funkcji Task1() ?
Jesli jest -to wszystko OK. Zadzialala optymalizacja.
peters
P.S. Bledow szukaj u siebie. Mnie udowodnienie bledu Keilowi zajmuje
czasem
dwa miesiace ciezkiej pracy,
upraszczania wlasnego programu tak aby nadal dzialal zle...
Krzysztof Rudnik
Guest
Mon Dec 27, 2004 11:28 am
Użytkownik "KS" <pokajok@interia.pl> napisał w wiadomości
news:cqoq38$adt$1@news.dialog.net.pl...
Quote:
Pomiar jest ostatnią funkcja w Task1.
No i dlatego robi JMP - po co wracac do return'a, mozna od razu pietro
wyzej.
Quote:
Przyznam że nie rozumię dlaczego kompilator nie wstawia tam Lcall Pomiar.
Ale jesli tak ma być, to gdzie może tkwic bład?
Jeśli funkcja Pomiar() jes twywoływana w funkcji głównej to wszystko jest
ok
a jesli w funkcji INT_T0 to program pada.
Nie znam tego procka, czy tam do wykorzystania w przerwaniach funkcja nie
musi
by jakos specjalnie kompilowana (inny return, zachowanie wszystkich
rejestrow itp).
W takiej sytuacji ten JMP bylby faktycznie bledny - program wykona
niewlasciwy RET.
Trche to glupie, ale sprobuj umiescic jakies instrukcje po wywolaniu
Pomiar(), by wymusic
powrot.
Cos wspominales o jakims czekaniu, jesli to jest w procedurze obslugi
przerwania
to nie za dobrze. Jesli tam sie zawiesi (np. nie ustawi sie jakis bit) to
wszystko wisi.
Krzysiek Rudnik
peters
Guest
Mon Dec 27, 2004 11:32 am
Użytkownik "KS" <pokajok@interia.pl> napisał w wiadomości
news:cqoq38$adt$1@news.dialog.net.pl...
Quote:
Pomiar jest ostatnią funkcja w Task1.
Przyznam że nie rozumię dlaczego kompilator nie wstawia tam Lcall Pomiar.
Czym rozni sie CALL od JMP?
Przy CALL na stosie zapamietywany jest adres powrotu.
Mamy cos takiego:
Taska1:
....
....
lcall Pomiar
ret
Pomiar:
....
ret
Przesledz sobie w myslach co robi procesor, co jest zapamietywane na stosie.
Po co wracac z procedury Pomiar tylko po to by wykonac jedna instrukcje
return?
Zamiast tego robi sie skok a return wykonuje sie juz w procedurze Pomiar.
Efekt identyczny.
Quote:
Ale jesli tak ma być, to gdzie może tkwic bład?
Jeśli funkcja Pomiar() jes wywoływana w funkcji głównej to wszystko jest
ok
a jesli w funkcji INT_T0 to program pada.
Gdzie? Wszedzie. Dlatego programowanie nie jest latwe.
Nie wiadomo co masz w calej reszcie programu. Jak czesto wywolywane jest
przerwanie i ile czasu zajmuje jego wykonanie.
Nie wiadomo czy nie przepelnia sie stos, czy nie popelniles jakiegos
idiotycznego bledu, np nie dales pustych nawiasow przy wywolaniu funkcji bez
parametrow. :)
peters
Andy
Guest
Mon Dec 27, 2004 1:04 pm
Użytkownik "KS" <pokajok@interia.pl> napisał w wiadomości news:cqoq38$adt$1@news.dialog.net.pl...
Quote:
Pomiar jest ostatnią funkcja w Task1.
Przyznam że nie rozumię dlaczego kompilator nie wstawia tam Lcall Pomiar.
Ale jesli tak ma być, to gdzie może tkwic bład?
Jeśli funkcja Pomiar() jes twywoływana w funkcji głównej to wszystko jest ok
a jesli w funkcji INT_T0 to program pada.
...
a obsluga przerwania wyrabia sie czasowo ?
wolasz moze fun Pmiar() z glwonej petli jak i z przerwania ?
bo w takiej sytuacji funkcja musi byc "reentrant"
masz jakies warningi przy kompilacji ?
--
Andrzej