Hallo Leute, ich habe zwei AVRs - ein Controller soll dem anderen Controller seine Meßwerte übermitteln, damit dieser sie auf sein Display schreiben kann. Ein Telegramm soll dabei ungefähr aussehen STX[Meßwert]ETX. Alla gud - das senen der Info kein Problem, klappt auch nur am Empfang beiß ich mir schier die Zähne aus, WEIL der µC mit dem Display, der die Info empfangen soll auch noch Tasten, LEDs und so bedienen soll. Sprich ich kann nicht im Hauptprogramm einfach warten bis ein STX weil das ja dann alls blockieren würde. Also hab ich versucht im Interrupt des UART auf ein STX zu warten und dann jedes weiter neue Zeichen in ein Array zu schreiben bis ein ETX kommt ... das macht wenn es etwas macht nur komische Sachen. Hat jemand eine praktische Idee wie man eine Zeichenkette empfängt und dabei auch noch etwas anderes tun kann, vielleicht mit Beispiel :)? Danke vorab. Gruß Jens
>das macht wenn es etwas macht nur komische Sachen.
Dann solltest Du das Teil mal zügeln.
Im Grunde ist das mit den Interrupts der richtige Ansatz. Was besseres
gibt es nicht. Vielleicht sollte man aber diese Prüfung auf STX/ETX
nicht im Interrupt machen. Protokoll hat erstmal nichts mit dem Empfang
zu tun.
okay, das mit dem zügeln hört sich gut an: meine ISR: SIGNAL(UART1_RECEIVE_INTERRUPT) { if (UART1_DATA == 0x02) { RX1_index = 0; } RX1_buf[RX1_index] = UART1_DATA; RX1_index++; if (UART1_DATA == 0x03) { RX1flag = 1; } im HP: if (RX1flag == 1) { _delay_ms(4); for (i = 0; i < 32; i++) { uart1_putc(RX1_buf[i]); RX1_buf[i] = 0; } RX1flag = 0; _delay_ms(500); } ich sende mit hterm STX 0 1 2 3 ETX als Antwort bekomme ich ETX STX 0 1 2 3 NULL NULL ... NULL das is das 1. komische Phänomen ... drüberhinaus nach einem Reset bleibt das erste senden ohne Ergebnis ... verstehts jemand?
Also ich würde in der ISR erstmal das RXFlag prüfen! Sonst haut dir die ISR ggf mit neuen Daten dazwischen.
1 | SIGNAL(UART1_RECEIVE_INTERRUPT) { |
2 | if(RX1flag == 0) { |
3 | if (UART1_DATA == 0x02) { |
4 | RX1_index = 0; |
5 | }
|
6 | RX1_buf[RX1_index++] = UART1_DATA; |
7 | if (UART1_DATA == 0x03) { |
8 | RX1flag = 1; |
9 | }
|
10 | }
|
11 | }
|
Das gleiche habe ich auch gerade gemacht zur auswertung eines GPS Empföngers(allerdings in ASM). Desweiteren solltest du sicherstellen das RX1_index nicht größer als dein Array werden kann und korrekt initialisiert ist!
Läubi Mail@laeubi.de wrote: > Also ich würde in der ISR erstmal das RXFlag prüfen! > Sonst haut dir die ISR ggf mit neuen Daten dazwischen. > >
1 | SIGNAL(UART1_RECEIVE_INTERRUPT) { |
2 | > if(RX1flag == 0) { |
3 | > if (UART1_DATA == 0x02) { |
4 | > RX1_index = 0; |
5 | > } |
6 | > RX1_buf[RX1_index++] = UART1_DATA; |
7 | > if (UART1_DATA == 0x03) { |
8 | > RX1flag = 1; |
9 | > } |
10 | > } |
11 | > } |
Sorry, aber das ist seeehr "suboptimal". Wenn im Interrupt das Datenregister nicht ausgelesen wird, wird der Interrupt nach nur einem Asm-Befehl gleich wieder aufgerufen. @ Jens: Außerdem würde ich das Datenregister im Interrupt nur einmal auslesen, und nicht gleich dreimal.
also sowohl in meinem Code als auch in den Änderungen oben versteh ich eins mal gar ned, ich sende mit dem Computer STX 0 1 2 ... ETX und direkt nach dem Senden müßte das Echo ja auf dem Computer empfangen werden, durch das RX1flag. Macht es aber nicht erst wenn ich wieder STX blabla ETX sende, dann erscheint auf meinem Notebook das vorhergehende Telegram, das kann doch gar ned sein, aber ist reproduzierbar, wieso?
okay: data = UART1_DATA; // Zeichen kopieren und mit data weiterarbeiten - schon funktionierts wie erwartet ... im HP wird ein Echo der Eingabe sofort nach ETX zurückgeschickt. Allerdings würd ich gern verstehen wieso??? Wenn mich jemand nach einer Erklärung fragt würde ich sagen, dadurch, daß ich mehrmal das UDR1 abfrage wird immer wieder ein Interrupt ausgelöst und das ganze kommt durcheinander?
Falk Brunner wrote: > siehe Interrupt OT: Wieso gibt es in der Artikelsammlung eigentlich zwei Artikel über Interrupts wobei der von Dir genannte Interrupt in dem Inhaltsverzeichnis der Artikel scheinbar nicht verlinkt ist. Der Artikel AVR-Tutorial: Interrupts dagegen schon. Hmmm..... hier geht soviel Wissen unter, weil es einfach noch viel zu unübersichtlich organisiert ist. :-(
> Sorry, aber das ist seeehr "suboptimal". Wenn im Interrupt das > Datenregister nicht ausgelesen wird, wird der Interrupt nach nur einem > Asm-Befehl gleich wieder aufgerufen. > > @ Jens: > > Außerdem würde ich das Datenregister im Interrupt nur einmal auslesen, > und nicht gleich dreimal. Du hast recht was du über das Datenregister sagst ;)
1 | SIGNAL(UART1_RECEIVE_INTERRUPT) { |
2 | char data = UART1_DATA; |
3 | if(RX1flag == 0) { |
4 | if (data == 0x02) { |
5 | RX1_index = 0; |
6 | }
|
7 | RX1_buf[RX1_index++] = data; |
8 | if (data == 0x03) { |
9 | RX1flag = 1; |
10 | }
|
11 | }
|
12 | }
|
So besser? :)
900ss D. wrote: > Falk Brunner wrote: >> siehe Interrupt > > OT: > Wieso gibt es in der Artikelsammlung eigentlich zwei Artikel über > Interrupts wobei der von Dir genannte Interrupt in dem > Inhaltsverzeichnis der Artikel scheinbar nicht verlinkt ist. Der Artikel > AVR-Tutorial: Interrupts dagegen schon. Hmmm..... hier geht soviel > Wissen unter, weil es einfach noch viel zu unübersichtlich organisiert > ist. :-( siehe http://www.mikrocontroller.net/articles/Spezial:Allpages da die hauptseite der artikelsammlung auch bestandteil des wiki ist, kannst du ja deiner meinung nach fehldende artikel in einer diskussion beanstanden, oder einfach mit dazusetzen.
Michael H* wrote: > da die hauptseite der artikelsammlung auch bestandteil des wiki ist, > kannst du ja deiner meinung nach fehldende artikel in einer diskussion > beanstanden, oder einfach mit dazusetzen. Ja stimmt, allerdings ist es schon ungünstig, dass es zwei Artikel über Interrupts gibt. Ja ja gut, könnte ich auch ändern :-) Wenn ich mal Zeit habe (tm)....
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.