Forum: Mikrocontroller und Digitale Elektronik Ports in Array möglich?


von Dani (Gast)


Lesenswert?

Hallo zusammen,
ist es möglich Pins in einem Array zusammenzufassen? Ziel ist es
Ausgänge von verschiedenen Ports von einer Schlaufe aus anzusprechen.
Ich stelle mir das ganze ungefähr so vor:

Definition:
PINS(3) = {PORTA.0,PORTB.3,PORTE.7}

Ansprechen:
PINS(i) = 0;

von Philipp Sªsse (Gast)


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.

von Hanno (Gast)


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!

von Dani (Gast)


Lesenswert?

o.T

von Thomas (Gast)


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

von Thomas (Gast)


Lesenswert?

Ausruestung:

STK500 und STK501 mit AtMega128
4MHz Quarz
ICC AVR

von Hanno (Gast)


Angehängte Dateien:

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

von Thomas (Gast)


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

von Hanno (Gast)


Lesenswert?

>  und ich denke das mir dein Prog auf jeden Fall ein wenig weiterhelfen
wird.

Hoffe, das tut's :)

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.