Hey sternst,
vielen Dank für den Schubser, der Wald und die vielen Bäume....
Ich habe außerdem den Weg von oberallgeier probiert:Code:struct LED { volatile unsigned char *ddr; volatile unsigned char *port; uint8_t pin; }; void InitLed(struct LED *led) { *led->ddr |= 1<<(*led).pin; } void LedOn(struct LED *led) { *led->port |= 1<<(*led).pin; } void main() { struct LED led1 = {&DDRA, &PORTA, PA0}; struct LED led2 = {&DDRA, &PORTA, PA1}; InitLed(&led1); InitLed(&led2); }
Bei meinem aktuellen Projekt werde ich die define-Variante verwenden, doch die Flexibilität der Structs ist mir für Projekte wichtig, wo ich während des Betriebs Pins konfigurieren können möchte ohne den Microcontroller neu programmieren zu müssen, außerdem bietet sich hier noch eine "verkettete Liste" an.Code:#define SetBit(ADDR,BIT) (ADDR |= (1<<BIT)) #define ClrBit(ADDR,BIT) (ADDR &= ~(1<<BIT)) #define TglBit(ADDR,BIT) (ADDR ^= (1<<BIT)) #define Led_1_An() SetBit(PORTA,PA0) #define Led_1_Aus() ClrBit(PORTA,PA0) #define Tgl_Led_1() TglBit(PORTA,PA0) #define Led_2_An() SetBit(PORTA,PA1) #define Led_2_Aus() ClrBit(PORTA,PA1) #define Tgl_Led_2() TglBit(PORTA,PA1)
Viele Grüße,
Crazy
Dazu ne Anmerkung bzw. meine Überlegungen. Einige meiner #defines habe ich ohne Klammern für die Parameterliste geschrieben, siehe oben - einfach um diese von Funktionsaufrufen deutlich zu unterscheiden. Sprich (siehe oben)Code:... #define Led_2_An() SetBit(PORTA,PA1) ...
#define Taste1_an .. IsBitClr (PrtTAST, Tst_1) ........ statt
#define Taste1_an () IsBitClr (PrtTAST, Tst_1) ......,
bzw. in Deinem Fall würde ich schreiben
Led_2_An ...... statt
Led_2_An () ...... .
Für mich macht das Sinn wegen der besseren Lesbarkeit, da diese Schreibweise deutlich den Unterschied zum Funktionsaufruf mit leerer Parameterliste zeigt. Und der Compiler meckert es nicht an. Wie weit ein Profi das gut findet, weiß ich aber nicht.
Vielleicht kannst Du später auch Deine struct-Geschichte nach Erprobung vorstellen?
Ciao sagt der JoeamBerg
Hi oberallgeier,
schau dir das mal an:
In der stdio.h findest du unteranderem diese Zeile:Code:#define SetBit(ADDR,BIT) (ADDR |= (1<<BIT)) #define WasBinIch_1 42 #define WasBinIch_2 SetBit(PORTA,PA0) #define WasBinIch_3() SetBit(PORTA,PA1) void main() { int x = WasBinIch_1; // Hier ist klar, das du eine Variable/einen Wert verwendest WasBinIch_3(); // Hier ist klar, dass was passiert (es sieht wie ein Funktionsaufruf aus) WasBinIch_2; // Was ist das? // Geh' mal von einem Programm aus wo du grade in Zeile 1580 // ließt und nicht das #define-Statement im Blick hast ... ;-) }
"#define getchar() fgetc(stdin)", vermutlich aus den selben Gründen wie oben.
[EDIT] Kleiner Nachtrag: IBM schreibt hierzu: "An empty formal parameter list is legal: such a macro can be used to simulate a function that takes no arguments." http://publib.boulder.ibm.com/infoce...rc09cpxmac.htm
Wenn ich Zeit habe, bastel ich mal ein kleines Beispiel wie ich das mit den Structs meinte
-Crazy
Geändert von CrazyMetal (02.07.2013 um 13:50 Uhr)
Auch wenn der Thread schon geschlossen ist.
Nur mal so als Anregung zum struct. Wenn du das konsequent durchziehen möchtest, wäre es von der Lesbarkeit doch sicher noch besser, wenn du init oder zB Zustandsänderungen auch gleich als Funktionen im struct ablegst.
Ein Aufruf led1.init oder led1.switch(1), led1.switch(0) sollte fürs OOP Verständnis nachvollziehbar sein. Vielleicht kapselst du die Variablen für Port Pin usw auch und baust ein create dazu. Bin mal auf dein Beispiel gespannt.
sast (der findet, dass structs unterschätzt werden)
雅思特史特芬
开发及研究
Hallo Stefan,
es geht nicht um die Nachbildung einer OOP-Funktionalität. Sast schrieb was von
und eine OOP-Denke kann hierbei vom Vorteil sein, muss aber nicht.
Ich sehe den Vorteil von Funktionspointern in der Flexibilität die ich dadurch bekomme, es geht mir nicht um Pseudo-OOP. Vielmehr kann ich so unterschiedliche Funktionen (respektive Verhalten) einem Struct zuordnen (z.B. wann was wie schalten soll..)
Um bei dem LED-Beispiel zu bleiben: Eine LED soll schalten, wenn ein Signal an einem Pin anliegt, die andere soll bei dem Erreichen eines bestimmten ADC-Wert ausgehen. Dafür kann ich einen Funktionspointer mit einer "Aus/An"-Funktion und einen anderen mit "Bedingung erfüllt?"-Funktion verwenden, zudem könnte ich dem Controller über eine Serielle-Verbindung sagen "Wenn der Pin so ist, dann mach mit dem Pin mal das...".
Lesezeichen