www.mikrocontroller.net

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


Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hab ein Problem mit meinem Code.
int main(){

  init_USART( USART1 );        
  init_USART( USART0 );        

  DDRA = 0xFF;          
  DDRB = 0xFF;
  DDRC = 0xFF;  

  sei();              
  // Enable Global Interrupt verursacht, dass das Programm immer     
  // wieder an den Anfang springt.
  // --> An dieser Stelle springt das Programm dann an den Anfang   
  
    while(1){
         if( flag==1 ){
             Read_Instruct(buf);
             flag=0;
         }                
  }

}

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?

Autor: Andreas B. (buyman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du versehentlich ein Interrupt aktiviert aber nicht 
"ausprogrammiert"?

Von welchem Prozessor reden wir überhaupt?

Autor: Claus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Watchdog ausgeschaltet?

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1/ M103 Fuse nicht ausgeschaltet?
http://www.mikrocontroller.net/articles/AVR_Fuses#...

2/ Was machen

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

3/ Wie ist buf definiert?

Autor: S. Seegel (energizer)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
  unsigned char buf[20];
  

Autor: A. F. (artur-f) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber ich habe den Watchdog doch gar nicht aktiviert!

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Guest (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Guest (Gast)
Datum:

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

Autor: Andreas B. (buyman)
Datum:

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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Michael K. (mmike)
Datum:

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

Grüße,
Michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.