WinAVR, jak zmienić funkcję obsługi przerwania w t

Witam uprzejmie,

W programie pisanym na mikrokontroler ATmega128 w języku C (kompilator WinAVR) mam zdefiniowaną funkcję obsługi jednego z przerwań

SIGNAL (SIG_OVERFLOW1) { // jakiś kod }

Przy czym mam potrzebę, aby w trakcie działania programu móc przypisywać różne funkcje pod obsługę tego przerwania (przykładowo użytkownik wybiera pracę bipolarną albo unipolarną urządzenia, dla których to trybów powinny być inne funkcje podpinane pod obsługę przerwania). Mógłbym pewnie zrobić tak:

SIGNAL (SIG_OVERFLOW1) { if (pracaBipolarna) { // kod dla pracy bipolarnej } else { // kod dla pracy unipolarnej } }

Ale może da się podpinać pod obsługę przerwania różne funkcje w trakcie działania programu. Jeśli da się, to jak to zrobić?

Z góry dziękuję za pomoc.

Robbo PS. Wiem, że obecnie SIGNAL jest przestarzały.

Reply to
Robbo
Loading thread data ...

Am 04.10.2012 16:31, schrieb Robbo:

Nie programuję w WinAVR, ale możliwe jest pewnie podmienienie adresu w tabeli przerwań. Atmele programuję w assemblerze, ale inne procki tak mogą. Tylko nie zapomnij o wyłączeniu przerwania przed podmianą i załączeniem po, bo może być burda.

Waldek

Reply to
Waldemar Krzok

Ad maiorem Waldemar Krzok gloriam :

Tabela przerwań siedzi we flashu...

Sławek

Reply to
Sławomir Szczyrba

W dniu 04.10.2012 16:31, Robbo pisze:

Witam Jeśli to tylko dwie procedury do wyboru, to zaproponowane rozwiązanie jest chyba najoptymalniejsze. Jeśli do wyboru ma być więcej procedur, to zamiast ewentualengo switch()..case (różny czas reakcji na przerwanie w zależności od położenia w łancuchu case) proponuję tablicę wektorów do poszczególnych procedur.

AVRki mają rozkaz skoku do adresu określonego w rejestrze indeksowym Z.

Pozdrawiam Grzegorz

Reply to
Grzegorz Kurczyk

W dniu 2012-10-04 17:13, Grzegorz Kurczyk pisze:

Sensowny kompilator powinien przerobić switch właśnie na tablicę wektorów, jeśli uzna to za bardziej optymalne. Nawet SDCC tak robi.

Pozdrowienia, MKi

Reply to
MKi

Witam,

do zmiany "w locie" cu wykonuje sie w przerwaniu dobrze sie wykorzystuje wskaznik do funkcji. Zadeklaruj sobie zmienna typu wskaznik do funkcji w pliku, gdzie masz obsluge przerwania . Dodatkowo, w tym samym pliku stworz funkcje SetIrqHandler(), ktorej parameterm jest wskaznik na funkcje. W samym przerwaniu wywolujesz funkcje przez jej wskaznik.

na szybko cos podobnego do:

static void(*pIrqHandler)(void);

/** @file main.c */

// zmienna globalna dla tego pliku, niedostpena z innych modulow static void (*pIrqHandler)(void);

// funkcja do inicjalizacji wskaznika do funkcji, exportowana w irq.h void SetIrqHandler(void( *pNewHandler)(void)) { pIrqHandler = pNewHandler; }

/** to wlasciwa funkcja przerwania SIGNAL (SIG_OVERFLOW1) ale nie mam WinAvr zeby calosc kompilowac, testowalam poprawnosc skladni na Yagarto

*/ //SIGNAL (SIG_OVERFLOW1) void Doirq(void) { pIrqHandler(); }

/****************************/

int EnableIrq() { return 0; }

int DisableIrq() { return 0; }

void f1(void) { // zrob cos }

void f2(void) { // zrob co innego }

void main1 (void) { StandardowaInicjalizacja(); SetIrqHandler(f1);

EnableIrq();

while(1) {

// zrob co trzeba // a jak dojdziesz ze irq ma robic co innego to: // to tylko do testow, normalnie funkcja wywolana przez hardware irq Doirq(); DisableIrq(); SetIrqHandler(f1); EnableIrg(); // to tylko do testow, normalnie funkcja wywolana przez hardware irq Doirq(); // kontynuuj z main }

}

mankament jaki widze, to to ze obsluga przerwania wydluzy sie o wywolanie kolejnej funkcji oraz odlozy troche na stos. Ogowlnie, wskazniki do funkcji to bardzo uzyteczna rzecz, np. tablica takich wskaznikow zastepuje swietnie skomplikowane if czy switch no i mozna zmieniac je podczas dzialania programu

Reply to
Marcin

oczywiscie poza literowkami, mialo byc:

DisableIrq(); SetIrqHandler(f2); // zmiana funcji jaka wykona przerwanie EnableIrq();

no i podwojnie sie wkleilo static void(*pIrqHandler)(void);

Marcin

Reply to
Marcin

Lekko w bok od głównego tematu. Stosujesz stare funkcję obsługi przerwania. Zamiast SIGNAL stosuj ISR() z nowymi wektorami. Ich wykaz i zamianę starych na nowe znajdziesz tutaj:

formatting link

Reply to
Dondu

Mam małe doświadczenie z AVR-ami, ale może poczytaj o atrybutach OS_main, OS_task i przede wszystkim o naked.

Reply to
JDX

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.