Data Direction Register per Macro setzen

Gast #2547937
Hallo,

mit diesen Macros kann man komfortabel Ein-und Ausgänge lesen bzw. 
setzen/rücksetzen:
1
#define SETBIT(ADDRESS, BIT) (ADDRESS |= (1<<BIT))
2
#define CLEARBIT(ADDRESS, BIT) (ADDRESS &= ~(1<<BIT))
3
#define FLIPBIT(ADDRESS, BIT) (ADDRESS ^= (1<<BIT))
4
#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT)) 
5

6
#define ADDRFROMCOMB(x, y) x
7
#define BITFROMCOMB(x, y) y
8

9
#define SET(comb) SETBIT(ADDRFROMCOMB(comb), BITFROMCOMB(comb))
10
#define CLEAR(comb) CLEARBIT(ADDRFROMCOMB(comb), BITFROMCOMB(comb)) 
11
#define TOGGLE(comb) FLIPBIT(ADDRFROMCOMB(comb), BITFROMCOMB(comb))
12
#define CHECK(comb) CHECKBIT(ADDRFROMCOMB(comb), BITFROMCOMB(comb))

z.B. so:
1
#define TestLED  PORTA,0
2
#define TestLED_Ein    SET(TestLED)
3
#define TestLED_Aus    CLEAR(TestLED)

Weiß jemand wie man aus TestLED per Macro auf die Adresse des Data 
Direction Registers kommt? Also soetwas wie:
1
#define INPUT(comb) CLEARBIT(ADDRFROMCOMB(comb) + 1, BITFROMCOMB(comb)) // funktioniert nicht
2
#define OUTPUT(comb) SETBIT(ADDRFROMCOMB(comb) - 1, BITFROMCOMB(comb))  // und das auch nicht

Das Macro würde dann so verwendet werden:
1
OUTPUT(TestLED)

Oder anders gefragt: Wie kann man per Macro von der Adresse von PORTA 1 
subtrahieren bzw. addieren?


Vielen Dank im Voraus.
Krause
Moderator #2548063
So:
1
#define INPUT(comb) CLEARBIT(*(&ADDRFROMCOMB(comb)-1), BITFROMCOMB(comb))
2
#define OUTPUT(comb) SETBIT(*(&ADDRFROMCOMB(comb)-1), BITFROMCOMB(comb))

Du muss beachten, dass PORTA keine Adresse, sondern bereits dereferen-
ziert ist. Die zugehörige Adresse ist &PORTA, die Adresse von DDRA ist
&PORTA-1, DDRA ist damit *(&PORTA-1). Für PORTA kannst du das allgemei-
nere ADDRFROMCOMB(comb) einsetzen, fertig.
#2548070
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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.