Programm springt immer wieder an den Anfang zurück

Gast #959753
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?
Gast #959780
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.
Gast #959828
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];
Persönliche Seite #959831
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.
Gast #959853
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
Gast #959866
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.
Gast #959882
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren