mikrocontroller.net

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


Autor: Dani (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Philipp Sªsse (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hanno (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Dani (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
o.T

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ausruestung:

STK500 und STK501 mit AtMega128
4MHz Quarz
ICC AVR

Autor: Hanno (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Hanno (Gast)
Datum:

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

Hoffe, das tut's :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.