mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega 128 reset bei Interrupt


Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mein Programm hängt sich bei einem interrupt auf und resettet.

ich habe keinen watchdog an.

Ich enable globale interrupts und behandle nur den rxien also beim 
empfang von daten über den UART. mein Code sieht wiefolgt aus:
...
        // Global interrupt enable
        sei();
        sendStringRS232("Global Interrupt enabled\r\n");
...

...

  /**
   * Interrupt handling for the RS232 interface
   */
  ISR (USART_RXC_vect) {
    //sendStringRS232("Interrupt");
    //sendStringRS232((char)askCRS232());
    PORTC = 0xff;
  }
...
  /**
   * This function initializes the uart with the setten baudrate i the header file
   * F_CPU must be set
   * BAUDRATE must be set
   */
  void initRS232(void){
  uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
    UBRR1L = (uint8_t) (ubrr);  // set Baudrate
    UCSR1B |= (1<<RXCIE) | (1<<TXEN) | (1<<RXEN); //TX, RX, RX Interrupt enable
  }


in der mainloop lasse ich leds im sekundentakt blinken, die im interrupt 
alle eingeschaltet werden. Sende ich über das terminal ein Zeichen 
resettet sich der atmega andauernd. Drücke ich dann für eine Weile 
reset, fängt wer sich wieder und blinkt.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil du im Empfangs-Interrupt das Datenregister nicht ausließt.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Sende ich über das terminal ein Zeichen
>resettet sich der atmega andauernd.

Das glaub ich jetzt weniger. Wenn du UDR im Int. nicht
liest, dann feuert der RXC Int. weiter bis du schwarz wirst.

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger schrieb:
>> Sende ich über das terminal ein Zeichen
>>resettet sich der atmega andauernd.
>
> Das glaub ich jetzt weniger. Wenn du UDR im Int. nicht
> liest, dann feuert der RXC Int. weiter bis du schwarz wirst.

das kann ja sein aber warum dann der Reset?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Das glaub ich jetzt weniger. Wenn du UDR im Int. nicht
>> liest, dann feuert der RXC Int. weiter bis du schwarz wirst.

>das kann ja sein aber warum dann der Reset?

Woher soll ich wissen was du in deinem Programm
noch so für Unsinn machst? M103C Fuse abgeschaltet?

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jo klar

hier mal der gesammte code:
/**
 *
 *          Project:    Automatic WIFI Network
 *          Package:    Default
 *
 *
 * File:          Test.c
 * Author:        Soenke Paschko
 * Maintainer:   Soenke Paschko
 *
 * Created on:   21. July 2009, 21:33
 *
 * Content:
 *       A testfile for implementation and testing the drivers
 *
 * Revision history:
 * 21.07.09 1. revision Paschko  -  First version
 * 08.08.08 2. revision Paschko  -   initialization function with start screen
 */


//###################                 Includes                   ###################

   #include "main.h"      // default header file

//###################                 Functions                 ###################

  int main();        // main program
  void SPI_INIT();
  void initiazion();

//###################                 variables                  ###################





  /**
   * The main function
   */
  int main(){

    // initializes all main functions
    initiazion();






    // mainloop
    while(1){
      /*
      txDataWIFI("Hallo\n\r   ", 7);
      _delay_ms(1000);

      sendStringWIFI("Hello here i am");
      _delay_ms(1000);
      sendStringWIFI("\n\n\n");
      _delay_ms(1000);
      */

      /*
      //receiveStringWIFI(string);
      char data[128]="";
      setPowerWIFI(0, 6);      // 1mW Outputforce, 120k
      rxDataWIFI(data);
      //txDataWIFI(data, 128);
      setPowerWIFI(1, 6);      // 1mW Outputforce, 120k

      sendStringRS232(data);
     */

    _delay_ms(500);
    PORTC = 0b00000001;
    _delay_ms(500);
    PORTC = 0b00000010;
    _delay_ms(500);
    PORTC = 0b00000100;
    _delay_ms(500);
    PORTC = 0b00001000;
    _delay_ms(500);
    PORTC = 0b00010000;
    _delay_ms(500);
    PORTC = 0b00100000;
    _delay_ms(500);
    PORTC = 0b01000000;
    _delay_ms(500);
    PORTC = 0b10000000;
    }

    return 0;
  }


  /**
   * This function initializes the SPI Interface (Has to be moved to an other file)
   */
  void SPI_INIT(){
    //Activates the SPI - Bus, Clock = Idel LOW
    //SPI Clock divided by 128, Enable SPI, SPI in Master Mode
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
    SPSR &= ~(0<<SPI2X);
  }


  /**
   * This function makes a basic initialization
   */
  void initiazion(){

    // port initialization
        DDRA = 0xFF;      // LED
        DDRB = 0b01000111;  // Encoder / WIFI module
      DDRC = 0xFF;
        DDRD = 0xFF;       // PORT D Output
      DDRE = 0xFF;       // PORT D Output



        beep_short();      // To show that the module is online

        // USART initialization
        initRS232();

        // USART output
        sendStringRS232("\x1B[2J \x1B[0;0f");   /* clear screen and cursor home  */

      // output UART welcome screen
        sendStringRS232("\a\r\n\r\n\r\n");
        sendStringRS232("            \x1B[41m*****************************\r\n\x1B[47m"); // \x1B[47m setzt den Hintergrund auf grau
        sendStringRS232("            \x1B[41m***     "  PROGNAME  "    ***\r\n\x1B[47m");
        sendStringRS232("            \x1B[41m***       "VERSION"       ***\r\n\x1B[47m");
        sendStringRS232("            \x1B[41m***                       ***\r\n\x1B[47m");
        sendStringRS232("            \x1B[41m***                       ***\r\n\x1B[47m");
        sendStringRS232("            \x1B[41m*****************************\r\n\r\n\x1B[47m");


        sendStringRS232("UART init successful\r\n");


        // LC Display basic initialization
        initLCD();
        sendStringRS232("LCD init successful\r\n");


      // Welcome screen LCD
        clearLCD();
        setCursorLCD(0,1);
        sendStringLCD(" "  PROGNAME  "    ***");
        setCursorLCD(0,2);
        sendStringLCD("    "VERSION"       ***");




        // SPI init
        SPI_INIT();
        sendStringRS232("SPI init successful\r\n");


        // WIFI init
        initialiseWIFI(RF12FREQ(433.92),9600);
        setBandwidthWIFI(5, 1, 4);    // 200kHz bandwidth, -6dB gain, DRSSI threshold: -79dBm
        setPowerWIFI(0, 6);        // 1mW output force, 120k
        sendStringRS232("RFM12 init successful\r\n");


        _delay_ms(1000);
        txDataWIFI("Hallo\n\r   ", 7);
        //_delay_ms(1000);

        // Global interrupt enable
        sei();
        sendStringRS232("Global Interrupt enabled\r\n");

        //initialisazion of the event queue
        initEventQueue();
        sendStringRS232("EventQueue init successful\r\n");

        beep_short();


  }

 



/**
 *
 *          Project:    Automatic WIFI Network
 *          Package:    UART
 *
 *
 * File:          Test.c
 * Author:        Soenke Paschko
 * Maintainer:   Soenke Paschko
 *
 * Created on:   26. July 2009, 14:09
 *
 * Content:
 *       Here are the driver functionality of the uart
 *
 * Revision history:
 * 26.07.09 1. revision Paschko  -  First version
 */

//##################################################################################

//###################                 Includes                   ###################

    #include "../main.h"      // Main head file
  #include "uart.h"

//###################                 Functions                   ###################

  void initRS232();
  void sendStringRS232(char *s);
  //static uint8_t askCRS232();
  //static uint8_t getCRS232();


//###################                 variables                  ###################


  /**
   * This function initializes the uart with the setten baudrate i the header file
   * F_CPU must be set
   * BAUDRATE must be set
   */
  void initRS232(void){
  uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
    UBRR1L = (uint8_t) (ubrr);  // set Baudrate
    UCSR1B |= (1<<RXCIE) | (1<<TXEN) | (1<<RXEN); //TX, RX, RX Interrupt enable
  }


  /**  PROTECTED
   * This function sends a data word to the UART
   */
  static void sendRS232( unsigned char data ){

  // wait for empty buffer
  while ( !( UCSR1A & (1<<UDRE1)) );
  // send data to the buffer
   UDR1 = data;

  }


  /**  PROTECTED
   * This function waits for a character
   * Attention!! this function will block everything else if no character comes
   */
   /*
  static uint8_t getCRS232(void){

    while (!(UCSR1A & (1<<RXC1)));
    return UDR1;                   // return the character from UDR to the caller
  }*/


  /**
   * This function looks for a character without waiting
   */

  uint8_t askCRS232(void){
  UDR1=0;
    UCSR1A & (1<<RXC1);
    return UDR1;                   // return the character from UDR to the caller
  }



  /**
   * This function sends a string to the UART
   */
  void sendStringRS232(char *s){

    while (*s){   // sends until s is 0
        sendRS232(*s);
        s++;
    }
  }






/**
 *
 *          Project:    Automatic WIFI Network
 *          Package:    EventQueue
 *
 *
 * File:          TerminalFunctionality.h
 * Author:        Soenke Paschko
 * Maintainer:   Soenke Paschko
 *
 * Created on:   06. September 2009, 16:49
 *
 * Content:
 * Functionality for the terminal and the terminal history
 *
 *
 * Revision history:
 * 06.09.09 1. revision Paschko  -  First version
 */

//##################################################################################

//###################                 Includes                   ###################

    #include "../main.h"      // Main head file
  #include "uart.h"

//###################                 Functions                   ###################




//###################                 variables                  ###################

  /**
   * Interrupt handling for the RS232 interface
   */
  ISR (USART_RXC_vect) {
    //sendStringRS232("Interrupt");
    sendStringRS232(UDR1);
    PORTC = 0xff;
  }




die restlichen funktionen für RFM12 und LCD sind nicht relevant,da hier 
keine Interrupts behandelt werden.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> das kann ja sein aber warum dann der Reset?

Da Du den µC nicht verraten hast, also mal in den includes gesucht.
Die USART_RXC_vect gibt's für den M8, M16, M32 & M323.

Keine dieser includes kennt das UCSR1B Register, also muss es wohl ein 
anderer µC sein. Da der dann wieder Deine USART_RXC_vect ISR nicht 
kennt, ist die eigentliche RX ISR für den nicht vorhanden und damit 
geht's ab in's Nirvana.

Keine Warnung vom Compiler bekommen ?

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich tipp mal auf USART1_RX_vect :D

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke das wars

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich tipp mal auf USART1_RX_vect :D

Nicht schlecht für die Uhrzeit ;)

Aber noch was ganz übles:
  ISR (USART_RXC_vect) {
    //sendStringRS232("Interrupt");
    sendStringRS232(UDR1);
    PORTC = 0xff;
  }

Nimm das sendString...() da raus.
Man ruft Funktionen nicht ungestraft
in ISRs und im Hauptprogramm auf.

Und was ist das?
  uint8_t askCRS232(void){
  UDR1=0;
    UCSR1A & (1<<RXC1);
    return UDR1;                 // return the character from UDR to the caller
  }


Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
altlasten
das mit dem funktionsaufruf kommt noch weg, war ja nur erstmal nen debug 
test

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sönke Paschko schrieb:
> altlasten
> das mit dem funktionsaufruf kommt noch weg, war ja nur erstmal nen debug
> test

Ist aber trotzdem Quatsch.
UDR1 ist bestenfalls vom Datentyp char. sendStringRS232 will aber einen 
String. Ooops.
Gabs da keine Warnung vom Compiler? Irgendwas, dass die Datentypen nicht 
passen? Immerhin versuchst du einer Funktion, die einen Pointer haben 
will einen einzelnen char unterzujubeln.

Mir scheint, du misst den Warnungen deines Compilers keine rechte 
Bedeutung bei. Lass dir gesagt sein, dass in vielen Firmen die Maxime 
gilt: Code muss in einem der höheren Waninglevels (falls es so etwas 
gibt) absolut ohne jeglichen Kommentar des Compilers compilieren. Keine 
Warnungen erlaubt!
Und diese Firmen haben guten Grund für diese Direktive!

Autor: Sonke A. (soeni)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie gesagt, das stimmt am ende müssen tool wie lint keine fehler melden 
aber mal ebend um einen anderen fehler auszuschließen ist mir das egal. 
ich verstehe auch nicht den entwickler, der nur mal ebend zur 
debugzwecken ein programm schreibt, welches ohne jegliches mucken eines 
speziellen diagnosetools arbeitet nur um schnell mal was zu testen, was 
keinerlei relevanz für das spätere programm hat.

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@sönke:
lol

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sönke Paschko schrieb:

> debugzwecken ein programm schreibt, welches ohne jegliches mucken eines
> speziellen diagnosetools arbeitet nur um schnell mal was zu testen, was
> keinerlei relevanz für das spätere programm hat.

Woher weißt du, ob die Warnung relevant ist oder nicht? Du hättest dir, 
ja nachdem was die Funktion macht, ja auch den Stack komplett 
zerschiessen können, was dann unter Umständen auch zu einem Neustart des 
Programms führen könnte.

Nur so als Nachdenkhilfe: Was du da gemacht hast, würde auf einem PC 
ziemlich sicher zum sofortigen Crash des Programms führen. Du hättest 
eine 'access violation'. Lediglich die Tatsache, dass auf einem AVR kein 
Betriebssystem läuft und die Hardware keine Möglichkeit hat, deine 
Speicherzugriffe zu überwachen, hat dich vor diesem Schicksal bewahrt.

Ganz abgesehen davon, wenn jemand versucht einen char in eine Funktion 
reinzustopfen, die einen Pointer haben will UND die Warnung des 
Compilers auch noch ignoriert, denke ich mir meinen Teil über seine 
Programmierfähigkeiten. Sowas passiert schon mal beim schnellen tippen 
aber spätestens nach dem ersten Compilerlauf ist der Code geändert.

(Und wenn ich ein Testprogramm sehe, bei dem anscheinend das Wichtigste 
der Programmheader und die Begrüßungsmaske ist, denke ich mir auch 
meinen Teil)

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.