Forum: Mikrocontroller und Digitale Elektronik AVR Assembler – Port-Definitionen zur Laufzeit ändern


von Terence (Gast)


Lesenswert?

Ich benutze eine modifizierte Version der I2C-Bibliothek von Peter 
Fleury für einen Sensor mit I2C-ähnlicher 2-Draht-Schnittstelle. Die 
Bibliothek implementiert die Schnittstelle als Softwareprotokoll in 
Assembler. Alles funktioniert sehr gut.

Die Port- und Pin-Definitionen für den Sensor setzt Herr Fleury über 
#define Anweisungen. Ich verwende nun mehrere Sensoren in folgender 
Anordnung:

  - Sensor1: PA0 und PA1
  - Sensor2: PA2 und PA3
  - Sensor3: PA4 und PA5, …

Dazu habe ich die Bibliothek mehrfach eingebunden und allen Bezeichnern 
(Sprungadressen, Definitionen, Funktionen, …) jeweils neue, andere Namen 
gegeben. Alles funktioniert sehr gut.

Der Nachteil, und auch der Grund warum ich eine neue Lösung suche, ist, 
jedes Mal wenn ich etwas an der Bibliothek ändere, muss ich alle 
eingebundenen „Kopien“ der Bibliothek konsistent halten. Das ist nicht 
sehr effizient. Mir wäre es lieber, wenn ich eine Art 
Funktionsdefinition hätte und die Port- und Pin-Nummern zur Laufzeit 
übergeben könnte.

Kann mir evtl. jemand einen Tipp geben, wie so etwas gehen könnte?

Vielen Dank,
Terence

von spess53 (Gast)


Lesenswert?

Hi

>Mir wäre es lieber, wenn ich eine Art
>Funktionsdefinition hätte und die Port- und Pin-Nummern zur Laufzeit
>übergeben könnte.

Ich kenne die Bibliothek nicht. Aber hast du schon mal an Macros 
gedacht?

MfG Spess

von MWS (Gast)


Lesenswert?

Du müsstest jegliche Portkommunikation in der Lib modifizieren.

Wenn z.B jetzt so gelesen würde:

In   RegX,   InAddr

Dann müsste das geändert werden in:

LDS  ZL, Pointer_of_InAddr_LB
LDS  ZH, Pointer_of_InAddr_HB
LD   RegX,   Z

Der Wert in Pointer_of_InAddr muss +0x20 gegenüber InAddr sein. Damit 
kann dann jede beliebige Adresse verwendet werden.

von Terence (Gast)


Lesenswert?

Vielen Dank Euch Beiden für die schnellen Antworten.

Das muss ich jetzt erstmal verdauen. Aber ich sehe schon, wenn es 
ordentlich werden soll, wird die Umstellung kein Spaß.

Die Lösung von MWS werde ich auf jeden Fall ausprobieren. Vielleicht 
lässt sich diese in der Bibliothek auch geschickt mit einem Macro 
kombinieren ... muss ich aber erstmal durchdenken.

von Sascha W. (sascha-w)


Lesenswert?

@Terence,

da bei dir alle Leitungen auf dem selben Port liegen sollte das recht 
einfach zu machen sein.

wenn möglich 2 Register vorhalten, in denen du zuvor die entsprechenden 
Pins einträgst welche mit der Funktion bedient werden sollen.
1
ldi   sda_pin,(1<<PA0)  ;PA2 o. PA4
2
ldi   scl_pin,(1<<PA1)  ;PA3 o. PA5

die SBI/CBI -Aufrufe ersetzt du folgendermaßen ...

aus ...
1
SBI  SCL_DDR,SCL

wird ...
1
IN   Hilfsregister,SCL_DDR
2
OR   Hilfsregister,scl_pin
3
OUT  SCL_DDR,Hilfsregister

aus ...
1
CBI  SCL_DDR,SCL

wird ...
1
IN   Hilfsregister,SCL_DDR
2
COM  Hilfsregister
3
OR   Hilfsregister,scl_pin
4
COM  Hilfsregister
5
OUT  SCL_DDR,Hilfsregister

die SBIS/SBIC -Aufrufe ersetzt du folgendermaßen ...

aus ...
1
SBIS SDA_IN,SDA
2
;[mach was wenn Bit gelöscht]
3
;[normal weiter ...]

wird ...
1
IN   Hilfsregister,SDA_IN
2
AND  Hilfsregister,sda_pin
3
brne weiter                   ;für SBIC -> 'breq' verwenden 
4
;[mach was wenn Bit gelöscht]
5
weiter:
6
;[normal weiter ...]


Sascha

von Terence (Gast)


Lesenswert?

Hallo Sascha,

vielen Dank für die ausführliche Antwort. Ich schreibe erst jetzt, da 
ich letztes Wochenende keine Zeit mehr hatte Deine Lösung zu durchdenken 
und auszuprobieren.

Habe mir die IN und OUT Befehle im Instruction Set angeschaut und 
verstehe langsam wie es funktioniert.

Du hast mir mit Deiner Lösung sehr viel "Zeit" erspart, dennoch muss ich 
mich jetzt wirklich mal sehr intensiv mit der Adressierung 
auseinandersetzten.

Terence

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.