Forum: Mikrocontroller und Digitale Elektronik elegante serielle 8N1 TX in Software? AVR, C


von Seb (Gast)


Lesenswert?

Hi,

ich bräuchte mal nen Anstoss für eine elegante Lösung.
Und zwar habe ich einen 4.8kHz Timerinterrupt und die Endlosschleife in 
Main zur Verfügung.

Dort zählt ggf. eine Variable von 10 herunter und entscheidet daran:

10  -> 1 Startbit
9-2 -> 8 Datenbits einer Byte-Variable
1   -> 1 Stoppbit

Das funktioniert eigentlich ganz gut.

Unzufrieden bin ich mit der eigentlichen Übertragung.
In der Endlosschleife wird die Variable von oben auf Null und eine 
weitere Zählvariable auf 3 geprüft (3 Zeichen übertragen).
Dann wird jeweils der gewünschte Wert gesetzt, und beide Zählvariablen 
aktualisiert.

Das erscheint mir umständlich, deswegen würde ich mich über bessere 
Vorschläge freuen!

von Andreas K. (a-k)


Lesenswert?

16bit Variable für das zu sendende Zeichen. Wenn's was zu senden gibt: 
Warten bis ==0, dann 0x200|((c)<<1) reinschreiben.

Im Interrupt: Wenn != 0, dann unterstes Bit ausgeben, danach nach rechts 
schieben.

von Seb (Gast)


Lesenswert?

Hi,

das wäre der 'eigentlich ganz gut' funkionierende Teil ohne Zählvariable 
aber mit 16 Bit Daten...

Und zwar wesentlich übersichtlicher!
Spart auch noch Speicher!

Und ist schneller?

Jedenfalls danke, ich hatte das mal angedacht..hätte ich es mal 
umgesetzt..


Jetzt bräuchte ich allerdings noch eine Art Ausgabeschlange, an die ich 
bei Gelegenheit einfach Zeichen dranhängen kann. Wie heißt sowas?

von Peter D. (peda)


Lesenswert?

siehe Codesammlung


Peter

von Seb (Gast)


Lesenswert?

als Antwort auf welche Frage?

suart.c:79
1
 while( stx_count ); // until last byte finished

soll wohl 'bit' heißen ?

wenn ich das richtig verstehe, ist main für die dauer der übertragung 
blockiert. dann wird natürlich auch keine 'ausgabeschlange' benötigt..

ich dachte, das kann man noch pfiffiger machen?

von Seb (Gast)


Lesenswert?

trotzdem danke für den hinweis, ich werd's erstmal mit ner zeichenkette 
machen..

von Peter D. (peda)


Lesenswert?

Seb wrote:
> suart.c:79
>
1
>  while( stx_count ); // until last byte finished
2
>
>
> soll wohl 'bit' heißen ?

Ne, Byte.
Es wird erst ein neues Byte gesendet, wenn das vorherige Byte fertig 
ist, also der Bitcounter 0 ist.

> wenn ich das richtig verstehe, ist main für die dauer der übertragung
> blockiert. dann wird natürlich auch keine 'ausgabeschlange' benötigt..

Das Beispiel ist ungepuffert.
Da aber Empfang und Senden über Interrupts erfolgt, kann man natürlich 
auch eine Pufferung dazu basteln.

Macht man dann genau so wie bei ner HW-UART, daher hab ichs nicht extra 
dazu geschrieben.


Peter

von Peter D. (peda)


Lesenswert?

Seb wrote:

> Spart auch noch Speicher!
>
> Und ist schneller?

Nö, auf ner 8Bit-CPU ist ein extra Bitzähler effizienter (weniger Code, 
CPU-Zeit).


Peter

von Seb (Gast)


Lesenswert?

> Ne, Byte.
Stimmt, ist egal.

Na ich feil noch ein bisschen dran rum, zumindest sieht es jetzt relativ 
ordentlich aus.
Hat denn so eine Pufferung einen speziellen Namen? Würde ich mir bei 
Gelegenheit gerne mal aneignen.

von Seb (Gast)


Lesenswert?

AVR274: Single-wire Software UART ist vielleicht auch was.

von Seb (Gast)


Lesenswert?

oder AVR304: Half Duplex Interrupt Driven Software UART

von Ulrich P. (uprinz)


Lesenswert?

Hi!
AVR304 kann ich nur empfehlen. Funktioniert einwandfrei und ist leicht 
auf andere Bitzahlen modifizierbar. Musste mal ein 21-Bit serielles 
Interface adaptieren und das ging sehr gut, zumal dieser Code 0% Fehler 
bzgl. des Timings ermöglicht.

Gruß, Ulrich

von Seb (Gast)


Lesenswert?

oder per USI in den tiny AVRs

Half-duplex Asynchronous Data Transfer

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.