mikrocontroller.net

Forum: Compiler & IDEs Gepollten SW-UART implementieren


Autor: roboguy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: roboguy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: roboguy (Gast)
Datum:

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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: roboguy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Simon K. (simon) Benutzerseite
Datum:

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

Autor: roboguy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.