Forum: Mikrocontroller und Digitale Elektronik UART Interrupt Mega 16


von Marcel K. (viewer)


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

von Michael U. (amiga)


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

von Marcel K. (viewer)


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

von Marcel K. (viewer)


Lesenswert?

Hmmmmmmmmmmmmmmmmmmmmmmmmmmmm,

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

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

Grüße, marcel

von crazy horse (Gast)


Lesenswert?

Hm, Interrupt-Funktion mit return-Wert? Wer kann damit was anfangen?

von Timmo H. (masterfx)


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
1
U8 uart_getchar( void )
2
{
3
  U8 data;
4
  while ( !(UCSRA_RXC) );
5
  data = UDR;
6
  return data;//UDR;
7
}
Vielleicht will er sowas machen:
1
SIGNAL(SIG_UART_RECV){
2
  char data;
3
  data = UDR;
4
  uart_putchar('L');
5
}
Wobei hier natürlich keine Auswertung von data stattfindet

von Gabriel W. (gagosoft)


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...

von Marcel K. (viewer)


Lesenswert?

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

Gruß Marcel (",)

von Timmo H. (masterfx)


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#Tipps_.26_Tricks
Aber da er eh IAR nimmt ist es ja egal.
@Marcel
Dann übernimm mal den Teil in die ISR
1
  char data;
2
  data = UDR;
3
  uart_putchar('L');
Die Abfrage des UDR sollte das Int-Flag löschen.

von Marcel K. (viewer)


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

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.