Forum: Mikrocontroller und Digitale Elektronik Atmega48 - UART als Interrupt


von Julian W. (julian-w) Benutzerseite


Lesenswert?

Hallo,
ich verzweifle gerade... ich kriege einfach nicht die UART beim Atmega48 
zum laufen... :( Hier mal mein Code:
1
int main(void)
2
{
3
    InitIO();
4
    InitUART();
5
    sei();
6
7
    while(1){};
8
9
    [...]
10
}
11
12
[...]
13
14
void InitUART()
15
{
16
    LightOn(LED_READY);
17
18
    #ifndef  UART_BAUD
19
    #define  UART_BAUD    9600UL
20
    #endif
21
22
    #ifndef  F_CPU
23
    #define  F_CPU    16000000UL
24
    #endif
25
26
    #define  UART_UBRR    ( ( ( F_CPU / 16 ) / UART_BAUD ) - 1 )
27
28
    UBRR0H = ( unsigned char )( UART_UBRR >> 8 );
29
    UBRR0L = ( unsigned char )UART_UBRR;
30
31
    UCSR0B = ( _BV( RXCIE0 ) | _BV( RXEN0 ) | _BV( TXEN0 ) );
32
    UCSR0C = ( _BV( USBS0 ) | _BV( UCSZ01 ) | _BV( UCSZ00 ) ); // 8N2
33
34
    LightOn(LED_ERROR);
35
}
36
37
ISR(USART_RX0_vect )
38
{
39
    uint8_t tmp = UDR0;
40
    LightOn(LED_RESET);
41
}

Die Funktion LightOn() schaltet einfach nur simple LEDs an und aus, die 
funktioniert auch tadelos. Nur sobald jetzt ein Zeichen empfangen wird 
passiert nichts und der Atmega48 stürzt einfach ab!? (Hatte noch eine 
TLC5940 ansteuerung im Hintergrund die Interrupt-Basiert ist und die 
funktionierte nach dem Senden eines Zeichens nicht mehr)

Könnt irh einen Fehler finden? Ich weiß einfach nicht mehr weiter bei 
sowas simplen...

Viele Grüße
Julian

von Thomas E. (thomase)


Lesenswert?

Julian W. schrieb:
> ISR(USART_RX0_vect )
Der Vektor heisst USART_RX_vect. Compilerwarnungen beachten!

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Julian W. schrieb:

> funktioniert auch tadelos. Nur sobald jetzt ein Zeichen empfangen wird
> passiert nichts und der Atmega48 stürzt einfach ab!?

Wenn Interrupts im Spiel sind und der µC bei Auftreten eines INterrupts 
abschmiert, dann stimmt meistens der Name der ISR nicht.
D.h. da wurde an den Interrupt KEINE ISR gebunden. Und sobald dieser 
Fall eintritt, tritt der Default-Handler auf die Bühne, welcher .... den 
µC resettet.

Also: Überprüf den Namen deiner ISR

von Julian W. (julian-w) Benutzerseite


Lesenswert?

Okay, hab ich mal geändert... aber darüber hat der Compiler eigetnlich 
nie gemekert.
Einzigst was noch immer kommt:

main.c|67|warning: control reaches end of non-void function|

von Karl H. (kbuchegg)


Lesenswert?

Julian W. schrieb:
> Okay, hab ich mal geändert... aber darüber hat der Compiler eigetnlich
> nie gemekert.
> Einzigst was noch immer kommt:
>
> main.c|67|warning: control reaches end of non-void function|

Schön.
UNd welches ist die Zeile 67?

von Julian W. (julian-w) Benutzerseite


Lesenswert?

Das hier:
1
ISR(USART_RX_vect)
2
{
3
    uint8_t tmp = UDR0;
4
    LightOn(LED_RESET);
5
}

von Cyblord -. (cyblord)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Julian W. schrieb:
>> Okay, hab ich mal geändert... aber darüber hat der Compiler eigetnlich
>> nie gemekert.
>> Einzigst was noch immer kommt:
>>
>> main.c|67|warning: control reaches end of non-void function|
>
> Schön.
> UNd welches ist die Zeile 67?

Das Ende der main wahrscheinlich. Die sollte int zurückgeben. Macht er 
aber nicht. Macht wohl nur return; oder gar nix.
Ist aber auch für das Problem hier nicht relevant.

gruß cyblord

von Thomas E. (thomase)


Lesenswert?

../usart0.c:119:1: warning: 'USART_RX0_vect' appears to be a misspelled 
signal handler

Julian W. schrieb:
> aber darüber hat der Compiler eigetnlich nie gemekert.
Wie dem auch sei.

Karl Heinz Buchegger schrieb:
> Schön. UNd welches ist die Zeile 67?
Mach doch mal die Augen auf:

Julian W. schrieb:
> [...]

Julian W. schrieb:
> control reaches end of non-void function
Da wurde der "Point of no return" erreicht.

cyblord ---- schrieb:
> Ist aber auch für das Problem hier nicht relevant.
Ist dem GCC aber auch egal.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Julian W. schrieb:
> Das hier:
>
>
1
> ISR(USART_RX_vect)
2
> {
3
>     uint8_t tmp = UDR0;
4
>     LightOn(LED_RESET);
5
> }
6
>

Womit wir wieder beim Punkt angelangt sind, dass der Name der ISR immer 
noch nicht stimmt.

Da ist deine Warnung, dass der Name nicht stimmt, denn eine ISR ist 
definitiv eine void Funktion.
Wenn der Compiler das nicht erkannt hat und auswirft
Control reaches end of non-void function
dann bedeutet das, dass er das als int Funktion ansieht. Woraus man 
schliessen kann, dass er das nicht als ISR anerkennt

von Karl H. (kbuchegg)


Lesenswert?

cyblord ---- schrieb:
> Karl Heinz Buchegger schrieb:
>> Julian W. schrieb:
>>> Okay, hab ich mal geändert... aber darüber hat der Compiler eigetnlich
>>> nie gemekert.
>>> Einzigst was noch immer kommt:
>>>
>>> main.c|67|warning: control reaches end of non-void function|
>>
>> Schön.
>> UNd welches ist die Zeile 67?
>
> Das Ende der main wahrscheinlich. Die sollte int zurückgeben. Macht er
> aber nicht.

Muss er auch nicht.

Für main() gibt es eine Ausnahme :-)
main ist zwar eine int Funktion, aber wenn der Code selbst kein return 
enthält, muss sich der COmpiler ein
   return EXIT_SUCCESS;
dazudenken.

Frag mich nicht ....

von Julian W. (julian-w) Benutzerseite


Angehängte Dateien:

Lesenswert?

ich weiß einfach nicht mehr weiter... hier der komplette Code fals es 
weiter hilft.

Hab das UART Signal mir mal mit dem Oszi angeschaut, das passt aber :(

von Thomas E. (thomase)


Lesenswert?

Karl Heinz Buchegger schrieb:
>> ISR(USART_RX_vect)
Doch. Die stimmt jetzt.
Aber "LightOn(LED_RESET);" befindet sich noch immer zwischen den ersten 
beiden Punkten: [...]

mfg.

von Julian W. (julian-w) Benutzerseite


Lesenswert?

Thomas Eckmann schrieb:
> Aber "LightOn(LED_RESET);" befindet sich noch immer zwischen den ersten
> beiden Punkten: [...]

LightOn ist in der io.c und sieht wie folgt aus:
1
void LightOn(uint8_t led)
2
{
3
    PORTD &= ~(1<<led);
4
}

von Julian W. (julian-w) Benutzerseite


Lesenswert?

Waaahhhh... ich hab es....

es fehlte einfach nur
1
#include <avr/interrupt.h>

in der uart.h -.- Naja da war ich wohl sehr Betriebsbilnd. Doof das der 
Compiler nicht meckert.

Danke für die vielen und schnellen Antworten ;)

von Karl H. (kbuchegg)


Lesenswert?

Thomas Eckmann schrieb:
> Karl Heinz Buchegger schrieb:
>>> ISR(USART_RX_vect)
> Doch. Die stimmt jetzt.
> Aber "LightOn(LED_RESET);" befindet sich noch immer zwischen den ersten
> beiden Punkten: [...]

Ich versteh nicht.

Die Fehlermeldung ist nicht typisch dafür.

von Karl H. (kbuchegg)


Lesenswert?

Julian W. schrieb:
> Waaahhhh... ich hab es....
>
> es fehlte einfach nur
>
1
> #include <avr/interrupt.h>
2
>
>
> in der uart.h -.- Naja da war ich wohl sehr Betriebsbilnd. Doof das der
> Compiler nicht meckert.

Hat er doch :-)

Für den Compiler war das hier
1
ISR( UART_RXC_vect )
2
{
3
}

eine ganz normale C-Funktion.

OK. Der Compiler musste seinen Freiraum komplett ausnutzen, um daraus 
etwas Sinnvolles zu machen - in dem er alle unbekannten Datentypen als 
int annahm, aber ... das darf er.
Für ihn stand da
1
int ISR( int UART_RXC_vect )
2
{
3
  ...
4
}

und: diese Funktion hat keinen return, obwohl sie eine int-Funktion ist. 
UNd das hat er dir freundlicherweise mitgeteilt.

Erst durch den #include wurde dann aus "ISR" etwas ganz anders.

von Thomas E. (thomase)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Die Fehlermeldung ist nicht typisch dafür.
Doch wäre sie, wenn die Funktion nicht void wäre. Daß sie das ist, habe 
ich erst nachher gesehen.

Julian W. schrieb:
> es fehlte einfach nur#include <avr/interrupt.h>
Aber das erklärt den Fehler.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Thomas Eckmann schrieb:
> Karl Heinz Buchegger schrieb:
>> Die Fehlermeldung ist nicht typisch dafür.
> Doch wäre sie, wenn die Funktion nicht void wäre. Daß sie das ist, habe
> ich erst nachher gesehen.

Ich hab dich immer noch nicht.
Die Fehlermeldung

control reaches end of non-void function|

an dieser Stelle
1
ISR(USART_RX_vect)
2
{
3
     uint8_t tmp = UDR0;
4
     LightOn(LED_RESET);
5
}     // <--------------

hat nichts mit der Funktion LightOn zu tun.

Aber egal.

von Thomas E. (thomase)


Lesenswert?

Karl Heinz Buchegger schrieb:
> hat nichts mit der Funktion LightOn zu tun.
Der Fehler kam ja auch daher, daß der Compiler nicht wusste, was eine 
ISR ist. Deswegen gab es auch keine Warnung wegen dem misspelled 
handler.

Da ich aber weiß, was das ist, bin ich davon ausgegangen, daß dem 
Compiler das auch mitgeteilt wurde. Somit blieb aus der ISR heraus als 
nächste Funktion, die nichts zurück gibt die LightOn(...

Das ist eben das Resultat, wenn man aus Codefetzen, bei denen alles 
weggelassen wurde, woran es garantiert nicht liegt, versucht, sich etwas 
zusammen zu reimen.

mfg.

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.