Krause schrieb:
> Oder anders gefragt: Wie kann man per Macro von der Adresse von PORTA 1
> subtrahieren bzw. addieren?
Wenn du dran denkst, dass ein Makro einfach nur Textersetzungen machst,
musst du dir nur überlegen, wie die Textersetzung sein muss, damit der
Compiler, der nachher das Endergebnis compiliert, das richtige tut.
Grundsätzlich ist das schon möglich. Ich bin aber nicht sicher, ob es
bei allen AVR-µC auf allen Ports so ist, dass das DDR Register 1 vor dem
Port Register liegt.
Aber grundsätzlich musst du nur dafür sorgen, dass der Compiler vor dem
Zugriff die Adresse um 1 verringert. Dazu muss man wissen, wie das PORTA
Makro gemacht ist. Der PortA hat ja letztendlich eine Speicheradresse.
Also eine Zahl. Die wird in einen volatile unsigned char* umgecastet und
dann mittels * auf den Wert zugegriffen.
PORTA = 0xFF;
wird vom Compiler nach all den Ersetzungen für PORTA letztendlich so
*(volatile uint8_t*)0x23 = 0xFF;
übersetzt (die 0x23 hab ich jetzt erfunden, keine Ahnung welche Zahl das
wirklich ist.
Um aus den 0x23 eine 0x22 zu machen, genügt es also den * mit einem &
wieder 'aufzuheben', 1 abzuziehen und erneut dereferenzieren.
*((&*(volatile uint8_t*)0x23) - 1) = 0xFF;
würde daher den Zugriff über die Adresse 0x22 machen.
Von diesem Ziel ausgehen, ist es nicht schwer zu sehen, dass man vor der
Ersetzung von PORTA durch den Klimbim
*(&(PORTA)-1) = 0xFF;
schreiben müsste.
Was jetzt wieder bedeutet, wenn man diese Ersetzung automatisch machen
lässt
#define DDR(port) *(&(port)-1)
schreibt man daher
DDR(PORTA) = 0xFF;
und führt die Textersetzung durch, landet man bei
*(&(PORTA)-1) = 0xFF;
genau so, wie es sein sollte.