Forum: Mikrocontroller und Digitale Elektronik #define nutzen um mehr als 8 Ein- oder Ausgänge anzusprechen


von Gabi D. (mbc-user)


Lesenswert?

Hallo AVR-Programmierfans,

ich habe folgende Fragestellung.
Ich nutze einen Arduino Mega 2560.

Um das Einlesen oder Ansprechen von mehr als 8 Ports zu realisieren, ist 
meine Überlegung über #define ein Makro zu definieren.
Dazu definiere ich noch ein Array der betroffenen native Pins.
Mit dem "Makro" könnte ich dann meine "if"-Abfragen einfach darstellen.
So die Theorie.

Bsp.:
/*Einlesen 9x Tastenpins */
#define TastePort PINA 
// definiert PORTA Import

#define TastePort PINC = PORTC |= (1<<PC7) 
// definiert PC7 als Import

 /* 'das ist natürlich Unsinn, da ich "TastePort" 2x deklariere! */

  const uint8_t taste_Pins[] = { PA0, PA1, PA2, PA3, PA4, PA5, PA6, PA7, 
PC7 };       // nurLese-Array

//-------------

Ich muss also eine Lösung finden, mit der ich portspezifisch ein Makro 
definieren kann. Komme aber hier nicht wirklich weiter.

Ich arbeite in C. Daher wenn möglich auf dieser Sprache Tipps zukommen 
lassen. Außer es geht nicht unter C, was ich mir nicht vorstellen kann.
Herzlichen Dank.
Gabi

von Mark B. (markbrandis)


Lesenswert?

Gabi D. schrieb:
> Um das Einlesen oder Ansprechen von mehr als 8 Ports zu realisieren, ist
> meine Überlegung über #define ein Makro zu definieren.

Mir erschließt sich da der Zusammenhang nicht so recht. Was hat ein 
#define damit zu tun, ob Du mehr oder weniger als 8 Eingänge einlesen 
willst?

> Mit dem "Makro" könnte ich dann meine "if"-Abfragen einfach darstellen.
> So die Theorie.

Dann zeige doch erstmal den "komplizierten" Code, den Du vereinfachen 
willst.

Ein #define ist einfach eine Textersetzung. Nicht mehr, nicht weniger. 
Das heißt, dass man sich dadurch im Grunde genommen überhaupt keinen 
Code spart: Der Präprozessor macht die Textersetzung, und am Ende hat 
der Compiler auch nicht weniger zu tun als vorher.

von Holger L. (max5v)


Lesenswert?

Du könntest dir diesen Beitrag durchlesen, dort stehen viel nützliche 
Informationen.

Beitrag "C -> Port Bitset"

von mbc-user (Gast)


Lesenswert?

@ Mark,

ich könnte mit einer solchen Definition, im Weiteren folgendes dann 
darstellen:

/---- Positionserkennung auf Neutrallage

if ( NeutralPort & (1<< sens_Pins[NeutralLage]) ) {     // steht auf 
Neutralposition
   zielSensorNr = NeutralLage;
   aktNr = zielSensorNr;                         // -> Position ok

   LED_Port |= (1<<led_Pins[aktNr]);        // zugehörige LED ON
/----

Es geht um eine Drehscheibe die über 25 Tasten in gewisse Stellungen 
positioniert werden kann. Die Position wird über Positionssensoren 
erkannt, (sens Pins). Dieser Codeschnippsel ist die Erkennung, dass die 
Drehscheibe in der definierten Neutralposition steht. Daher soll soll 
die entsprechende (Neutral-) Positions-LED leuchten.
vg gd

von MagIO2 (Gast)


Lesenswert?

Also so wie ich das verstehe sind defines nicht die Antwort auf das 
Problem.
Hier mangelt es am Verständnis von Compile-Zeit vs. Laufzeit.

Makros sorgen dafür, dass man zur Compile-Zeit unterschiedlichen Code 
generieren kann. Wurde oben schon erwähnt, man kann es als reine 
Text-Ersetzung betrachten.
Dieser Code bleibt dann aber auch zur Laufzeit konstant.

Was du brauchst ist eben noch ein weiteres Array. In dem einen Array 
definierst du die Pins, in dem anderen Array den dazu gehörigen Port.

Also taste_Pins[] wie gehabt und dazu noch taste_Ports[], der die 
Pointer auf die Portaddresse beinhaltet.
{ PORTA, PORTA ..... , PORTC }

Frag mich nicht nach der genauen Syntax, bin schon zu lange raus aus C.

Noch besser ist natürlich sich einen eigenen Typ zu definieren, der dann 
aus Portaddresse und Pin-Nummer besteht und macht daraus ein einziges 
Array.

Und wenn du die ganze Pin-Abfragerei dann auch noch in eine Funktion 
auslagerst, dann wird der Code auch gut lesbar.

von kghgdhuh (Gast)


Lesenswert?

Warum keine Funktion? Die sind für sowas da.

von Gabi D. (mbc-user)


Lesenswert?

zunächst herzlichen Dank für Eure Informationen.
Den Gedanke mit einer Funktion hatte ich auch, aber keinen Ansatz.

Den Tipp mit dem 2.Array versuche ich einmal.
Schönes Wochenende noch.
Gabi

von PittyJ (Gast)


Lesenswert?

Anfänger sollten keine Macros benutzen, solange sie die Zusammenhänge 
nicht verstehen.

Schreib bitte erst einmal eine richtige Funktion. Ein guter Compiler 
optimiert das schon.

Gute Bücher helfen beim Verständnis.

von Peter D. (peda)


Lesenswert?

Gabi D. schrieb:
> Um das Einlesen oder Ansprechen von mehr als 8 Ports zu realisieren

Was ist denn Dein konkretes Problem?
Du kannst jederzeit jeden beliebigen Portpin direkt ansprechen.

Willst Du mehrere 8Bit-Ports gleichzeitig ansprechen, geht das mit einer 
Funktion.
Z.B. für 4 Ports einlesen:
1
uint32_t get_32pins(void)
2
{
3
  return PINA | PINB<<8 | (uint32_t)PINC<<16 | (uint32_t)PIND<<24;
4
}

von Rolf M. (rmagnus)


Lesenswert?

MagIO2 schrieb:
> Noch besser ist natürlich sich einen eigenen Typ zu definieren, der dann
> aus Portaddresse und Pin-Nummer besteht und macht daraus ein einziges
> Array.

Ja, z.B. grob sowas in der Art:
1
struct Pin
2
{
3
    volatile uint8_t* port;
4
    uint8_t bv;
5
};
6
7
const struct Pin pins[] = 
8
{
9
    { .port = &PORTA, .bv = 1 << PA3 },
10
    { .port = &PORTB, .bv = 1 << PB5 },
11
12
};
13
14
static inline void setPin(uint8_t pin, bool on)
15
{
16
    if (on)
17
        *pins[pin].port |= pins[pin].bv;
18
    else
19
        *pins[pin].port &= ~pins[pin].bv;
20
}

Dem Leser bleibt zu Übungszwecken überlassen, das jetzt so zu erweitern, 
dass die Tabelle am Ende nicht im RAM liegt.

: Bearbeitet durch User
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.