-
1. Data: 2012-10-04 16:31:02
Temat: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: "Robbo" <n...@g...com>
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.
-
2. Data: 2012-10-04 16:42:19
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Waldemar Krzok <w...@z...fu-berlin.de>
Am 04.10.2012 16:31, schrieb Robbo:
> 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ć?
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
--
My jsme Borgové. Sklopte štíty a vzdejte se. Odpor je marný.
-
3. Data: 2012-10-04 16:59:15
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Sławomir Szczyrba <c...@o...the.night>
Ad maiorem Waldemar Krzok gloriam :
> 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.
>
Tabela przerwań siedzi we flashu...
> Waldek
Sławek
--
________
_/ __/ __/ Do I BELIEVE in the Bible?! HELL man, I've SEEN one!!!
\__ \__ \___________________________________________________
____________
/___/___/ Sławomir Szczyrba steev/AT/hot\dot\pl
-
4. Data: 2012-10-04 17:13:25
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Grzegorz Kurczyk <g...@c...slupsk.pl>
W dniu 04.10.2012 16:31, Robbo pisze:
> 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
> }
> }
>
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
-
5. Data: 2012-10-04 18:16:35
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: MKi <e...@o...pl>
W dniu 2012-10-04 17:13, Grzegorz Kurczyk pisze:
> 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.
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
-
6. Data: 2012-10-04 18:49:59
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Marcin <m...@o...pl>
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
-
7. Data: 2012-10-04 18:58:37
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Marcin <m...@o...pl>
oczywiscie poza literowkami, mialo byc:
DisableIrq();
SetIrqHandler(f2); // zmiana funcji jaka wykona przerwanie
EnableIrq();
no i podwojnie sie wkleilo static void(*pIrqHandler)(void);
Marcin
-
8. Data: 2012-10-04 20:11:11
Temat: Re: WinAVR, jak zmienic funkcje obslugi przerwania w trakcie wykonywania programu
Od: "Robbo" <n...@g...com>
Tez myslalem o wywolywaniu funkcji. Elegancko to wyglada, alewiaze sie z
narzutem zwiazanym z odlozeniem rejestrów na stos. Mysle, ze poprzestane na
zwyklym if (mam tylko dwa warianty kodu do przelaczania).
R.
-
9. Data: 2012-10-05 03:26:28
Temat: Re: WinAVR, jak zmienić funkcję obsługi przerwania w trakcie wykonywania programu
Od: Dondu <d...@g...com>
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:
http://www.nongnu.org/avr-libc/user-manual/group__av
r__interrupts.html
-
10. Data: 2012-10-05 09:54:21
Temat: Re: WinAVR, jak zmienic funkcje obslugi przerwania w trakcie wykonywania programu
Od: JDX <j...@o...pl>
On 2012-10-04 20:11, Robbo wrote:
> Tez myslalem o wywolywaniu funkcji. Elegancko to wyglada, alewiaze sie z
> narzutem zwiazanym z odlozeniem rejestrów na stos. Mysle, ze poprzestane
> na zwyklym if (mam tylko dwa warianty kodu do przelaczania).
Mam małe doświadczenie z AVR-ami, ale może poczytaj o atrybutach
OS_main, OS_task i przede wszystkim o naked.