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
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.
Du könntest dir diesen Beitrag durchlesen, dort stehen viel nützliche Informationen. Beitrag "C -> Port Bitset"
@ 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
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.
Warum keine Funktion? Die sind für sowas da.
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
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.
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 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.