Forum: Mikrocontroller und Digitale Elektronik Port-Register indirekt adressieren?


von Daniel Roth (Gast)


Lesenswert?

Hallo !!

Wie kann ich mit so wenig Asm-Befehlen wie möglich die I/O-Ports
indirekt adressieren und beschreiben ? Befehle hab ich dafür nicht
gefunden. Bei IN und OUT muss die Adresse beim Assemblieren bereits
feststehen. In meinem Programm soll aber die Adresse erst während der
Laufzeit festgelegt werden..

Notfalls müsste ich eine Sprungtabelle wie
...
OUT12: OUT $12, R
       RJMP xx
OUT13: OUT $13, R
       RJMP xx
OUT14: OUT $14, R
       RJMP xx
...
benutzen, wenn es keine bessere Lösung gibt. Hat jemand eine Idee ?
Danke.

Daniel

von Joerg Wunsch (Gast)


Lesenswert?

Du nutzt Dir dafür aus, daß der gesamte IO-Port-Bereich auch in den
RAM gemappt wird, so daß Du ihn mit normalen STD-Befehlen ansprechen
kannst.

von Daniel Roth (Gast)


Lesenswert?

Hallo Joerg !

Ich hatte auch gehofft, dass es so funktioniert. Wenn man aber
folgendes Programm im Simulator abarbeitet, dann funktioniert nur die
Variante mit OUT:

    .include "4433def.inc"

    ldi R16, $FF       ;funktioniert für Port D
    out portd, R16

    ldi XL, portc      ;funktioniert nicht für Port C
    ldi XH, 0
    st X, R16

Der Port-Bereich ist scheinbar aufgrund der internen Architektur nur
für IN und OUT zugänglich, trotz des gleichen Speichers !?

Daniel

von Joerg Wunsch (Gast)


Lesenswert?

Klar, die haben einen Offset von 0x20.

Datenblatt lesen hilft, wirklich. ;-)

(Oder nimm gleich einen Compiler, der erledigt das dann für Dich.)

von Daniel Roth (Gast)


Lesenswert?

hi Joerg !

Hab meinen Fehler gefunden ! Das Datenblatt kenn ich zwar, aber erst
das Lesen der 4433def.inc hat mich darauf gebracht, dass die
Portbezeichner nur relative Adressen für die Benutzung mit IN und OUT
enthalten. Man sollte halt vorgefertigten Dateien immer misstrauisch
gegenüberstehen..

Vielen Dank für deine Hilfe !
Daniel

(noch mehr Misstrauen sollte man vor Compilern haben ;)

von Joerg Wunsch (Gast)


Lesenswert?

Nö, zumindest der avr-gcc löst das auf intelligente Weise. ;-)

Sämtliche IO wird dort über die Speicheradressen erledigt, da diese
Methode die einzige ist, bei der man erstens indirekt adressieren
kann und bei der zweitens garantiert ist, daß man jeden Port auch
erreicht (der ATmega128 hat Ports, die nur über das memory mapping
erreichbar sind).

Die Ersetzung durch entsprechend effizientere IN/OUT/CBI/SBI wird,
wenn immer (infolge der Randbedingungen der Operanden) erst durch
den Optimierer vorgenommen.

Dadurch kann man komplett dieselbe Syntax für alles benutzen.  Man
sollte natürlich die Architektur des Chips im Hinterkopf behalten,
da es eben sein kann, daß

REGISTER |= (1 << BITNUMMER);

nicht in jedem Falle tatsächlich durch ein SBI abgebildet werden
kann.

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.