Ports in Array möglich?

Gast #117711
Lesenswert?
• ▲
▼
Kommt darauf an, womit Du programmierst und was für einen µC Du benutzt.
Beim AVR hast Du bei den Port-Bit-Befehlen im low byte das IO-Register
und das Bit definiert, da wird es also relativ einfach mit einem
byte-array für die Pins.

Wenn Du es in C machen willst, mußt Du es aber wohl etwas anders
angehen als oben. Also ein SET_PORT(X) definieren, was dann ein SBI mit
PINS[X] macht.
Gast #117712
Lesenswert?
• ▲
▼
Für den AVR habe ich mir folgendes zusammengestrickt:


// Port-Address-Definitions
#define PA_PORTA 3
#define PA_PORTB 2
#define PA_PORTC 1
#define PA_PORTD 0
#define PA_INIT_OUTPUT 0x20
#define PA_INIT_HIGH   0x40

#define pinAddr(prt,pin) ((prt << 3) | pin)

#define pinBaseAddr(pa) ( (((pa) >> 3) & 3) * 3 + 0x10 + 0x20)
#define pinPinAddr(pa) pinBaseAddr(pa)
#define pinDdrAddr(pa) (pinBaseAddr(pa) + 1)
#define pinPortAddr(pa) (pinBaseAddr(pa) + 2)

#define pinBit(pa) ((pa) & 0x07)

#define setPort(pa,v) if(v) { (*(volatile uint8_t*)pinPortAddr(pa)) |=
_BV(pinBit(pa)); } else { (*(volatile uint8_t*)pinPortAddr(pa)) &=
~_BV(pinBit(pa)); }
#define getPort(pa) ((*(volatile uint8_t*)pinPortAddr(pa)) &
_BV(pinBit(pa)))

#define setDdr(pa,v) if(v){ (*(volatile uint8_t*)pinDdrAddr(pa)) |=
_BV(pinBit(pa)); } else { (*(volatile uint8_t*)pinDdrAddr(pa)) &=
~_BV(pinBit(pa)); }
#define getDdr(pa) ((*(volatile uint8_t*)pinDdrAddr(pa)) &
_BV(pinBit(pa))

#define getPin(pa) ((*(volatile uint8_t*)pinPinAddr(pa)) &
_BV(pinBit(pa)))

#define initPin(pa) setDdr((pa), (pa) & PA_INIT_OUTPUT); setPort((pa),
(pa) & PA_INIT_HIGH )



Dann die Pins definieren mit:

#define BIT_BTN_1 6
#define BIT_BTN_2 7

#define PIN_BTN_1   (pinAddr( PA_PORTA, BIT_BTN_1 ) | PA_INIT_HIGH)
#define PIN_BTN_2   (pinAddr( PA_PORTA, BIT_BTN_2 ) | PA_INIT_HIGH)


Initialisieren mit:

initPin( PIN_BTN_1 );

bzw.

setDdr( PIN_BTN_1, 0 );
setPort( PIN_BTN_1, 1 );

if ( getPin( PIN_BTN_1 ) )
{
...
}

Die #define-ten Werte kann man dann auch in ein Array schreiben und von
da aus verwenden.
Klappt natürlich nur mit PortA-D. Auf dem Mega16 geht das so, bei
anderen muss die pinBaseAddr ggf. angepasst werden.

Hth!
Gast #117714
Lesenswert?
• ▲
▼
Hallo,

ich habe leider erst letzte Woche angefangen mit mit Mikrokontrollern
zu beschaeftigen.
Nun sind sie Inhalt meines Praktikums, und ich gucke auf die meisten
Quelltexte wie das sprichwoertliche "Schwein ins Uhrwerk).
Ich trage mich mit dem selben Problem wie im Thread beschrieben.
Das Prog von Hanno sieht richtig interessant aus. Aber koenntest du
bitte mal ein paar Kommentare einfuegen welche beschreiben was was
macht?

Danke schoen im Voraus,

Thomas
Gast #117716
Lesenswert?
• ▲
▼
Ok, hier mal eine Version mit ein paar Kommentaren.
Noch zwei Bemerkungen:
- Das klappt so nur mit den Ports A bis D auf dem ATmega16. Für andere
Controller muss ggf. der Offset 0x30 bei der pinBaseAddr geändert
werden. Die anderen Ports, die z.B. der ATmega128 hat können nicht so
einfach verwendet werden.
- Das ganze ergibt konstante Ausdrücke, die zur Compile-Zeit
ausgewertet werden, so dass es kompakten und schnellen Code ergibt. Das
stimmt aber nicht mehr, sobald die Konstanten in Variablen abgelegt
werden, mit denen dann gearbeitet wird. Die werden dann erst zur
Laufzeit ausgewertet, was weniger effizient ist.
Beispiel:
  setPort( PA_BTN1, 1 ); // schnell+kompakt, wird zu einem SBI

  unsigned char x;
  x = PA_BTN1;
  setPort( x, 1 ); // langsamer+umfangreicher, wird erst zur Laufzeit
ausgewertet

Grüße,
Hanno
Angehängte Dateien:
Gast #117717
Lesenswert?
• ▲
▼
@Hanno,

vielen Dank fuer Deine schnelle und Umfangreiche Antwort.
Du hast Dir mit den Kommentaren wirklich muehe gegeben, und ich denke
das mir dein Prog auf jeden Fall ein wenig weiterhelfen wird.

MfG Thomas

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

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.