Forum: Mikrocontroller und Digitale Elektronik UART-Emppfang zu Ende.


von W.Meyer (Gast)


Lesenswert?

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.

von Binomie (Gast)


Lesenswert?

Hi Wolfgang,

Gibt es einen Grund, dass du keinen RXC-Interrupt verwendest?

Simon

von W.Meyer (Gast)


Lesenswert?

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.

von Meiserl (Gast)


Lesenswert?

.... eine ganz dumme Frage

Warum schreibst du dein Programm nicht in C?

http://dhptechn.ir.ro/

von Interessierter (Gast)


Lesenswert?


von bitte löschen (Gast)


Lesenswert?

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.

von h_ (Gast)


Lesenswert?

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.

von µC-Bastler (Gast)


Lesenswert?

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.

von Helmut L. (helmi1)


Lesenswert?

Leute ihr seit Leichenflederer.

Der Ursprungspost liegt mittlerweile 11 Jahre zurueck.
Meint ihr W.Meyer (Gast) liest hier noch mit?

von bitte löschen (Gast)


Lesenswert?

Bruhaaahaaa Geil! Ich Depp! :-D ;-)
Jo is denn scho' Ostern?

von Peter D. (peda)


Lesenswert?

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

von Helmut L. (helmi1)


Lesenswert?

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
Noch kein Account? Hier anmelden.