Atmega 162 - UART/Interrupt geht nicht

#1130203
Lesenswert?

Hi :)
Ich versuche mit dem Atmega 162 einen String über UART zu empfangen.
Zurzeit löst aber nichtmal der Interrupt aus.Sitze schon seit 3Tagen 
dran und finde den Fehler einfach nicht.Hab im Forum leider nichts 
gefunden,was mir helfen würde und das UART Tutorial hab ich auch schon 
gelesen.
Hättet ihr vlt eine Idee woran es liegen könnte?

UART Initialisierung
1
void initusart1(void)
2
{
3
unsigned char x;
4
#ifdef UBRR1L
5
  UBRR1L = (TAKT / (16ul * BAUD))-1;
6
  UCSR1B |=(1<<TXEN1)|(1<<RXEN1);
7
  UCSR1C |=(1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10);
8
#else
9
  UBRR = (TAKT / (16 * BAUD))-1;
10
  UCR |=(1<<TXEN)|(1<<RXEN);
11
#endif
12
  x=UDR1;
13
}

UART empfangen
1
unsigned char empf1 (void)
2
{
3
#ifdef UCSR1A
4
  while(!(UCSR1A & (1<<RXC1)));
5
#else
6
  while(!(USR & (1<<RXC)));
7
#endif
8
return UDR1;}

Interrupt
1
#include <stdlib.h>
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <string.h>
5
#define TAKT 8000000UL 
6
#define BAUD 9600UL  
7

8

9
ISR(SIG_USART1_RECV){  //habs auch schon mit ISR(USART1_RXC_vect)  versucht          
10

11
cli();
12
          
13
strcpy (test,"test");
14

15
sei();
16
}

Main
1
int main(void)
2
{
3

4
DDRB = 0x00;
5
initusart1();    // UART initialisieren  
6
UCSR1B |= (1<<RXCIE1);  //Interrupt freigeben UART1
7
sei();      //Interrupt freigeben Global
8
return 0;
9
}

Am Prozessor hängt ein externer Quarz von 8MHz
Der String wird mit einer Baudrate von  9600 gesendet(Datenbyte 
8,Stoppbits 1)

Ich hoffe ich habe keine wichtigen Informationen vergessen.
Vielen Dank schonmal im voraus!

Gruss
#1130219
Lesenswert?

Beim Verlassen von main werden die Interrupts global deaktiviert, also 
Endlosschleife einfügen (wie auch schon vom Vorboster geschrieben).

Desweiteren nimm die cli und sei aus dem Interrupt raus. Die sind nicht 
nur unnötig, sondern sogar kontraproduktiv.

Und da du im Interrupt das Empfangsregister nicht aussließt, kannst du 
dich schon mal auf eine Art "Endlosinterrupt" freuen.
#1130229
Lesenswert?

Steffan Kleritchi wrote:

> Könntest du mir bitte das mit dem Empfangsregister nochmal näher
> erläutern?

Du musst im Interrupt das Datenregister (UDR1) auslesen. Dadurch wird 
das Interruptflag gelöscht. Ansonsten würde der Interrupt nach Verlassen 
der ISR sofort wieder auslösen.

> Ich wäre ja froh wenn der Interrupt überhaupt mal auslösen würde.

Wie stellst du fest, dass er nicht auslöst?
#1130242
Lesenswert?

> Wie stellst du fest, dass er nicht auslöst?

In der If-Schleife im Main,ist ein String vergleich,der mir den "test" 
vom Interrupt mit dem "test1" vergleicht und eine LED einschaltet.Wenn 
ich den Befehl "strcpy (test,"test");" aus dem Interrupt raushole und 
ins main schreibe funktioniert das auch soweit,die LED geht an.
Sprich,..Interrupt löst aus,test wird in den String test geschreiben,er 
beendet den Interrupt,test wird mit test1 verglichen und die LED geht 
an.So zumindest mein Plan.
Normal steht im Interrupt folgendes,zum einlesen des Strings.
1
          empfang = empf1();
2
          if(empfang=='X') //Anfangskennung des gesendeten Strings        
3
            {
4
            test[0] = empfang;
5
            for(zahl=1;zahl<=10;zahl++) 
6
              {            
7
              test[zahl] = empf1();
8
              }
9
    
10
            }

Wie lese ich denn das UDR1 aus?Reicht da ein Befehl z.B. X = UDR1; ?Sry, 
für die blöde Frage,aber arbeite zum ersten mal mit der 
UART-Schnittstelle.

Gruss
#1130315
Lesenswert?

1
UCSR1C |=(1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10);
Hier steht im Augenblick quasi:
1
UCSR1C = UBRRH | (1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10);
Da UBRRH null sein sollte, stört es nicht weiter, aber ändere es doch 
besser von "|=" in "=".

Du wirst wohl die übliche Checkliste abarbeiten müssen. Angefangen 
damit, ob der Prozessor überhaupt mit dem erwarteten Takt läuft (ist 
vielleicht noch der interne RC-Oszillator aktiv?). Dann die Hardware 
checken, Verkabelung, Pegelwandler, etc (kommen überhaupt irgendwelche 
Signale beim µC an?).
Gast #1132674
Lesenswert?

so,hab jetzt nochmal alles durchgemessen.
Passt alles bis auf den Quarz,..Dieser schwingt jetzt nur noch mit 0,125 
MHz anstatt mit den ursprünglichen 8MHz.
Weis vlt jemand an was das liegen könnte?

Gruss
Gast #1132898
Lesenswert?

nein.wenn sie gesetzt ist wird der takt doch durch 8geteilt oder? Dann 
hätte ich ja noch zumindest 1Mhz.Aber von 8Mhz auf 0,125Mhz ist das ja n 
Faktor von 64.
Oder hab ich das mit der Fuse falsch verstanden?

Gruss
Gast #1132918
Lesenswert?

Hi

>,..Dieser schwingt jetzt nur noch mit 0,125 MHz anstatt mit den >ursprünglichen 
8MHz.

Womit gemessen? Wenn DSO, evtl. mal Zeitbasis wechseln.

CKDIV8 hat nichts mit dem Oszillator zu tun.

MfG Spess

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren