#define nutzen um mehr als 8 Ein- oder Ausgänge anzusprechen

OP #6074104
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
#6074128
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.
Gast #6074147
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
Gast #6074201
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.
Gast #6074306
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.
#6074369
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
}
#6074627
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren