Forum: Mikrocontroller und Digitale Elektronik Atmega 128 reset bei Interrupt


von Sonke A. (soeni)


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:
1
...
2
        // Global interrupt enable
3
        sei();
4
        sendStringRS232("Global Interrupt enabled\r\n");
5
...
6
7
...
8
9
  /**
10
   * Interrupt handling for the RS232 interface
11
   */
12
  ISR (USART_RXC_vect) {
13
    //sendStringRS232("Interrupt");
14
    //sendStringRS232((char)askCRS232());
15
    PORTC = 0xff;
16
  }
17
...
18
  /**
19
   * This function initializes the uart with the setten baudrate i the header file
20
   * F_CPU must be set
21
   * BAUDRATE must be set
22
   */
23
  void initRS232(void){
24
  uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
25
    UBRR1L = (uint8_t) (ubrr);  // set Baudrate
26
    UCSR1B |= (1<<RXCIE) | (1<<TXEN) | (1<<RXEN); //TX, RX, RX Interrupt enable
27
  }


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.

von Stefan E. (sternst)


Lesenswert?

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

von holger (Gast)


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.

von Sonke A. (soeni)


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?

von holger (Gast)


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?

von Sonke A. (soeni)


Lesenswert?

jo klar

hier mal der gesammte code:
1
/**
2
 *
3
 *          Project:    Automatic WIFI Network
4
 *          Package:    Default
5
 *
6
 *
7
 * File:          Test.c
8
 * Author:        Soenke Paschko
9
 * Maintainer:   Soenke Paschko
10
 *
11
 * Created on:   21. July 2009, 21:33
12
 *
13
 * Content:
14
 *       A testfile for implementation and testing the drivers
15
 *
16
 * Revision history:
17
 * 21.07.09 1. revision Paschko  -  First version
18
 * 08.08.08 2. revision Paschko  -   initialization function with start screen
19
 */
20
21
22
//###################                 Includes                   ###################
23
24
   #include "main.h"      // default header file
25
26
//###################                 Functions                 ###################
27
28
  int main();        // main program
29
  void SPI_INIT();
30
  void initiazion();
31
32
//###################                 variables                  ###################
33
34
35
36
37
38
  /**
39
   * The main function
40
   */
41
  int main(){
42
43
    // initializes all main functions
44
    initiazion();
45
46
47
48
49
50
51
    // mainloop
52
    while(1){
53
      /*
54
      txDataWIFI("Hallo\n\r   ", 7);
55
      _delay_ms(1000);
56
57
      sendStringWIFI("Hello here i am");
58
      _delay_ms(1000);
59
      sendStringWIFI("\n\n\n");
60
      _delay_ms(1000);
61
      */
62
63
      /*
64
      //receiveStringWIFI(string);
65
      char data[128]="";
66
      setPowerWIFI(0, 6);      // 1mW Outputforce, 120k
67
      rxDataWIFI(data);
68
      //txDataWIFI(data, 128);
69
      setPowerWIFI(1, 6);      // 1mW Outputforce, 120k
70
71
      sendStringRS232(data);
72
     */
73
74
    _delay_ms(500);
75
    PORTC = 0b00000001;
76
    _delay_ms(500);
77
    PORTC = 0b00000010;
78
    _delay_ms(500);
79
    PORTC = 0b00000100;
80
    _delay_ms(500);
81
    PORTC = 0b00001000;
82
    _delay_ms(500);
83
    PORTC = 0b00010000;
84
    _delay_ms(500);
85
    PORTC = 0b00100000;
86
    _delay_ms(500);
87
    PORTC = 0b01000000;
88
    _delay_ms(500);
89
    PORTC = 0b10000000;
90
    }
91
92
    return 0;
93
  }
94
95
96
  /**
97
   * This function initializes the SPI Interface (Has to be moved to an other file)
98
   */
99
  void SPI_INIT(){
100
    //Activates the SPI - Bus, Clock = Idel LOW
101
    //SPI Clock divided by 128, Enable SPI, SPI in Master Mode
102
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
103
    SPSR &= ~(0<<SPI2X);
104
  }
105
106
107
  /**
108
   * This function makes a basic initialization
109
   */
110
  void initiazion(){
111
112
    // port initialization
113
        DDRA = 0xFF;      // LED
114
        DDRB = 0b01000111;  // Encoder / WIFI module
115
      DDRC = 0xFF;
116
        DDRD = 0xFF;       // PORT D Output
117
      DDRE = 0xFF;       // PORT D Output
118
119
120
121
        beep_short();      // To show that the module is online
122
123
        // USART initialization
124
        initRS232();
125
126
        // USART output
127
        sendStringRS232("\x1B[2J \x1B[0;0f");   /* clear screen and cursor home  */
128
129
      // output UART welcome screen
130
        sendStringRS232("\a\r\n\r\n\r\n");
131
        sendStringRS232("            \x1B[41m*****************************\r\n\x1B[47m"); // \x1B[47m setzt den Hintergrund auf grau
132
        sendStringRS232("            \x1B[41m***     "  PROGNAME  "    ***\r\n\x1B[47m");
133
        sendStringRS232("            \x1B[41m***       "VERSION"       ***\r\n\x1B[47m");
134
        sendStringRS232("            \x1B[41m***                       ***\r\n\x1B[47m");
135
        sendStringRS232("            \x1B[41m***                       ***\r\n\x1B[47m");
136
        sendStringRS232("            \x1B[41m*****************************\r\n\r\n\x1B[47m");
137
138
139
        sendStringRS232("UART init successful\r\n");
140
141
142
        // LC Display basic initialization
143
        initLCD();
144
        sendStringRS232("LCD init successful\r\n");
145
146
147
      // Welcome screen LCD
148
        clearLCD();
149
        setCursorLCD(0,1);
150
        sendStringLCD(" "  PROGNAME  "    ***");
151
        setCursorLCD(0,2);
152
        sendStringLCD("    "VERSION"       ***");
153
154
155
156
157
        // SPI init
158
        SPI_INIT();
159
        sendStringRS232("SPI init successful\r\n");
160
161
162
        // WIFI init
163
        initialiseWIFI(RF12FREQ(433.92),9600);
164
        setBandwidthWIFI(5, 1, 4);    // 200kHz bandwidth, -6dB gain, DRSSI threshold: -79dBm
165
        setPowerWIFI(0, 6);        // 1mW output force, 120k
166
        sendStringRS232("RFM12 init successful\r\n");
167
168
169
        _delay_ms(1000);
170
        txDataWIFI("Hallo\n\r   ", 7);
171
        //_delay_ms(1000);
172
173
        // Global interrupt enable
174
        sei();
175
        sendStringRS232("Global Interrupt enabled\r\n");
176
177
        //initialisazion of the event queue
178
        initEventQueue();
179
        sendStringRS232("EventQueue init successful\r\n");
180
181
        beep_short();
182
183
184
  }
1
/**
2
 *
3
 *          Project:    Automatic WIFI Network
4
 *          Package:    UART
5
 *
6
 *
7
 * File:          Test.c
8
 * Author:        Soenke Paschko
9
 * Maintainer:   Soenke Paschko
10
 *
11
 * Created on:   26. July 2009, 14:09
12
 *
13
 * Content:
14
 *       Here are the driver functionality of the uart
15
 *
16
 * Revision history:
17
 * 26.07.09 1. revision Paschko  -  First version
18
 */
19
20
//##################################################################################
21
22
//###################                 Includes                   ###################
23
24
    #include "../main.h"      // Main head file
25
  #include "uart.h"
26
27
//###################                 Functions                   ###################
28
29
  void initRS232();
30
  void sendStringRS232(char *s);
31
  //static uint8_t askCRS232();
32
  //static uint8_t getCRS232();
33
34
35
//###################                 variables                  ###################
36
37
38
  /**
39
   * This function initializes the uart with the setten baudrate i the header file
40
   * F_CPU must be set
41
   * BAUDRATE must be set
42
   */
43
  void initRS232(void){
44
  uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BAUDRATE) - 1);
45
    UBRR1L = (uint8_t) (ubrr);  // set Baudrate
46
    UCSR1B |= (1<<RXCIE) | (1<<TXEN) | (1<<RXEN); //TX, RX, RX Interrupt enable
47
  }
48
49
50
  /**  PROTECTED
51
   * This function sends a data word to the UART
52
   */
53
  static void sendRS232( unsigned char data ){
54
55
  // wait for empty buffer
56
  while ( !( UCSR1A & (1<<UDRE1)) );
57
  // send data to the buffer
58
   UDR1 = data;
59
60
  }
61
62
63
  /**  PROTECTED
64
   * This function waits for a character
65
   * Attention!! this function will block everything else if no character comes
66
   */
67
   /*
68
  static uint8_t getCRS232(void){
69
70
    while (!(UCSR1A & (1<<RXC1)));
71
    return UDR1;                   // return the character from UDR to the caller
72
  }*/
73
74
75
  /**
76
   * This function looks for a character without waiting
77
   */
78
79
  uint8_t askCRS232(void){
80
  UDR1=0;
81
    UCSR1A & (1<<RXC1);
82
    return UDR1;                   // return the character from UDR to the caller
83
  }
84
85
86
87
  /**
88
   * This function sends a string to the UART
89
   */
90
  void sendStringRS232(char *s){
91
92
    while (*s){   // sends until s is 0
93
        sendRS232(*s);
94
        s++;
95
    }
96
  }
1
/**
2
 *
3
 *          Project:    Automatic WIFI Network
4
 *          Package:    EventQueue
5
 *
6
 *
7
 * File:          TerminalFunctionality.h
8
 * Author:        Soenke Paschko
9
 * Maintainer:   Soenke Paschko
10
 *
11
 * Created on:   06. September 2009, 16:49
12
 *
13
 * Content:
14
 * Functionality for the terminal and the terminal history
15
 *
16
 *
17
 * Revision history:
18
 * 06.09.09 1. revision Paschko  -  First version
19
 */
20
21
//##################################################################################
22
23
//###################                 Includes                   ###################
24
25
    #include "../main.h"      // Main head file
26
  #include "uart.h"
27
28
//###################                 Functions                   ###################
29
30
31
32
33
//###################                 variables                  ###################
34
35
  /**
36
   * Interrupt handling for the RS232 interface
37
   */
38
  ISR (USART_RXC_vect) {
39
    //sendStringRS232("Interrupt");
40
    sendStringRS232(UDR1);
41
    PORTC = 0xff;
42
  }


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

von MWS (Gast)


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 ?

von MWS (Gast)


Lesenswert?

Ich tipp mal auf USART1_RX_vect :D

von Sonke A. (soeni)


Lesenswert?

danke das wars

von holger (Gast)


Lesenswert?

>Ich tipp mal auf USART1_RX_vect :D

Nicht schlecht für die Uhrzeit ;)

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

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

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

von Sonke A. (soeni)


Lesenswert?

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

von Karl H. (kbuchegg)


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!

von Sonke A. (soeni)


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.

von Jean P. (fubu1000)


Lesenswert?

@sönke:
lol

von Karl H. (kbuchegg)


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)

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.