Forum: Mikrocontroller und Digitale Elektronik Programm springt immer wieder an den Anfang zurück


von Guest (Gast)


Lesenswert?

Hallo,

ich hab ein Problem mit meinem Code.
1
int main(){
2
3
  init_USART( USART1 );        
4
  init_USART( USART0 );        
5
6
  DDRA = 0xFF;          
7
  DDRB = 0xFF;
8
  DDRC = 0xFF;  
9
10
  sei();              
11
  // Enable Global Interrupt verursacht, dass das Programm immer     
12
  // wieder an den Anfang springt.
13
  // --> An dieser Stelle springt das Programm dann an den Anfang   
14
  
15
    while(1){
16
         if( flag==1 ){
17
             Read_Instruct(buf);
18
             flag=0;
19
         }                
20
  }
21
22
}

Sobald ich sei() auskommentiere funktioniert alles einwandfrei. Woran 
liegt das? Ich muss leider die Interrupts global zulassen. Wie 
verhindere ich nun, dass das Programm an den Anfang zurückspringt?

von Andreas B. (buyman)


Lesenswert?

Hast du versehentlich ein Interrupt aktiviert aber nicht 
"ausprogrammiert"?

Von welchem Prozessor reden wir überhaupt?

von Claus (Gast)


Lesenswert?

Watchdog ausgeschaltet?

von Guest (Gast)


Lesenswert?

1. Das ist ein ATmega 128.
2. Wenn ich einen Interrupt aktiviert habe, dann würde das Programm doch 
an   der Stelle weiterlaufen, an der der Inerrupt ausgelöst worden ist. 
Das Programm springt doch nicht an den Anfang zurück, falls ich die 
dazugehörige Interrupt Service Routine nicht ausprogrammiert habe oder 
etwa doch?
3. Den Watchdog habe ich gar nicht angefasst.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

1/ M103 Fuse nicht ausgeschaltet?
http://www.mikrocontroller.net/articles/AVR_Fuses#Kompatibilit.C3.A4tsfuses_und_manchmal_l.C3.A4stige_Defaults

2/ Was machen

  init_USART( USART1 );
  init_USART( USART0 );
  Read_Instruct(buf);

3/ Wie ist buf definiert?

von Stefan S. (energizer)


Lesenswert?

>Das Programm springt doch nicht an den Anfang zurück, falls ich die
>dazugehörige Interrupt Service Routine nicht ausprogrammiert

Doch, genau das tut es. Also nicht implementierte Interrupt 
deaktivieren.

von Guest (Gast)


Lesenswert?

1/ M103 Fuse ist ausgeschaltet!

2/ Die Funktion init_USART(..) trifft die notwendigen Einstellungen um
   die beiden USART´s zu initialisieren.
   Read_Instruct(..) führt denn über USART eingelesenen Befehl 
(eingegeben im
   Hyperterminal) ausm, sobald die globale Variable flag gesetzt ist.

3/ buf ist definiert als
1
  unsigned char buf[20];

von A. F. (artur-f) Benutzerseite


Lesenswert?

>Doch, genau das tut es. Also nicht implementierte Interrupt
>deaktivieren.
Das ist mir neu, dass man die nicht implementierte Interrupts abschalten 
muss. Stimmt das auch? Ich war der Meinung, dass man alle IR's explizit 
enablen muss. Oder meinst du IR's die man drin hat, aber wo kein Flag 
gelöscht wird? Dann kann ich mir gut vorstellen, dass WTDoggy das 
Programm neu startet.

von Guest (Gast)


Lesenswert?

Aber ich habe den Watchdog doch gar nicht aktiviert!

von Andreas K. (a-k)


Lesenswert?

Guest wrote:

> 2/ Die Funktion init_USART(..) trifft die notwendigen Einstellungen um
>    die beiden USART´s zu initialisieren.

Und schaltet dabei einen Interrupt ein ohne einen passenden Handler zu 
definieren.

von Peter (Gast)


Lesenswert?

Aber die Funkionen init_USART(USART1) und init_USART(USART0) enabeln 
vermutlich die RX + TX Interrupts für die beiden UARTS. Wenn dann dort 
keine Interruptroutine vorhanden sind, die zumindest ein "iret" bewirken 
läuft das Programm wieder in den Start:

MfG Peter

von yalu (Gast)


Lesenswert?

Jetzt schreib ich's halt auch nochmal:  ;-)

Die init_USART-Routine aktiviert wahrscheinlich die jeweiligen
USART-Interrupts. Für alle Interrupts, für die es keinen
benutzerdefinierten Interrupthandler gibt, wird bei der GNU-Toolchain
ein Sprung nach __bad_interrupt in die Interrupttabelle eingetragen.
Und an __bad_interrupt steht ein Sprung zur Adresse 0, was das
Programm ganz von vorne beginnen lässt.

Also: Was hat es mit diesen USART-Routinen auf sich? Handelt es ich um
eine fertige Bibliothek oder um etwas unfertiges selbstgemachtes? Was
gehört sonst noch alles zu dieser USART-Software dazu? Wie gesagt,
wenn die Interrupthandler fehlen, dann startet das Programm beim
Eintreffen eines Interrupts von vorne.

Mit dem Watchdog hat das Ganze übrigens nichts zu tun. Der würde auch
bei nicht aktivierten Interrupts beißen, wenn er aktiv wäre.

von Guest (Gast)


Lesenswert?

Danke für die Antworten. Also es existiert ein Handler für die durch 
init_USART(..) aktivierten Interrupts. Sobald an der RxD Leitung Daten 
anliegen wird ein Interrupt ausgelöst und auch eine dazugehörige Routine 
ausgeführt. Ich habe dann vermutlich die aus Versehen auch noch den 
Interrupt  für TxD enabled.

von Guest (Gast)


Lesenswert?

Leute ich bin beeindruckt! Genau das war es. Woher wisst ihr das mit dem 
_bad_interrupt?

von Andreas B. (buyman)


Lesenswert?

Früher oder später stolpert jeder mal über diesen Fehler (wage ich 
zumindest mal zu behaupten ;-))

von Johannes M. (johnny-m)


Lesenswert?

Guest wrote:
> Leute ich bin beeindruckt! Genau das war es. Woher wisst ihr das mit dem
> _bad_interrupt?
Indem wir die Dokumentation der lib lesen?

von Michael K. (mmike)


Lesenswert?

Da muss ich Andreas K. Recht geben. So hab ichs auch gelernt und dann 
wie Johannes M. schreibt brav nachgelesen ....

Grüße,
Michael

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.