Hallo,
soweit ich weis hat der ATmega8 einen USART (also auch einen Puffer). Im
Moment benutze ich einen Softwarepuffer. Das heißt ich Empfang ein Byte
schiebs in den Puffer und wenn der Puffer voll ist leer ich ihn und es
wird wieder in den Anfang des Puffers geschrieben. Nun habe ich gehört,
dass es auch einen Hardwareseitigen Puffer gibt und wollte fragen, wie
groß der ist, wie man ihn verwendet und was der Vorteil von dem Ding
ist? So wie ich es bis jetzt gelöst habe ist es sehr unschön.
(Es soll ein Terminal werden, deswegen nicht wundern über die Funktionen
put_c und die Überprüfung ob ein Carriage Return erfolgt ist.
Hallo, S.T,
> Nun habe ich gehört,> dass es auch einen Hardwareseitigen Puffer gibt und wollte fragen, wie> groß der ist, wie man ihn verwendet und was der Vorteil von dem Ding> ist?
Findest Du alles im Datenblatt zu jedem Atmega.
Das Datenblatt gehört zur Pflichtlektüre jedes Embedded-Programmierers.
Sehr gute Antworten findest Du auch durch Studium der Programme, die
kluge und gut eingestellte Programmier in diesem Forum veröffentlichen.
Viel habe ich gelernt von den Programmen des Peter Fleury.
Ciao
Wolfgang Horn
Wolfgang Horn schrieb:> Ciao
Naja ich wollte eigentlich die Vorteile von USART wissen. Die werde ich
doch wohl auch nicht unbedingt von Programmcode lesen erfahren...
S.T schrieb:> wird wieder in den Anfang des Puffers geschrieben. Nun habe ich gehört,> dass es auch einen Hardwareseitigen Puffer gibt und wollte fragen, wie> groß der ist
1 Byte, steht alles im Datenblatt
> wie man ihn verwendet
gar nicht. Er dient dazu das eine Byte zwischenzuspeichern, während über
die USART die Bits des nächsten Bytes reinkommen.
Karl Heinz Buchegger schrieb:> S.T schrieb:>>> wird wieder in den Anfang des Puffers geschrieben. Nun habe ich gehört,>> dass es auch einen Hardwareseitigen Puffer gibt und wollte fragen, wie>> groß der ist>> 1 Byte, steht alles im Datenblatt>>> wie man ihn verwendet>> gar nicht. Er dient dazu das eine Byte zwischenzuspeichern, während über> die USART die Bits des nächsten Bytes reinkommen.
Naja ich dachte die werden immer direkt in UDR geschoben. Und wenn ich
nur 1 Byte Platz habe, dann könnten doch auch nicht die nächsten kommen.
Irgendwo müssen sie wohl dann doch zwischenspeichern. Sonst wären die
nachfolgenden Bits doch für die Katz.
Hi
>Naja ich dachte die werden immer direkt in UDR geschoben. Und wenn ich>nur 1 Byte Platz habe, dann könnten doch auch nicht die nächsten kommen.>Irgendwo müssen sie wohl dann doch zwischenspeichern. Sonst wären die>nachfolgenden Bits doch für die Katz.
Sieh dir einfach mal das Block-Schaltbild der UART im Datenblatt an.
Vielleicht bringt das etwas mehr Klarheit.
MfG Spess
spess53 schrieb:> Hi>>>Naja ich dachte die werden immer direkt in UDR geschoben. Und wenn ich>>nur 1 Byte Platz habe, dann könnten doch auch nicht die nächsten kommen.>>Irgendwo müssen sie wohl dann doch zwischenspeichern. Sonst wären die>>nachfolgenden Bits doch für die Katz.>> Sieh dir einfach mal das Block-Schaltbild der UART im Datenblatt an.> Vielleicht bringt das etwas mehr Klarheit.>> MfG Spess
Okay, dann kram ichs mal wieder raus :)
S.T schrieb:> spess53 schrieb:>> Hi>>>>>Naja ich dachte die werden immer direkt in UDR geschoben. Und wenn ich>>>nur 1 Byte Platz habe, dann könnten doch auch nicht die nächsten kommen.>>>Irgendwo müssen sie wohl dann doch zwischenspeichern. Sonst wären die>>>nachfolgenden Bits doch für die Katz.>>>> Sieh dir einfach mal das Block-Schaltbild der UART im Datenblatt an.>> Vielleicht bringt das etwas mehr Klarheit.>>>> MfG Spess>> Okay, dann kram ichs mal wieder raus :)
Also so wie ich das jetzt von dem Block - Diagramm gesehen habe, werden
die Bits erst in das Shift-Register abgelegt und sobald ein Stop-Bit
kommt ins UDR geschoben. Währenddessen kommen neue Daten ins
Shift-Register.
Was mir allerdings nicht ganz klar ist, was passiert wenn ich die Daten
vom UDR nicht rechtzeitig abhole... Wird das UDR dann einfach mit dem
Inhalt aus dem Shift-Register überschrieben?
Hi
>Was mir allerdings nicht ganz klar ist, was passiert wenn ich die Daten>vom UDR nicht rechtzeitig abhole... Wird das UDR dann einfach mit dem>Inhalt aus dem Shift-Register überschrieben?
Ja. Allerdings besteht das Receive-UDR aus 2 Registern:
Datenblatt:
A second Buffer Register has been added. The two Buffer Registers
operate as a circular FIFO buffer.
The Receiver Shift Register can now act as a third buffer level. This is
done by allowing the received data to remain in the serial Shift
Register
(see Figure 61 on page 129) if the Buffer Registers are full, until a
new
start bit is detected.
MfG Spess
Hi
So wird's wohl sein, wenn du nicht die Daten per ISR abholst. Es macht
sowieso Sinn, einen kleinen Rinpuffer einzurichten. Dazu brauchst du ca.
1- 1,5 mal soviel Bytes, wie im Rutsch zu erwarten sind. Dann setzt du
zwei Zeiger, einen Lese- und einen für Schreibzugriffe. Kommt ein Byte,
schreibst du in der ISR einfach an die Stelle, wo dein SChreibzeiger
hinzeigt und erhöhst diesen. Kommst du an die Grenze, dann setzt du
diesen Zeiger auf 0. Im Programm prüfst du, ob Lese- und Schreibzeiger
ungleich sind und nimmst dann das Zeichen mit dem Lesezeiger zur
Bearbeitung. Anschließend erhöhst du den Schreibzeiger bzw. setzt ihn
beim Erreichen der Puffergrenze auf 0.
Bei Polling bist du dir nie sicher, ob du alle Daten erfasst hast. Da
hilft dann ein Check-Sum Byte, welches z,B, alle zu sendenden Zeichen
exclisiv verodert und zum Schluß übertragen wird. Auf Empfängerseite
führtst du die gleiche Veroderung durch und vergleichst das letzte Byte.
Funktioniert aber nur bei bekannter Anzahl von gesendeten / empfangenen
Bytes.
Bisher hab ich mit der Interrupt Service Routine keine Probleme. Das
funktioniert immer.
Gruß oldmax
S.T schrieb:> Was mir allerdings nicht ganz klar ist, was passiert wenn ich die Daten> vom UDR nicht rechtzeitig abhole... Wird das UDR dann einfach mit dem> Inhalt aus dem Shift-Register überschrieben?
Das Receiver UDR ist ein FIFO mit 2 Bytes (angedeutet durch die
waagerechte Linie im Blockschaltbild des Receive-UDR). Erst wenn das
FIFO und das Schieberegister voll sind und ein Startbit erkannt wird,
dann gehen die Daten im Schieberegister verloren. Gleichzeitig wird DOR
im UCSRA gesetzt. Beispiel: Du sendest "ABCDE" ohne das UDR zu lesen.
Dann liest Du das UDR bis RXC 0 ist. Du bekommst "ABE".
Nachtrag zum Beispiel:
Die ErrorBits im UCSRA werden auch im gleichen FIFO zwischengespeichert
und müssen vor dem UDR gelesen werden, da beim Lesen des UDR das FIFO
geleert wird.
Lese Ergebnis
UCSRA RXC=1,DOR=0
UDR "A"
UCSRA RXC=1,DOR=1 logisch, denn danach fehlen Daten
UDR "B"
UCSRA RXC=1,DOR=0
UDR "E"
UCSRA RXC=0,DOR=0
Klaus2m5 schrieb:> S.T schrieb:>> Was mir allerdings nicht ganz klar ist, was passiert wenn ich die Daten>> vom UDR nicht rechtzeitig abhole... Wird das UDR dann einfach mit dem>> Inhalt aus dem Shift-Register überschrieben?>> Das Receiver UDR ist ein FIFO mit 2 Bytes (angedeutet durch die> waagerechte Linie im Blockschaltbild des Receive-UDR). Erst wenn das> FIFO und das Schieberegister voll sind und ein Startbit erkannt wird,> dann gehen die Daten im Schieberegister verloren. Gleichzeitig wird DOR> im UCSRA gesetzt. Beispiel: Du sendest "ABCDE" ohne das UDR zu lesen.> Dann liest Du das UDR bis RXC 0 ist. Du bekommst "ABE".
Naja, vorhin hat man mir erzählt der Buffer wäre nur 1 Byte groß. Und
jetzt heißt es 2 Bytes.
Hi
>Naja, vorhin hat man mir erzählt der Buffer wäre nur 1 Byte groß. Und>jetzt heißt es 2 Bytes.
Vorhin? Das war im letzten Monat. Seitdem ist der Puffer gewachsen. Lies
einfach das Datenblatt.
MfG Spess
S.T schrieb:> Naja, vorhin hat man mir erzählt der Buffer wäre nur 1 Byte groß. Und> jetzt heißt es 2 Bytes.
1 Byte UDR Register + 1 Byte Buffer.
Aber spielt das jetzt wirklich die große Rolle? Selbst wenn der BUffer 2
Bytes aufnehmen könnte, ist das im Regelfall zu wenig, als dass du auf
einen Software-Buffer verzichten könntest.
Ergo: Das was du im Eröffnungsposting als unschön ansiehst, ist nur
insofern unschön, als dein Ringbuffer schon zu speziell ist: Er weiß,
dass da Zeilen daherkommen. Das muss man aber nicht so programmieren.
Der Empfangsinterrupt legt die Zeichen einfach in einen Ringbuffer und
kümmert sich nicht weiter darum, was mit denen weiter geschieht bzw. was
die Zeichen bedeuten. Erst beim Abholen der Zeichen aus dem Ringbuffer,
welches laufend in der Hauptschleife passiert, wird dann dem Empfangenen
eine Bedeutung zugewiesen.
Die einzige Aufgabe des Rindbuffers ist es dann, für eingehende Zeichen
als Zwischenspeicher zu fungieren, damit man dem restlichen Programm
etwas Zeit erkauft in dem es die UART nicht überwachen muss.