Forum: Compiler & IDEs USART1 RX Interrupt atmega 1284p


von Lukas (Gast)


Lesenswert?

Hallo Leute,
ich bekomm meine zweite UART auf einem atmega 1284P einfach nicht mit 
Empfangsinterrupt zum laufen. Die "Uart enabled!" Meldung und die Punkte 
alle 100ms bekomme ich, aber immer wenn ich das RXCIE Flag setze hängt 
sich der uC beim ersten empfangenen Zeichen auf.
Ich hab im Manual gelesen, dass der Interrupt so lange feuert bis das 
RXC1 Flag gelöscht wird, aber das sollte ja in der ISR mit nextChar = 
UDR1 automatisch passieren, oder hab ich das missverstanden?
Hab auch versucht ISRs für sämtliche Vektoren zu definieren, falls da 
was im avr header faul ist, nutzt aber auch nix. Hat jemand einen Tipp? 
Überseh ich was?
Danke, Lukas

avr-gcc-4.3.5
avr-libc_1.6.8-2

1
#include <util/delay.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
5
#ifndef F_CPU
6
#define F_CPU       20000000UL
7
#endif
8
9
#define BAUD    9600
10
#define bauddivider  (unsigned char)(1.0 * F_CPU / BAUD / 16 - 0.5)
11
12
unsigned char nextChar = '.';
13
14
void u1putchar( char c )
15
{
16
  while( !(UCSR1A & (1<<UDRE1)));
17
  UDR1 = c;
18
}
19
20
21
void u1puts( char *s )
22
{
23
  while( *s )
24
    u1putchar( *s++ );
25
}
26
27
ISR(_VECTOR(28))
28
{
29
  nextChar = UDR1;
30
}
31
32
int main( void )
33
{
34
    UBRR1 = bauddivider;
35
    UCSR1B |= _BV( TXEN1 ) | _BV( RXEN1 ) | _BV( RXCIE1 ); // enable TX, RX and Receive Interrupt
36
    sei();
37
     u1puts("Uart enabled!\n");
38
     for(;;) {
39
         if (nextChar != '.'){
40
            u1putchar(nextChar);
41
            nextChar='.';
42
         } else {
43
            u1putchar(nextChar);
44
         }
45
         _delay_ms(100);
46
     }
47
48
    return 0;
49
}

von Krapao (Gast)


Lesenswert?

Aus Sicht des Compilers ändert sich nextchar in main() nicht daher wurde 
der != Fall komplett wegoptimiert und der == Fall effektiv durch 
u1putchar('.'); ersetzt.

>>> Abhilfe:
volatile unsigned char nextChar = '.';
Hintergrund: Interrupt

von Lukas (Gast)


Lesenswert?

darauf bin ich auch gerade gekommen, aber das ändert's leider nicht, und 
erklärt auch nicht, wieso nach dem ersten empfangenen zeichen keine 
punkte mehr gesendet werden...
hab auch versucht mit einem Beinchen zu wackeln in der ISR, aber da 
scheint er gar nicht reinzuspringen...

von Krapao (Gast)


Lesenswert?

Das ist nur eine Vermutung. Das kannst du aber im Disassembler 
überprüfen, wenn du dir den erzeugten Assemblercode für main() ansiehst.

von Krapao (Gast)


Lesenswert?

Hast du schon im Disassembler nachgesehen, ob die ISR tatsächlich am 
richtigen Punkt in der IRQ-Vektortabelle eingetragen ist?

von Lukas (Gast)


Lesenswert?

danke für den tipp, ich werd mal reinsehen, hab zwar keine ASM 
kenntnisse, aber vielleicht erkenn ich's ja. worann könnte das liegen, 
dass er nicht in die ISR springt sondern sich lieber verabschiedet?

von Krapao (Gast)


Lesenswert?

Check auch die Projekteinstellungen - nicht dass du dort aus versehen 
statt Atmega1284P den Atmega1281 oder den Atmega128 eingetragen hast. 
Alle drei haben den UART1-RX Vektor an einer anderen Tabellenposition.

von Lukas (Gast)


Lesenswert?

Ich verwende deshalb _VECTOR(28) statt der defines, die nummer kommt aus 
dem Datenblatt. Das iom1284p.h file hab ich auch angesehen, aber die 
Interruptvektoren scheinen richtig definiert zu sein...

Als compiler option hab ich -mmcu=atmega1284p, das sollte doch dann 
passen oder?
hab avrdisas installiert (linux) und versuch grade zu disassemblen...
danke für die schnelle Hilfe...

von Lukas (Gast)


Lesenswert?

Oh mann bin ich blöd, hattest doch recht, ich habe zwar in den general 
options -mmcu=atmega1284p, aber im "Release" target einen anderen...
verdammt. Jetzt gehts.
Danke, da hätte ich noch lang gesucht!

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.