- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 21

Thema: DDR und PORT in einem Struct

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.07.2013
    Beiträge
    12
    Zitat Zitat von oberallgeier Beitrag anzeigen
    Deine Lösung finde ich pfiffig, ein bisschen sophisticated aber für mich nicht wirklich besser
    lesbar - und damit auch nicht besser pflegbar. Meine Lösung ist recht konventionell (denke ich)
    und gut lesbar - weil die #define´s schon recht praktisch sind.
    Wie du schon schreibst, es ist Geschmackssache. Dennoch halte ich "sprechende Funktionsnamen" für besser lesbar,
    wenn ich eine Funktion aufrufe die "LedOn()" heißt, weiß ich gleich beim Code lesen was dort vor sich geht. Der Vorteil
    der Wartbarkeit ist hier auch gegeben. Angenommen (als Beispiel) ich habe eine Funktion die LEDs blinken lassen kann,
    dann brauche ich nur die Funktion aufrufen und das LED-Struct übergeben. Zum einen kann ich in einer Zeile lesen was passiert,
    zum anderen: Sollte sich an der Funktionalität des Blinkens was ändern, so ändere ich eine Funktion und die Änderung ist
    umgesetzt, ohne dass ich das Projekt durchsuchen muss und ggf. eine Stelle übersehe wo ich eine Änderung hätte machen müssen.

    Zitat Zitat von oberallgeier Beitrag anzeigen
    Erst mal - ich fühle mich immer noch als C-Anfänger, zumindest nicht als Könner.
    Auch wenn ich gelernter Softwareentwickler bin, so ist C momentan noch Neuland (Achtung: Kanzler-Witz) für mich.
    Dennoch haben sich halt einige Prinzipien für Programmierung und Codegestaltung bisher bei jedem großen Projekt bewährt,
    das ist einer der Gründe, weshalb ich dieses Vorgehen auch bei einem Microcontroller wähle.

    Zitat Zitat von oberallgeier Beitrag anzeigen
    Und strukts sind für mich eben nicht die erste Wahl.
    Ja und Nein. Ich sehe hier einige Vorteile. Mein aktuelles Projekt läuft auf einem ATMEGA128 und hat viele LEDs und einen LED-Bar, die PORTs B, C, E und F sind hierbei teilweise mit LEDs belegt. Wenn ich deinen Code richtig überfolgen habe, so müsste ich pro LED ein define-Statement haben und bei der Verwendung von SetBit noch immer aufpassen, dass ich den passenden Port verwende.

    Meinst du nicht es wäre andersrum einfacher, wenn ich den Schaltplan und das Gerät kenne und im Code lese LedOn(&ledStoerung_1);", hierbei weiß ich gleich worum es sich handelt und was passieren wird.


    Puh! Genug getippt.

    Vielleicht hat ja einer von Euch schon mal einen ähnlichen Stunt gemacht und kann mir sagen wo ich momentan auf dem Holzweg bin.

    Ich habe meine Funktion so geändert
    Code:
    struct LED
    {
    	volatile unsigned char *ddr;
    	volatile unsigned char *port;
    	volatile unsigned char *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);
    }
    leider geht beim STK500 nur die LED 0 (<-- Null) an.

    Viele Grüße,
    Crazy

  2. #2
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    ... Dennoch halte ich "sprechende Funktionsnamen" für besser lesbar, wenn "LedOn()" heißt ...
    Da bin ich völlig Deiner Meinung, ich mache genau das mit meinen #define´s. Und ich zeige das jetzt nicht wegen der Besserwisserei - sondern nur um (m)eine Möglichkeit mit diesen gestuften #define´s aufzuzeigen. Ach so, die Taster schalten gegen GND.

    Code:
    // - - - - - - - - - - - - - - - -
    // in der *.h so:
    // . . .
      #define PrtTAST       PIND    //
      #define Tst_1            6    //
      #define Tst_2            7    //
    ...
      #define Taste1_an     IsBitClr (PrtTAST, Tst_1)       // Taster 1 gedrückt ??
      #define Taste1_aus    IsBitSet (PrtTAST, Tst_1)       // Taster 1 gelöst ??
      #define Taste2_an     IsBitClr (PrtTAST, Tst_2)       // Taster 2 gedrückt ??
      #define Taste2_aus    IsBitSet (PrtTAST, Tst_2)       // Taster 2 gelöst ??
    // - - - - - - - - - - - - - - - -
    //      Im Code so benutzt
    // . . .
        if (TasteA_an)              // Wenn "A" gedrückt, dann hochzählen
        {                           //
          wms (   10);              //
          while (TasteA_an)  {}     // Weiter nur mit gelöster Taste
          while (TasteA_aus) {}     //
          mnuptr ++;                //
          if (mnuptr ==  9) mnuptr = 1;
        }                           //
    // . . .
    // - - - - - - - - - - - - - - - -
    Ciao sagt der JoeamBerg

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    01.07.2013
    Beiträge
    12
    Zitat Zitat von oberallgeier Beitrag anzeigen
    (..) ich mache genau das mit meinen #define´s.
    Und ich zeige das jetzt nicht wegen der Besserwisserei - sondern nur um (m)eine Möglichkeit mit diesen gestuften #define´s aufzuzeigen.
    Don't panic. Ich habe das auch nicht als Besserwisserei verstanden und ich ziehe die Möglichkeit auch in Erwägung, dennoch wäre mir ein Struct schon sehr am Herzen gelegen...

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von CrazyMetal Beitrag anzeigen
    Ich habe meine Funktion so geändert
    Code:
    struct LED
    {
        volatile unsigned char *ddr;
        volatile unsigned char *port;
        volatile unsigned char *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);
    }
    Denk nochmal genau nach, was 'pin' eigentlich sein soll.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    Zitat Zitat von sternst Beitrag anzeigen
    Denk nochmal genau nach, was 'pin' eigentlich sein soll.
    Ach Mist, genau deswegen hatte ich noch mein Tastenbeispiel nachgeschoben - und habs trotzdem übersehen
    Ciao sagt der JoeamBerg

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    01.07.2013
    Beiträge
    12
    Hey sternst,
    vielen Dank für den Schubser, der Wald und die vielen Bäume....
    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);
    }
    Ich habe außerdem den Weg von oberallgeier probiert:
    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)
    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.

    Viele Grüße,
    Crazy

  7. #7
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.698
    Code:
    ...
    #define Led_2_An() SetBit(PORTA,PA1)
    ...
    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)
    #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

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    01.07.2013
    Beiträge
    12
    Hi oberallgeier,
    schau dir das mal an:
    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 ... ;-)
    }
    In der stdio.h findest du unteranderem diese Zeile:
    "#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)

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von sast
    Registriert seit
    30.11.2004
    Alter
    54
    Beiträge
    502
    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)

    雅思特史特芬
    开发及研究

Ähnliche Themen

  1. Zeiger auf Struct in einer Struct
    Von Jaecko im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 11.11.2009, 14:42
  2. Antworten: 8
    Letzter Beitrag: 30.06.2008, 20:54
  3. Fragen zum Wiki. Pin. Port und DDR
    Von Lordcyber im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 22.03.2008, 09:29
  4. RS232 Empfang UND Versand auf einem Port?
    Von RHS im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 22.01.2007, 18:02
  5. Bascom Port,Pin,DDR
    Von Baui im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 07.12.2004, 13:20

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen