Forum: Mikrocontroller und Digitale Elektronik Interrupt Vectoren ATmega16a


von Matze T. (gruetzwurschd)


Lesenswert?

Hallo Leute,

ich habe momentan Folgendes Problem. Habe die suchfunktion genutzt und 
auch Google fördert nichts brauchbares zu Tage.

Ich benutze derzeit einen ATmega16A und den WinAVR Compiler. Nun habe 
ich das Problem, dass der Compiler den Prozessor unterstützt, aber 
sobald ich in der int_vector-tabelle suche, ist dieser Prozessortyp 
nicht gelistet. Bis dato hatte ich keine Probleme wenn ich die Vektoren 
dennoch benutzt habe:


ISR(INT0_vect) oder ISR(TWI_vect)
funktionier tadellos.

Verwende ich allerdings:
UART_UDRE_vect oder USART0_UDRE_vect
kommt die warningmeldung "../rs232.c:31: warning: 'USART0_UDRE_vect' 
appears to be a misspelled signal handler"

benutze ich hingegen USART_UDRE_vect
kommt zwar kein warning. sobale ich aber sei(); setze wird mir ein Reset 
ausgelöst und ich stehe wieder am Anfang vom Programm.

auch _VECTOR(13) funktioniert auch nicht

ich habe es mit folgendem quellcode probiert.
für Hilfe vielen dank im vorraus
gruß Tarkan
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
void RS232_Init();
5
6
int main(void)
7
{int a;
8
9
RS232_Init();
10
sei();
11
a=1;
12
13
while(1);
14
}
15
16
void RS232_Init()
17
{
18
19
UBRRH = 0x00;
20
UBRRL = 0x03;  //Entspricht 250kbps bei 16 MHz
21
22
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<UDRIE);//|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE);
23
24
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
25
26
}
27
28
ISR(_VECTOR(13))//geht nicht
29
{int a;
30
a=1;
31
}

von Falk B. (falk)


Lesenswert?

@  Tarkan D. (gruetzwurschd)

>benutze ich hingegen USART_UDRE_vect

Der ist OK.

>kommt zwar kein warning. sobale ich aber sei(); setze wird mir ein Reset
>ausgelöst und ich stehe wieder am Anfang vom Programm.

Woran erkennst du das?

>ich habe es mit folgendem quellcode probiert.

Du musst natürlich Daten in UDR schreiben, sonst bleibt dein Interrupt 
ständig aktiv.

MFG
Falk

von Matze T. (gruetzwurschd)


Lesenswert?

Falk Brunner schrieb:
>>kommt zwar kein warning. sobale ich aber sei(); setze wird mir ein Reset
>>ausgelöst und ich stehe wieder am Anfang vom Programm.
>
> Woran erkennst du das?

da erkenne ich am Debuggen daran, dass sobald ich über das sei(); laufe, 
ich sofort wieder am anfang der main-funktion stehe, anstatt in die ISR 
zu kommen :)
zusätlich habe ich breakpoints in der ISR und kann somit sicher sagen, 
dass der code in der ISR nicht ausgeführt wird.

Falk Brunner schrieb:
> Du musst natürlich Daten in UDR schreiben, sonst bleibt dein Interrupt
> ständig aktiv.

da gebe ich dir vollkommen recht, allerdings ist das ja der effekt den 
ich erzielen will, um zu verifizieren ob die ISR ausgeführt wird.

von Matze T. (gruetzwurschd)


Lesenswert?

übrigens:

sobald ich an der ISR was ändere kommt auch:

../rs232.c:31: warning: 'USART_UDRE_vect' appears to be a misspelled 
signal handler

von Hc Z. (mizch)


Lesenswert?

> sobald ich an der ISR was ändere kommt auch:

> ../rs232.c:31: warning: 'USART_UDRE_vect' appears to be a misspelled
> signal handler

Du solltest auch am Namen der ISR nicht einfach rumprobieren und was 
ändern, sondern säuberlich darauf achten, dass Du nur die Bezeichnungen 
nimmst, die in der Dokumentation zu <avr/interrupt.h> stehen, und zwar 
für Deinen µC-Typ.

Wenn nach sei() ein Reset ausgeführt wird, hast Du einen weiteren 
Interrupt hängen (also erlaubt und seine Bedingung trifft zu), und zwar 
einen, für den Du keine ISR definiert hast.  Ganz sicher weißt Du das, 
wenn Du einen Breakpoint auf __bad_interrupt setzst und der triggert.

von Matze T. (gruetzwurschd)


Lesenswert?

Hc Zimmerer schrieb:
> Du solltest auch am Namen der ISR nicht einfach rumprobieren und was
> ändern, sondern säuberlich darauf achten, dass Du nur die Bezeichnungen
> nimmst, die in der Dokumentation zu <avr/interrupt.h> stehen, und zwar
> für Deinen µC-Typ.

ich änder nix am namen, sondern wenn ich statt a=1; a=2; schreibe, kommt 
die warningmeldung beim ersten kompilieren, beim zweiten mal mit 
unveränderter ISR kommt 0 warnings, 0 errors.

Des Weiteren steht in der in der Dokumentation von <avr/interrupt.h> 
rein garnihcts über den ATmega16a, sondern nur über den ATmega16, was 
aber bis jetzt immer wunderbar geklappt hat.

Hc Zimmerer schrieb:
> Wenn nach sei() ein Reset ausgeführt wird, hast Du einen weiteren
> Interrupt hängen (also erlaubt und seine Bedingung trifft zu), und zwar
> einen, für den Du keine ISR definiert hast.

Das ist ja soweit richtig. aber wenn mich nicht alles täuscht sind die 
einzelnen interrupts doch nach einem Reset deaktiviert, außer ich sage 
ausdrücklich sie sollen aktiviert werden(was ich nicht habe).

von Karl H. (kbuchegg)


Lesenswert?

Tarkan D. schrieb:

> Des Weiteren steht in der in der Dokumentation von <avr/interrupt.h>
> rein garnihcts über den ATmega16a, sondern nur über den ATmega16, was
> aber bis jetzt immer wunderbar geklappt hat.

Das ist auch egal.
Aus Softwaresicht sind die beiden soweit identisch

> Das ist ja soweit richtig. aber wenn mich nicht alles täuscht sind die
> einzelnen interrupts doch nach einem Reset deaktiviert, außer ich sage
> ausdrücklich sie sollen aktiviert werden(was ich nicht habe).

Mit dem sei() aktivierst du aber den Data Register Empty Interrupt, den 
du vorher eingeschaltet hast.

In der iom16.h steht, wie der wirklich heisst
USART_UDRE_vect

und ja, nach dem sei() feuert der, denn das Data Register ist ja 
wirklich empty. Und der feuert und feuert und feuert.

Das hier
1
ISR(_VECTOR(13))
solltest du hingegen nicht tun.
Denn der Vector 13 ist mit dem Tx-Complete Interrupt verknüpft. Dadurch 
das du hier den Vector 13 angegeben hast, hast du dir selbst den Data 
Register Empty Interrupt geklaut und damit hast du einen Interrupt 
eingeschaltet, für den du keinen Handler hast - der Bad Interrupt 
schlägt zu und resettet den µC.

Für den Mega16 läuft dieses Programm so wie es programmiert ist. Wenn es 
bei dir nicht tut, oder du vom Compiler Warnungen oder Fehler bekommst, 
dann hast du höchst wahrscheinlich bei den Projektoptionen oder im 
Simulator den falschen Prozessor eingestellt.
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
void RS232_Init();
5
6
int main(void)
7
{int a;
8
9
RS232_Init();
10
sei();
11
a=1;
12
13
while(1);
14
}
15
16
void RS232_Init()
17
{
18
19
UBRRH = 0x00;
20
UBRRL = 0x03;  //Entspricht 250kbps bei 16 MHz
21
22
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<UDRIE);//|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE);
23
24
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
25
26
}
27
28
ISR( USART_UDRE_vect )
29
{int a;
30
a=1;
31
}

von Matze T. (gruetzwurschd)


Angehängte Dateien:

Lesenswert?

Karl heinz Buchegger schrieb:
> Das hierISR(_VECTOR(13))
> solltest du hingegen nicht tun.
> Denn der Vector 13 ist mit dem Tx-Complete Interrupt verknüpft. Dadurch
> das du hier den Vector 13 angegeben hast, hast du dir selbst den Data
> Register Empty Interrupt geklaut und damit hast du einen Interrupt
> eingeschaltet, für den du keinen Handler hast - der Bad Interrupt
> schlägt zu und resettet den µC.

Danke für die Antwort. Ich weiß es kling blöd wenn ich jetzt sage dass 
ich alles richtig gemacht habe und alle anderen haben unrecht. Aber ich 
habe hier einen Ausschnitt aus dem Datenblatt des ATmega16a. Also 
entweder ist tatsächlich in der headerfile ein Fehler oder im Datenblatt 
oder ich bin wirklich zu unfähig. Aber hier seht selbst:(hoffe das hat 
geklappt mit dem dateianhang)

von Karl H. (kbuchegg)


Lesenswert?

Tarkan D. schrieb:

> ich alles richtig gemacht habe und alle anderen haben unrecht. Aber ich
> habe hier einen Ausschnitt aus dem Datenblatt des ATmega16a.

Das Datenblatt beginnt mit seiner Zählung bei 1
Das Header File beginnt in typischer C-Manier seine Zählung bei 0

Das hat seine Vorteile, wenn man aus der Nummerierung des Vektors die 
Adresse ausrechnenn soll, wo der entsprechende Eintrag in der 
Vektortabelle gemacht werden soll.

Nur musst du auch die Zählweise verwenden, auf die das VECTOR Makro 
ausgelegt ist.

von Matze T. (gruetzwurschd)


Lesenswert?

Ich hab jetzt das komplette Projekt gelöscht und nochmal neu aufgezogen.
Hat alle snihct geholfen.

mit ISR( USART_UDRE_vect ) kam das Warning immernoch. ISR wurde nicht 
aufgerufen.


anschließend habe ich es nochmal mit folgendem Quelltext probiert:
1
#include<avr/io.h>
2
#include<avr/interrupt.h>
3
4
void RS232_Init();
5
6
int main(void)
7
{int a;
8
9
RS232_Init();
10
sei();
11
a=1;
12
13
while(1);
14
}
15
16
void RS232_Init()
17
{
18
19
UBRRH = 0x00;
20
UBRRL = 0x03;  //Entspricht 250kbps bei 16 MHz
21
22
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<UDRIE);//|(1<<RXCIE)|(1<<TXCIE)|(1<<UDRIE);
23
24
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
25
26
    }
27
28
ISR( _VECTOR(12) )
29
{int a;
30
a=1;
31
}

und... es funktioniert.

ein Blick in die iom16a offenbarte mir folgende Code-Zeilen:
1
#define USARTUDRE_vect_num  12
2
#define USARTUDRE_vect      _VECTOR(12)  /* USART Data Register Empty */

das heißt bei USART_UDRE_vect ist der _ zuviel. Das gilt allerdings nur 
für die Vektoren die das USART-Modul und das SPI-Modul betreffen.



Grüße Tarkan

von Karl H. (kbuchegg)


Lesenswert?

Tarkan D. schrieb:

> ISR( _VECTOR(12) )
> {int a;
> a=1;
> }[/c]
>
> und... es funktioniert.

Schreib trotzdem USARTUDRE_vect, solange bis der Fehler in der Toolchain 
behoben wurde.

> ein Blick in die iom16a offenbarte mir folgende Code-Zeilen:
>
1
> #define USARTUDRE_vect_num  12
2
> #define USARTUDRE_vect      _VECTOR(12)  /* USART Data Register Empty */
3
>

Da wurde offenbar an der Nomenklatur gedreht. Diese Schreibweise ist 
IMHO nicht richtig.

von Matze T. (gruetzwurschd)


Lesenswert?

ja ich werde es in zukunft schon mit dem USARTUDRE_vect machen. Wollte 
nur bescheid sagen, weil ich mit sicherheit nihct der Letzte bin der 
damit Probleme hat.

von Hc Z. (mizch)


Lesenswert?

Ich bin gerade dabei, einen Patch für avr-libc zusammenzustellen, der 
Namen erlaubt, die konsistent zum bisherigen Vektor-Schema sind (z.B. 
USART_RXC_vect), die geänderten aber nicht rausschmeißt (so dass in 
Zukunft beides geht).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.