problem z funkcjami w C dla 8051

Dec 27, 2004 7 Replies

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


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

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$ snipped-for-privacy@nemesis.news.tpi.pl...

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...

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" snipped-for-privacy@poczta.onet.pl> napisa³ w wiadomo¶ci news:cqome9$838$ snipped-for-privacy@nemesis.news.tpi.pl...

U¿ytkownik "KS" snipped-for-privacy@interia.pl napisa³ w wiadomo¶ci news:cqoq38$adt$ snipped-for-privacy@news.dialog.net.pl...

No i dlatego robi JMP - po co wracac do return'a, mozna od razu pietro wyzej.

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

U¿ytkownik "KS" snipped-for-privacy@interia.pl napisa³ w wiadomo¶ci news:cqoq38$adt$ snipped-for-privacy@news.dialog.net.pl...

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.

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

U¿ytkownik "KS" snipped-for-privacy@interia.pl napisa³ w wiadomo¶ci news:cqoq38$adt$ snipped-for-privacy@news.dialog.net.pl...

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 ?

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required