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
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
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
Hmmmmmmmmmmmmmmmmmmmmmmmmmmmm, das kommt davon wenn man nicht richtig überlegt!!! Jetzt hab ich's, trotzdem VIELEN DANK!!! Grüße, marcel
>#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
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...
Ich weiß zwar nicht was du meinst aber ich verwende IAR als Software. Gruß Marcel (",)
>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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.