Forum: Mikrocontroller und Digitale Elektronik AVR Assembler: Unterschiede zwischen OUT und STS


von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Kurze Frage, weiß hier bestimmt irgendjemand und ich kanns mir gerade 
nicht so recht erklären...

Bei den größeren ATMega-AVRs liegen viele Peripherie-Adressen/Ports 
außerhalb des mit IN und OUT adressierbaren Bereichs, diese müssen dann 
mit LDS und STS gelesen oder geschrieben werden.

Was ich nicht verstehe, ich kann dies nicht einheitlich mit LDS und STS 
für alle diese Portzugriffe machen. Wenn ich z.B. STS auf eine mit OUT 
erreichbare Adresse ausführe, funktioniert das nicht bzw. der Controller 
verhält sich merktwürdig, daß entweder Teile des Programms oder der 
Peripherie gar nicht oder nicht richtig funktionieren. Ersetzt man das 
STS dann durch ein OUT ohne weitere Änderungen, funktioniert alles 
wunderbar.

Wo liegt der Unterschied zwischen beiden Befehlen, warum führt ein STS 
auf niedrige Portadressen zu Problemen?

Danke...

von Purzel H. (hacky)


Lesenswert?

Atmel fragen.
Das Doofe daran ist, falls man sich ASM antun muss, dass die Handhabung 
des Ports von einem Controller zum naechst groesseren wechseln kann. zB 
vom 324 zum 644. Bedeutet alles kontrollieren und ersetzen. Da die 
Befehle moeglicherweise auf Laufzeit und Speicherplatz optimiert sind, 
kann das nochmals eine Problemursache sein.

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ Ben B. (Firma: Funkenflug Industries) (stromkraft)

>Bei den größeren ATMega-AVRs liegen viele Peripherie-Adressen/Ports
>außerhalb des mit IN und OUT adressierbaren Bereichs, diese müssen dann
>mit LDS und STS gelesen oder geschrieben werden.

Stimmt.

>Was ich nicht verstehe, ich kann dies nicht einheitlich mit LDS und STS
>für alle diese Portzugriffe machen. Wenn ich z.B. STS auf eine mit OUT
>erreichbare Adresse ausführe, funktioniert das nicht bzw. der Controller
>verhält sich merktwürdig,

Nö, das geht schon. Aber  . . .

>Wo liegt der Unterschied zwischen beiden Befehlen, warum führt ein STS
>auf niedrige Portadressen zu Problemen?

Weil die Headerfiles nicht auf STS ausgelegt sind, wo es auch ein OUT 
tut.

Alle per OUT erreichbaren Register sind mit ihrer OUT-Adresse definiert. 
Will man sie per STS ansprechen, muss man 0x20 addieren.

sts PORTA+0x20,R0

Dito bei den Register außerhalb des OUT-Adressbereichs, die sind mit 
ihrer normalen STS-Adresse definiert. Ein Out-Zugriff ist in keinster 
Weise möglich.

Leider hat der Assembler keine direkte Möglichkeit, eine 
Überkreuznutzung zu prüfen.

von Peter D. (peda)


Lesenswert?

Falk B. schrieb:
> Leider hat der Assembler keine direkte Möglichkeit, eine
> Überkreuznutzung zu prüfen.

Ja das ist lästig. Man kann dem mit einem Macro abhelfen:
1
.macro  xout
2
.if  @0 > 0x3F
3
  sts  @0, @1
4
.else
5
  out  @0, @1
6
.endif
7
.endmacro
8
;---------------------------
9
.macro  xin
10
.if  @1 > 0x3F
11
  lds  @0, @1
12
.else
13
  in  @0, @1
14
.endif
15
.endmacro

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Hm okay danke. Ich dachte mir schon, daß es da irgendwo eine 
Verschiebung in den Adressbereichen gibt, wußte nur nicht wo.

Hilft mir nur nicht viel weiter, außer ich würde die Headerfiles 
modifizieren (die +20h-Addition in den Headerfiles vornehmen).

Naja, muß ich mir das Vereinheitlichen abgewöhnen und immer zuerst mit 
OUT probieren, wenn's ein Assemblerfehler gibt, dann durch STS ersetzen. 
Leider ist im Quellcode nicht so leicht ersichtlich, ob eine Adresse 
noch mit OUT erreicht werden kann oder nicht und zwischen den 
Controllern wirds da auch noch Unterschiede geben.

Oki, danke euch trotzdem.

von Falk B. (falk)


Lesenswert?

@ Ben B. (Firma: Funkenflug Industries) (stromkraft)

>Naja, muß ich mir das Vereinheitlichen abgewöhnen und immer zuerst mit
>OUT probieren, wenn's ein Assemblerfehler gibt, dann durch STS ersetzen.

So würde ich das nicht so machen.

>Leider ist im Quellcode nicht so leicht ersichtlich, ob eine Adresse
>noch mit OUT erreicht werden kann oder nicht

Aber sicher! Erstens arbeitet man mit den Registernamen und die stehen 
im Datenblatt in der Registerübersicht. Da weiß man, ob OUT oder STS 
gefragt ist!

>und zwischen den Controllern wirds da auch noch Unterschiede geben.

Tja, ein paar Nachteile muß Assembler halt haben. Der C-Compiler nimmt 
einem diese "Drecksarbeit" ab.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Klar könnte man im Datenblatt nachschauen. Ist aber einfacher, den 
Assembler das machen zu lassen und bei Bedarf auf STS zu korrigieren, 
als wenn ich jetzt jede einzelne Adresse nachschlage.

Ich mag Assembler nunmal und ich bin nicht schlecht damit. Kleine Macke 
von mir. C habe ich nie wirklich gelernt, ich bin zwar sehr gut in PHP 
und C soll dem recht ähnlich sein... Allerdings gibts in C so viele 
verschiedene und nicht kompatible Stile, daß ich lieber bei Assembler 
bleibe anstatt C für das bißchen AVR zu lernen. Der Befehlssatz der AVRs 
ist ja gar nicht so verkehrt, da hat man es auf den PICs schwerer.

von spess53 (Gast)


Lesenswert?

Hi

>Ist aber einfacher, den
>Assembler das machen zu lassen und bei Bedarf auf STS zu korrigieren,
>als wenn ich jetzt jede einzelne Adresse nachschlage.

Kannst du doch. Neben den von PeDa vorgesclagenem Makros gibt es noc 
einige andere:

http://ww1.microchip.com/downloads/en/AppNotes/doc2550.pdf
http://ww1.microchip.com/downloads/en/AppNotes/AVR001.zip

MfG Spess

von S. Landolt (Gast)


Lesenswert?

Jetzt ist G. schrieb:
> dass die Handhabung
> des Ports von einem Controller zum naechst groesseren wechseln kann. zB
> vom 324 zum 644

Wie sollte das sein, wenn beide im selben Datenblatt stehen und es dort 
nur eine Tabelle 'Register summary' gibt?

von spess53 (Gast)


Lesenswert?

Hi

>Wie sollte das sein, wenn beide im selben Datenblatt stehen und es dort
>nur eine Tabelle 'Register summary' gibt?

Das stimmt für den AtMega644p/pa. Die ATMega644(V) haben ein eigenes 
Datenblatt.

MfG Spess

von Peter D. (peda)


Lesenswert?

Jetzt ist G. schrieb:
> Das Doofe daran ist, falls man sich ASM antun muss, dass die Handhabung
> des Ports von einem Controller zum naechst groesseren wechseln kann. zB
> vom 324 zum 644.

Eher nicht.
Nur von alt zu neu, z.B. ATmega8 zu ATmega88 oder ATtiny26 zu ATtiny261.

von S. Landolt (Gast)


Lesenswert?

> Das stimmt für den AtMega644p/pa. Die ATMega644(V) haben
> ein eigenes Datenblatt.

Das stimmt, trotzdem sind die Adressen gleich, d.h. die ursprüngliche 
Aussage ist aus der Luft gegriffen.

von c-hater (Gast)


Lesenswert?

Falk B. schrieb:

> Tja, ein paar Nachteile muß Assembler halt haben. Der C-Compiler nimmt
> einem diese "Drecksarbeit" ab.

Tja, gerade in diesem Fall ist das Argument völlig daneben, da kann man 
in Assembler leicht denselben Luxus geniessen wie in C. Nämlich durch 
Verwendung solcher Makros wie den von PeDa geposteten.

Das Problem ist nur: Längst nicht alles ist so leicht mit einfachen, 
"nichtinvasiven"(*) Makros abzuhandeln.

(*) nichtinvasiv ist vielleicht kein sonderlich glücklicher Ausdruck, 
mir ist nur gerade kein passenderer eingefallen. Ich meine damit solche 
Makros, die bei jedem gegebenen Ziel den bestmöglichen Code erzeugen 
können, ohne dabei jemals weitere Resourcen in Anspruch nehmen zu 
müssen. Diese Sache in/out vs. lds/sts ist ein Beispiel für diese Klasse 
von Makros.

Ein Beispiel für das Gegenteil wäre der Zugriff auf einzelne Bits in 
IO-Registern, die mal mit sbi/cbi/sbis/sbic möglich sind, mal nicht und 
in letzterem Fall dann halt ein MCU-Register als zusätzliche Resource 
benötigen würden, um die Funktion abzubilden.

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.