Folgendes Problem habe ich: Der Hardware-UART des ATMega103 empfängt vom PC-Terminal-Programm eine Zeichenkette, die danach über einen Port parallel Byteweise ausgegeben wird. Zur Kontrolle lasse ich die Zeichenkette auch wieder zum PC zurück senden, was auch klappt. Damit nicht nur ein Zeichen (Byte) übertragen wird, muß ich anschließend wieder in die Empfangs-Schleife springen. Da kommt man offenbar nicht mehr raus, so das nachfolgende Programm-Teile nicht mehr abgearbeitet werden. Das Einfachste wäre, auf ein bestimmtes Zeichen zu reagieren, das mit einer Branch-Anweisung aus der EmpfLoop heraus geht. Die Empfangs-Datei kann nun aber alle möglichen Zeichen enthalten. Auch die schon von DOS her bekannte Datei-Ende Markierung (EOF) scheidet also aus. Da mein ATMega 4KByte Arbeitsspeicher hat, kann ich aber auch nicht erst mal alles reinholen und sehen, wenn nichts mehr kommt. (765968KByte). Bliebe da noch die Möglichkeit, feste Datei-Größen zu vereinbaren und einen Byte-Zähler mitlaufen zu lassen, der bei vorbestimmtem Überlauf das Verlassen der UART-Routine veranlasst. Der UART muß auf jeden Fall erst mal auf das PC-Programm warten, bis etwas kommt. Das Terminal-Programm selbst läßt sich nicht vom UART aus steuern, weil z.B.: nur die Hin und Rück-Sende Leitungen nebst Masse benutzt werden können. Das ist auf meinem Experimentier-Board schon vom Hersteller so vorgegeben. Welche Möglichkeiten gibt es noch, so etwas zu realisieren, bzw. wo sollte man eingreifen und wie. Feste Datei-Größen kann ich bereitstellen, bzw. sind in der vorgesehenen Anwendung auch nötig. 1.Programmteil: xxxxx EmpfLoop: ;xxxxx ; Hier müßte man wohl eingreifen? SBIS USR,RXC ; Teste RXC-bit auf vorliegendes Zeichen. JMP EmpfLoop ; Kein Zeichen vorhanden, warte. IN c,UDR ; Hole Zeichen vom UART ab. Mov sr20Inv,c ; Register c darf wegen SendLoop nicht invertiert werden. Com sr20Inv ; Zeichen Invertieren wegen LED's. ;Out PortB,sr20Inv ; Zeichen auf PortB-LED's anzeigen. Out PortC,sr20Inv ; Zeichen auf PortC-LED's anzeigen. Jmp SendLoop SendLoop: SBIS USR,UDRE ; Warte bis Sender bereit. JMP SendLoop ; Sender noch nicht frei. OUT UDR,c ; Sende Zeichen wieder zurück. JMP EmpfLoop 3.Programmteil: xxxxx Vielleicht hat jemand eine brauchbare Idee. Vielen Dank im Voraus. Wolfgang.
Hi Wolfgang, Gibt es einen Grund, dass du keinen RXC-Interrupt verwendest? Simon
Hi. Ja, die Errata-Seite von ATMEL hält mich davon ab. Man beschreibt dort Probleme in Zusammenhang mit Interrrupts. Da ich noch nicht viel Programmier- Erfahrung habe, wollte ich erst mal alles im Polling- Betrieb realisieren. Was nützt es mir, wenn ich dann mit Interrupt etliche Sprung-Befehle meiden muß. Aber vielleicht muß man ja nicht unbedingt den Stack benutzen und legt die Rückkehr-Adressen in reservierten Registern ab. Mal sehen, ob das eventuell geht. Wolfgang.
W.Meyer schrieb: > Ja, die Errata-Seite von ATMEL hält mich davon ab. > Man beschreibt dort Probleme in Zusammenhang mit > Interrrupts. Dann nimm einen Timer/Counter, der mit jedem empfangenen Zeichen resettet wird und beim Erreichen eines von Dir zu definierenden Timeouts ein Flag setzt, das Du in Deiner Warteschleife zusätzlich zum RCX-Bit abfragen kannst.
Hallo, anstatt eine feste Paketgröße zu vereinbaren, kannst du auch für jede Übertragung zuerst die Anzahl der zu übertragenden Bytes senden. Mit dieser Information kannst du im AVR herunterzählen, bis du alle Daten empfangen hast. Die Anzahl der Bytes muss natürlich ein festes Format haben, z.B. die ersten 4 Bytes, MSB first: [Anzahl 3] [Anzahl 2] [Anzahl 1] [ Anzahl 0 ] [ Daten ] Daraus machst du dir einen long int:
1 | unsigned long int data = 0; |
2 | for(int i = 0; i < 4; i++) |
3 | {
|
4 | data <<= 8; |
5 | data |= UDR; |
6 | }
|
Mit dieser Lösung musst du keine Füllbytes übertragen, falls dein Datenpaket kleiner ausfällt als die vereinbarte Paketgröße. Meinst du diese Errata: "Skip Instruction with Interrupts"? Das ist von 2001, avr-gcc kann bestimmt mittlerweile damit Umgehen. Da du Assembler benutzt, kannst du ja selbst darauf achten, keine Skip-Instruktionen bei aktivierten Interrupts zu verwenden.
W.Meyer schrieb: > Da ich noch nicht viel Programmier-Erfahrung habe, wollte ich erst > mal alles im Polling-Betrieb realisieren. Wenn dein Prozessor noch etwas anderes tun soll, als den USART-Empfänger zu pollen, müssen die anderen Tätigkeiten auch in der Abfrageschleife drinstehen. Aber du merkst schon: Ohne Interrupt wird das bald zu einem Problem, weil die anderen Tätigkeiten dann so kurz sein müssen, dass du beim USART nichts verpaßt. Mit einem Timeout-Zähler blockierst du bis zum Ablauf der maximalen Wartezeit ebenfalls den Prozessor.
Leute ihr seit Leichenflederer. Der Ursprungspost liegt mittlerweile 11 Jahre zurueck. Meint ihr W.Meyer (Gast) liest hier noch mit?
Helmut Lenzen schrieb: > Der Ursprungspost liegt mittlerweile 11 Jahre zurueck. Ich hab mich schon gewundert, wer den ATmega103 aus dem Museum geklaut hat. Und ohne Interrupts vernünftig programmieren zu können, halte ich für unmöglich. Peter
Peter Dannegger schrieb: > Ich hab mich schon gewundert, wer den ATmega103 aus dem Museum geklaut > hat. Peter das hatte ich mich auch gefragt und dann auf das Datum geschaut.
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.