www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Interrupt Mega 16


Autor: Marcel K. (viewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich habe ein Problem mit dem Rx- Interrupt des Mega 16.
Ich habe folgenden Code:

U16 uart_putchar(U16 ch)
{
  while(!(UCSRA_UDRE));
  UDR = ch;
 }

void init_uart(void)
{
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 19200

UCSRA=0x00;
// 0x80 = RXCIE enabled Rx
// 0x10 = RXEN überschreibt die Portfunktion
// 0x08 TXEN  überschreibt die Portfunktion
UCSRB=0x98;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x0C;
uart_putchar('U');
uart_putchar('A');
uart_putchar('R');
uart_putchar('T');
uart_putchar('_');
uart_putchar('O');
uart_putchar('K');
}

#pragma vector = USART_RXC_vect
__interrupt void uart_rx_interrupt()
{
  uart_putchar('L');
}

Der Controller sendet schön „UART_OK“ nach dem Reset. Dann möchte ich 
auf dem Hyperterminalprogramm eine Taste drücken und erwarte dann ein 
einzelnes „L“ zurück. Allerdings werden dann unendlich viele L’s 
gesendet. (Endlosschleife)
Was mache ich falsch? Ich habe schon im Datenblatt gesucht. Ich hatte 
die Vermutung dass ich ein Flag in der ISR zurücksetzen muss aber ich 
habe nichts gefunden.
Hat jemand eine Idee?? Wäre über jede Hilfe sehr dankbar!
Grüße, Marcel

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Du holst das empfangene Byte nicht ab, damit bleibt das RXC-Flag gesetzt 
und der Interrupt wird sofort wieder ausgelöst.

Gruß aus Berlin
Michael

Autor: Marcel K. (viewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,
ja soetwas änliches habe ich mir schon gedacht aber ich weiß nicht wie 
ich das Byte abholen kann!! Ich habe schon versucht:
U8 uart_getchar( void )
{
  U8 data;
  while ( !(UCSRA_RXC) );
  data = UDR;
  return data;//UDR;
}
 Grüße Marcel

Autor: Marcel K. (viewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmmmmmmmmmmmmmmmmmmmmmmmmmm,

das kommt davon wenn man nicht richtig überlegt!!!

Jetzt hab ich's, trotzdem VIELEN DANK!!!

Grüße, marcel

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, Interrupt-Funktion mit return-Wert? Wer kann damit was anfangen?

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>#pragma vector = USART_RXC_vect
>__interrupt void uart_rx_interrupt()
Ist diese Deklaration von Interrupts nicht veraltet? Ich verwende immer 
nur
SIGNAL(SIG_UART_RECV)

>Hm, Interrupt-Funktion mit return-Wert? Wer kann damit was anfangen?
Das ist doch keine ISR sondern nur eine Getchar Funktion mit polling
U8 uart_getchar( void )
{
  U8 data;
  while ( !(UCSRA_RXC) );
  data = UDR;
  return data;//UDR;
}
Vielleicht will er sowas machen:
SIGNAL(SIG_UART_RECV){
  char data;
  data = UDR;
  uart_putchar('L');
}
Wobei hier natürlich keine Auswertung von data stattfindet

Autor: Gabriel Wegscheider (gagosoft)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Timmo H. wrote:
>>#pragma vector = USART_RXC_vect
>>__interrupt void uart_rx_interrupt()
> Ist diese Deklaration von Interrupts nicht veraltet? Ich verwende immer
> nur
> SIGNAL(SIG_UART_RECV)
Ist SIGNAL nicht veraltet? meines Wissens wird ISR() in den aktuellen 
Libs verwendet...

Autor: Marcel K. (viewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß zwar nicht was du meinst aber ich verwende IAR als Software.

Gruß Marcel (",)

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist SIGNAL nicht veraltet? meines Wissens wird ISR() in den aktuellen
>Libs verwendet...
Stimmt, ich nehme auch immer ISR. g habs bloß nicht gemerkt, weil ich 
immer Copy&Paste mache. Steht auch hier: 
http://www.mikrocontroller.net/articles/AVR-GCC#Ti...
Aber da er eh IAR nimmt ist es ja egal.
@Marcel
Dann übernimm mal den Teil in die ISR
  char data;
  data = UDR;
  uart_putchar('L');
Die Abfrage des UDR sollte das Int-Flag löschen.

Autor: Marcel K. (viewer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ich habe es gestern Abend noch verstanden!!!


Das ganze sieht jetzt so aus:

---------------------------
void uart_putchar(U16 ch)
{
  while(!(UCSRA_UDRE));
  UDR = ch;
}

U8 uart_getchar( void )
{
  while ( !(UCSRA_RXC) );
  return UDR;
}

void uart_auslesen(void)
{
  uart_putchar(uart_getchar());
}

#pragma vector = USART_RXC_vect
__interrupt void uart_rx_interrupt()
{
  uart_auslesen();
}

---------------------------

So bekomme ich alles als Echo auf dem Hyperterminal zurück!!

Vielen Dank noch mal....

Grüße, Marcel

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.