Forum: Mikrocontroller und Digitale Elektronik USART bei ATmega8


von S.T (Gast)


Lesenswert?

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.
1
#define BUFFER_SIZE 64
2
uint8_t RXBUFFER[BUFFER_SIZE];
3
ISR(USART_RXC_vect)
4
{
5
  uint8_t letter;
6
  uint8_t static bufferpos;
7
  letter = UDR;
8
    if(letter == '\r')
9
    {
10
      check_input(RXBUFFER);
11
      put_string("\r\n ===> ");
12
      bufferpos = 0;
13
      memset(RXBUFFER,0,BUFFER_SIZE);
14
    } else
15
    {
16
      if(bufferpos < BUFFER_SIZE)
17
      {
18
        RXBUFFER[bufferpos] = letter;
19
        bufferpos++;
20
      } else { memset(RXBUFFER,0,BUFFER_SIZE); bufferpos = 0; }
21
      put_c(letter);
22
    }
23
}

von Wolfgang Horn (Gast)


Lesenswert?

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

von S.T (Gast)


Lesenswert?

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...

von Karl H. (kbuchegg)


Lesenswert?

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.

von S.T (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von S.T (Gast)


Lesenswert?

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 :)

von S.T (Gast)


Lesenswert?

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?

von spess53 (Gast)


Lesenswert?

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

von Oldmax (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

Hi

Nachtrag:

Die USART teilt dir das durch Setzen des Data OverRun Bits mit.

MfG Spess

von Klaus2m5 (Gast)


Lesenswert?

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".

von Klaus2m5 (Gast)


Lesenswert?

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

von S.T (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

Natürlich das Datenblatt aus diesem Monat!

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

>1 Byte UDR Register + 1 Byte Buffer.

Nö. 2 Byte Buffer + UDR.

MfG Spess

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.