Forum: Compiler & IDEs Gepollten SW-UART implementieren


von roboguy (Gast)


Lesenswert?

Ich möchte in meinem MEGA128-Projekt einen zusätzlichen gepollten
SW-UART implementieren, da die beiden HW-USARTS anderweitig benötigt
werden, einen Interrupt für einen INT-gesteuerten SW-UART habe ich auch
nicht zur Verfügung. Nun gibt es ja die ATMEL-AppNote 305, die genau so
eine Funktion beschreibt, samt Beispielcode - allerdings für einen
anderen Prozessor (sollte jedoch problemlos portierbar sein) und vor
allem in Assembler. Da ich WINAVR einsetze und mich bislang mit
Assembler kaum asueinandergesetzt habe, habe ich ehrlich gesagt keinen
rechten Plan, wie ich den Code dieser AppNote direkt übernehmen könnte.

Kann mir da jemand ein wenig auf die Sprünge helfen? Sollte der Code
vorzugsweise als separate Library oder als Inlinestatement eingebunden
werden?

von peter dannegger (Gast)


Lesenswert?

Du weißt was pollen bedeutet ?

Es bedeutet, Du rufst die Empfangsroutine auf und erst dann darf die
Gegenstelle ein Startbit senden. Und Du bleibst solange in dieser
Routine hängen, bis auch wirklich ein Startbit angekommen ist.

Daher eignet sich SW-UART-Polling nur für sehr kleine Programme, die
nichts weiter zu tun haben.


Wenn aber nebenbei noch 2 andere UARTs rumquäken und womöglich noch
gepuffert werden soll, gehts nur über den Timerinterrupt (siehe
Codesammlung).


Peter

von roboguy (Gast)


Lesenswert?

Mir ist schon klar, was pollen bedeutet.
Das Ganze soll ein RS485/422-Logger werden, der sowohl bei einer
Vollduplexverbindung mitlauschen bzw. zwischengeschaltet
Protokollinformationen umsetzen können soll (dafür habe ich die beiden
HW-USARTS vorgesehen). Wenn hier nur Halpduplex vorkäme, hätte ich
nicht beide USARTS verplant.
Der SW-UART soll wirklich nur Daten, die gegebenenfalls aufgenommen
wurden, zum PC übertragen bzw. eventuell abzusetzende Sequenzen vom PC
erhalten. In diesem (nennen wir es mal "Offline"-) Betriebszustand
soll keine weitere Aktion erfolgen. Das Gerät wird ansonsten mit einer
kleinen Tastatur und einem Display ausgestattet.

von roboguy (Gast)


Lesenswert?

Nochmal ich:
Es muss natürlich Halbduplex und nicht Halpduplex heißen!

von Simon K. (simon) Benutzerseite


Lesenswert?

@Peter: Man kann doch auch in einem Timerinterrupt Pollen. Dann hat man
eine Software Uart

von peter dannegger (Gast)


Lesenswert?

@Simon

"Man kann doch auch in einem Timerinterrupt Pollen"


Dann hat man einen Jitter oder muß ein vielfaches der Baudrate pollen.

Genauer gehts mit dem Capture-Interrupt und dann Compare für die
nächsten Bits (siehe mein Beispiel in der Codesammlung).


Wenn man keine 16Bit PWM braucht, ist T1 ideal für die SW-UART.

Wichtig ist aber, alle anderen Interrupts schön kurz zu halten, da ja
der AVR leider keine Interruptprioritäten hat.


Peter

von roboguy (Gast)


Lesenswert?

Vielen Dank für die bisherigen Kommentare.
Das der von mir gewählte Weg absolut nicht das Optimum darstellt, ist
mir klar. Aber erstens habe ich in meiner Schaltung keinen
Capture-Input zur Verfügung und zweitens würde ich gern generell
wissen, wie am besten Assembler-Code in einem C-Projekt eingebunden
wird.
Es muss doch prinzipiell möglich sein, so ähnlich wie bei den
C-Includes, die per Makefile separat compiliert werden, per Assembler
ein relozierbares Modul zu erstellen, das letztlich dazugelinkt wird,
oder?
Ich habe nur leider keine Idee, wie das zu bewerkstelligen ist.

von peter dannegger (Gast)


Lesenswert?

"Aber erstens habe ich in meiner Schaltung keinen
Capture-Input zur Verfügung"


Meinst Du damit, daß Du die beiden Capture-Eingänge (IC1, IC3) für was
anderes benötigst ?

Wenn Du sagen könntest für was, dann könnte man überlegen, ob man einen
freisetzen kann für die SW-UART.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Es muss doch prinzipiell möglich sein, so ähnlich wie bei den
> C-Includes, die per Makefile separat compiliert werden, per
> Assembler ein relozierbares Modul zu erstellen, das letztlich
> dazugelinkt wird, oder?

Na klar.

> Ich habe nur leider keine Idee, wie das zu bewerkstelligen ist.

Ein avr-libc-Demo dafür habe ich in Vorbereitung, ist aber noch nicht
fertig.

Du benennst die Datei auf .S endend (großes S) und nennst sie dem
Compiler mit als Quelldatei.  Falls du das WinAVR-Makefile-Template
benutzt, müsste es wohl einen Makro ASRC oder sowas geben dafür.
Anhand des großen S weiß der Compiler, dass er diese Datei nicht
compilieren soll, sondern lediglich durch den Präprozessor schicken
(damit #include und #define aufgelöst werden) und danach assemblieren
lassen soll.  Das Ergebnis ist dann ein Objektmodul.

http://www.nongnu.org/avr-libc/user-manual/assembler.html

kennst du schon, hoffe ich mal...

von Simon K. (simon) Benutzerseite


Lesenswert?

@Peter: dass dabei Jitter entsteht weiß ich auch, aber Pollen hat nicht
zwangsläufig was mit der Main-Loop zu tun.

PS: Man könnte doch auch einen Pinchange INT für solche Geschichten
nehmen.

von peter dannegger (Gast)


Lesenswert?

@Simon,

"Man könnte doch auch einen Pinchange INT für solche Geschichten
nehmen."

ist aber umständlicher.
Beim Capture-Interrupt hat man den genauen Zeitstempel gratis und sogar
ne Störunterdrückung.

Und das Capture wird in der Regel nur sehr selten benötigt. Daher
wundert es mich, daß roboguy sogar beide Capture-Eingänge benötigt
(wofür bloß ?).


Der einzige Hinderungsgrund ist der, daß T1 und T3 in dem PWM-Modus
laufen, wo sie auch rückwärts zählen, da dann das Capture keinen Sinn
mehr macht.


Peter

von Simon K. (simon) Benutzerseite


Lesenswert?

Dachte den PCINT als Alternative. Aber lassen wir uns doch erstmal die
Beschaltung der beiden Capture-Eingänge sagen.

von roboguy (Gast)


Lesenswert?

Also, um das kurz klarzustellen:
Ich betreibe das Ganze nebenberuflich und mehr aus Interesse (um nicht
einzurosten und etwas Neues kennenzu- und dazuzulernen), möchte aber
auch ein wenig praktischen Nutzen daraus ziehen.
Als ich die Schaltung entworfen habe, bin ich da ziemlich unbedarft
drangegangen und habe mir über den SW-UART wenig Gedanken gemacht.
Ursprünglich wollte ich alles mittels BASCOM erschlagen. BASCOM
ermöglicht einen SW-UART, ohne dass (zwangsweise) ein Capture-Input
verwendet werden muss.
Bei BASCOM gibt es jedoch den einen oder anderen Punkt, der mir nicht
so ganz gefällt. Deshalb mein Ansatz, das Ganze mittels C zu
realisieren.
Wenn ich das Projekt überarbeiten würde, gäbe es mit Sicherheit die
Möglichkeit, ISR-gesteuert zu arbeiten. Aber da es diese AppNote nun
einmal gibt (die zugegebenermaßen nicht das Gelbe vom Ei ist), und ich
gern wissen und lernen möchte, ASM-Code auf diese Weise einzubinden ist
dieses Posting entstanden, möchte ich diesen Ansatz erst einmal
weiterverfolgen.

von peter dannegger (Gast)


Lesenswert?

"BASCOM ermöglicht einen SW-UART"

Bascom kann auch nur mit Wasser kochen.

Entweder es pollt den Pin bis zum St. Nimmerleinstag in der Mainloop
oder es braucht auch den Timer.


"lernen möchte, ASM-Code auf diese Weise einzubinden"

Allgemein sind Assemblerprogramme C-feindlich geschrieben.
Z.B. sie verwenden erstmal alle Register, ehe sie auf SRAM auslagern
(was ja auch sinnvoll ist) und plazieren alles an direkte Adressen.

D.h. um ASM mit C zu verheiraten muß man das Programm schon komplett
verstanden haben und auch in ASM und C Profi sein.


Ich verheirate daher C mit ASM nur im äußersten Notfall, wenn es von
der Laufzeit her nicht anders geht (schnelle Interrupts), sonst lohnt
sich der Aufwand einfach nicht.
Man hat schneller die Funktion in C umgeschrieben und das gute Gefühl
sich kein faules Portabilitätsei ins Nest gelegt zu haben (Wartbarkeit,
Erweiterbarkeit).


Peter

von Chris (Gast)


Lesenswert?

Hallo Allerseits,

kann mir jemand aus Erfahrung sagen, welche maximale Baudrate bei einem 
SWUART verlässliche Daten liefert?

Das system läuft bereits mit einer Baudrate 1MHz, allerdings mit HWUART.

Da die Signalübertragung über ein Spulensystem stattfindet und ich eine 
Spule umpolen sollte, negiert sich also auch mein Signal. Soweit mir 
bekannt ist, kann der ATmega48 beim HWUART das Signal nicht invertieren. 
Folglich bleibt mir nur der SWUART. Langsamer darf ich aber nicht 
werden.

Falls ich mich in etwas irre oder jemand eine tolle Idee oder Lösung 
hat, wäre das toll.

Danke
Gruß Chris

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.