Dla znających AVR-y

Witam!

Mam problem, nie jestem zbyt biegły w programowaniu AVR w C, a chce zrobic w programie cos takiego: Program sklada sie z czeterech podprogramow i wykonywany jest tylko jeden podprogram az do nacisniecia klawisza, Key podpiety jest do INT0 i wiadomo ze jesli nacisne KEY to program zmyka do procedury obslugi przerwania (SIGNAL(SIG_INTERRUPT0)) w tej procedurze zmieniam ustawienia aby procesor wykonywal inny podprogram... ale zanim on bedzie wykonany procesor wroci do poprzedniego podprogramu aby go dokonczyc i tu moje pytanie: Jak mozna zmusic procesor aby zaniechal powrotu do poprzednio wykonywanej operacji - a przeszedl od razu do porzadanego podprogramu. Kojarze ze trzeba cos pokombinowac z licznikiem rozkazow oraz ze stosem ale chodzi mi o konkretny przyklad.

PS. Probowalem z instrukcja GOTO ale program AVR Edit nie kompiluje tego.

Reply to
mick
Loading thread data ...

Musisz znaleźć i podmienić adres powrotu na stosie.

Piotrek

Reply to
Piotrek Sz.

No niby tak, ale jak to wyglada w praniu - jakis przyklad

A tak w ogole to mam pytanie dla programistow w jaki sposob najczesciej rozwiazuja taki problem ktory opisalem??

Reply to
mi15

problem w tym, że praktycznie każda funkcja odkłada coś na stosie. nawet jeśli zmienisz adres powrotu (musiałbyś wiedzieć ile dokładnie bajtów na stosie odkłada funkcja obsługi przerwania), to nie dasz wykonywanej funkcji szansy na zdjęcie swoich śmieci ze stosu. przez to po paru(nastu) takich skokach przepełnisz stos i zaczną się czary mary.

ja bym po prostu w pętli głównej każdej funkcji sprawdzał jakąś flagę, która mówi, że ma zakończyć działanie i w pętli głównej programu wywołał odpowiednią funkcję. gdybyś się zdecydował na coś takiego, to nie zapomnij, żeby zmienne modyfikowane w przerwaniach były deklarowane jako ,,volatile''.

w.

Reply to
Wojtek Kaniewski

Najlepiej to przeformuuowac problem tak, aby nie wymagal tego typu dziwactw. Manipulacje ze stosem to proszenie sie o klopoty. Natomiast jesli masz rzeczywiscie tylko 4 procedury i stosu do niczego innego nie wykorzystujesz to mozesz po prostu w procedurze obslugi przerwania ponownie zainicjowac wskaznik stosu, a nastepnie wykonac skok przez rjmp lub odkladajac na stos adres wywolywanej procedury i reti. Gorzej jesli te podprogramy operuja na wspolnych danych - wtedy mozesz sie spodziewac ich uszkodzenia, gdyz przerwanie moze sie pojawic np. pomiedzy instrukcjami modyfikujacymi np. jakas wielobajtowa dana, co przerwie proces w polowie. Oczywiscie takie krytyczne sekcje mozna np. wykonywac z zablokowanymi przerwaniami -> jesli przerwanie wystapi w takiej sekcji AVR wykona je tuz po ponownym odblokowaniu przerwan.

Reply to
T.M.F.

T.M.F. snipped-for-privacy@nospam-mp.pl napisał(a):

Popieram przedmówcę :) Jeśli byś jednak upierał się przy swoim , to można zrobić tak: W pętli głównej sprawdzasz , który przycisk został wciśnięty i wywołujesz odpowiednią procedurę, natomiast w obsłudze przerwania odczytujesz numer przycisku, wstawiasz do zmiennej (koniecznie volatile), którą sprawdzi późnie pętla główna i nie bawiąc się ze stosem "rjmp main" , co pozwoli Ci na przywrócenie początkowej wartości wskaźnika stosu.

SIGNAL (INTERRUPT0) { //czytasz klawiaturę i zapisujesz do zmiennej asm volatile ("rjmp main"); }

int main(void) { sei(); while(1) { //Twoja pętla główna } }

Cuś w tym guście ;-)

Piotrek

Reply to
Piotrek Sz.

Widze ze rzeczywiscie najprosciej bedzie w kazdej procedurze dosc czesto sprawdzac flage, ktora powie czy zostal nacisniety Key.

DZiekuje WAM wszystkim za naswietlenie mi problemu. pozdrawiam Mick

Reply to
mi15

Najprościej to softwarowy reset trzeba zrobić.

Mister

Reply to
Mister

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.