www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Interrupt mit Mega8


Autor: Torsten K. (nobby)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche den UART Interrupt des Mega 8 zu aktivieren,
aber ich bekommen es nicht auf die Reihe.

Gesetzt habe ich:

UCSRB = (1<<RXCIE);
sei(); // Globaler Interrupt aktiviert.

Sobald nun in UCSRA das RXC gesetzt wird, sollte er doch in die
Interrupt Routine springen:

ISR(USART_RXC_vect)  // Daten Empfangen, Rx Complete
{

}

Das macht er aber nicht, habe ich was übersehen ??
Das Datenblatt habe ich schon rauf und runter gelesen....

Danke
Torsten

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Receiver aktiviert? (1<<RXEN) ?
globale Interrupts aktiv? sei();

WIe wäre es mit dem kompletten code?

Autor: Torsten K. (nobby)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, also die Interrupts sind aktiev, habe ja geschrieben sei().
Den (1<<RXEN) hatte ich auch gesetzt, aber das hat auch nichts geholfen.
Was meinst Du mit dem kompletten Code, ich habe im Interrupt eine LED 
aktiviert, aber die tut es eben nicht.

Hier nochmal alle Register, wenns denn hilft..

DDRC |=  _BV(PC0) |_BV(PC1) | _BV(PC2)| _BV(PC3) | _BV(PC4);   // Teile 
von PortC als Ausgang
  DDRC &=~ _BV(PC5);                   // Teile von PortC als Eingang



  DDRD |=  _BV(PD2) | _BV(PD5) | _BV(PD6) | _BV(PD7);  // Teile von 
PortD als Ausgang
  DDRD &=~ _BV(PD3) | _BV(PD4);               // Teile von PortD als 
Eingang
  PORTD |= _BV(PD3) | _BV(PD4);               // Teile von PortD PullUp


  DDRB |= _BV(PB0) | _BV(PB1) |  _BV(PB2) | _BV(PB3) | _BV(PB4) | 
_BV(PB5);    // Teile von PortB als Ausgang
  DDRB &=~  _BV(PB6) | _BV(PB7);              // Teile von PortB als 
Eingang
  PORTB |=  _BV(PB6) | _BV(PB7);              // Teile von PortB PullUp


  OSCCAL = eeprom_read_byte((uint8_t*)0xFF);



  TIFR = (1<<TOV0)|(1<<TOV1);
  TCCR0 = (1<<CS00)|(1<<CS01);
  TCCR1B = (1<<CS12)|(1<<CS10);


  UCSRB = (1<<RXCIE) | (1<<RXEN);



  TIMSK = (1<<TOIE0)|(1<<TOIE1);

Autor: Martin F. (martin-f)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wirklich vollständig ist der code wohl immernoch nicht. Hier fehlt mir 
z.B. die Baudratenintitialisierung. (stichwort UBRR)
Sonst schau Dir diesen Teil des tutorials noch mal an:
in C: 
https://www.mikrocontroller.net/articles/AVR-Tutor...
in ASM:  https://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

Autor: Torsten K. (nobby)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja, der USART funktioniert ja, denn wenn ich den  (UCSRA & (1<<RXC))
polle, bekomme ich Daten rein, kein Problem.

Aber gerne hier meine Init, genau nach Datasheet:

void USART_Init(void)
{
   UBRRH = (F_CPU/(UART_BAUD_RATE1*16l)-1) >> 8;
   UBRRL = (F_CPU/(UART_BAUD_RATE1*16l)-1);

// Enable Receiver and transmitter
   UCSRB = (1<<RXEN)|(1<<TXEN);
// Set frame format: 8data, 2stop bit
   UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

Ich habe auch gefunden woran es liegt, denn nur

UCSRB = _BV(RXCIE) |_BV(RXEN);

reicht nicht, es muß noch

 _BV(UDRIE)  mit dazu, und wenn ich das Datenblatt richtig verstehe muß 
auch noch in UCSRA einer gesetzt werden. Insgesamt sieht es dann so aus:

UCSRA = _BV(UDRE);
UCSRB = _BV(RXCIE) | _BV(UDRIE) | _BV(RXEN);

Dann springt er auch prima in den Interrupt.
Leider wird nun der Timer0 irgendwie beeinflusst, auch wenn der nicht in 
den Interrupt der Seriellen springt, scheint der Timer0 langsamer zu 
werden.

Mal sehen, ob ich das noch finde.

Gruß
Torsten

Autor: Chrisi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solange Du das Zeichen nicht aus dem Empfangspuffer liest, wird der 
Interrupt nicht gelöscht. Dann ist Deine CPU quasi dauerbusy :-) Nur ne 
Idee.

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

Bewertung
0 lesenswert
nicht lesenswert
Richtig. Es muss im RXC-Interrupt-Handler das UDR gelesen werden. Erst 
der Lesezugriff löscht das Interrupt-Flag. Wenn nicht gelesen wird, 
springt er nach dem Ende der ISR sofort wieder rein.

Autor: Torsten K. (nobby)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe den Eindruck das da irgendetwas mit dem Compiler nicht stimmt !

Wenn ich den
ISR(USART_RXC_vect)
benutze, springt er nur in den Interrupt wenn auch UDRIE gesetzt ist.
Aber er durchläuft dann nicht mehr das Hauptprogramm und verhält sich 
auch sonst "merkwürdig", als ob er überlastet ist.

Benutze ich hingegen den alten Ausdruck,
SIGNAL(SIG_UART_RECV)
dann scheint alles normal zu funktionieren und es muß auch nicht der 
UDRIE gesetzt sein.

Hat denn schonmal jemand den RX Interrupt mit dem Mega 8 benutzt ?

Gruß
Torsten

Autor: Chrisi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, hier z.B.:

// Setup USART
UBRRH = (byte)(BAUDVAL >> 8);
UBRRL = (byte)(BAUDVAL & 0xFF);
UCSRC = (1<<URSEL) | (3<<UCSZ0);
UCSRA = (1<<U2X);
UCSRB = (1<<RXEN) | (1<<RXCIE);

// Interrupt
SIGNAL(SIG_UART_RECV)
{
    // Read UDR and put it into the revceive buffer
    BUF_PUT(HostRX,UDR)
}

Was moderneres benutze ich auch nicht.

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.