mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega 162 - UART/Interrupt geht nicht


Autor: Steffan Kleritchi (martin09)
Datum:

Bewertung
0 lesenswert
nicht 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
void initusart1(void)
{
unsigned char x;
#ifdef UBRR1L
  UBRR1L = (TAKT / (16ul * BAUD))-1;
  UCSR1B |=(1<<TXEN1)|(1<<RXEN1);
  UCSR1C |=(1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10);
#else
  UBRR = (TAKT / (16 * BAUD))-1;
  UCR |=(1<<TXEN)|(1<<RXEN);
#endif
  x=UDR1;
}

UART empfangen
unsigned char empf1 (void)
{
#ifdef UCSR1A
  while(!(UCSR1A & (1<<RXC1)));
#else
  while(!(USR & (1<<RXC)));
#endif
return UDR1;}

Interrupt

#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#define TAKT 8000000UL 
#define BAUD 9600UL  


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

cli();
          
strcpy (test,"test");

sei();
}

Main
int main(void)
{

DDRB = 0x00;
initusart1();    // UART initialisieren  
UCSR1B |= (1<<RXCIE1);  //Interrupt freigeben UART1
sei();      //Interrupt freigeben Global
return 0;
}

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

Autor: *.* (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde in "main" nach dem "sei()" eine Endlosschleife einfügen, sonst 
ist das Progrämmchen ja gleich "durch".

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Steffan Kleritchi (martin09)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Endlosschleife ist drin und cli und sei draußen.

Könntest du mir bitte das mit dem Empfangsregister nochmal näher 
erläutern?
Ich wäre ja froh wenn der Interrupt überhaupt mal auslösen würde.

Gruss

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Steffan Kleritchi (martin09)
Datum:

Bewertung
0 lesenswert
nicht 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.
          empfang = empf1();
          if(empfang=='X') //Anfangskennung des gesendeten Strings        
            {
            test[0] = empfang;
            for(zahl=1;zahl<=10;zahl++) 
              {            
              test[zahl] = empf1();
              }
    
            }


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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Um zu testen, ob der Interrupt überhaupt auslöst, solltest du den 
einfachsten Weg gehen, um zusätzliche Fehlerquellen auszuschließen. 
Schalte zum Testen also einfach die LED direkt im Interrupt an.

> Wie lese ich denn das UDR1 aus?
> Reicht da ein Befehl z.B. X = UDR1;

Ja.

Autor: Steffan Kleritchi (martin09)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt,warum einfach wenns auch schwer geht ^^.
Also ich schalte die LEDs jetzt im Interrupt ein.
Das UDR1 Register lese ich auch aus.
Leider löst der Interrupt trotzdem nicht aus.

Gruss

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
UCSR1C |=(1<<URSEL1)|(1<<UCSZ11)|(1<<UCSZ10);
Hier steht im Augenblick quasi:
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?).

Autor: martin09 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CKDIV8-Fuse gesetzt?

Autor: martin09 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.