Julian von Mendel: (C) Funktion soll Pointer zurückgeben

Hallo Welt,

ich programmiere einen Mikrocontroller (Compiler avr-gcc, Library avr-libc), bei dem ich die Register über globale Variablen anspreche. Ich möchte dass eine Funktion eine dieser Variablen als Pointer an eine andere Funktion zurückgibt, so dass diese in das Register schreiben kann. Vereinfacht:

  
uint8_t* a(void)  
{  
     return &PORTB;  
}  
  
void b(void)  
{  
     uint8_t *port = 0;  
     *port = a();  
     /* Weitere Operationen mit *port */  
}  

=> warning: return discards qualifiers from pointer target type
in der Zeile des returns.

Was mache ich falsch?

Schöne Grüße
Julian

  1. Hi Julian!

      
    uint8_t* a(void)  
    {  
         return &PORTB;  
    }  
      
    void b(void)  
    {  
         uint8_t *port = 0;  
         port = a();  
         //*port = a();  
         /* Weitere Operationen mit *port */  
    }  
    
    

    Glaub ich... =)

    MfG H☼psel

    --
    "It's amazing I won. I was running against peace, prosperity, and incumbency."
    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
    1. Hallo Hopsel!

      uint8_t* a(void)
      {
           return &PORTB;
      }

      void b(void)
      {
           uint8_t *port = 0;
           port = a();
           //port = a();
           /
      Weitere Operationen mit *port */
      }

        
      Das lässt eine noch gar nicht beachtete, später auftretende Fehlermeldung tatsächlich verschwinden, ändert an der in Funktion a jedoch nichts.  
        
      Schöne Grüße  
      Julian
      
      -- 
      <http://lighttraffic.de> | <http://derjulian.net>
      
      1. Hi Julian!

        Das lässt eine noch gar nicht beachtete, später auftretende Fehlermeldung tatsächlich verschwinden, ändert an der in Funktion a jedoch nichts.

        Da ich davon ausgehen kann, dass PORTB vom Typ uint8_t ist, fällt mir nichts weiter ein. Dein Code müsste funktionieren. =)

        MfG H☼psel

        --
        "It's amazing I won. I was running against peace, prosperity, and incumbency."
        George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
        Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
        1. Hi,

          Das lässt eine noch gar nicht beachtete, später auftretende Fehlermeldung tatsächlich verschwinden, ändert an der in Funktion a jedoch nichts.

          Da ich davon ausgehen kann, dass PORTB vom Typ uint8_t ist, fällt mir nichts weiter ein. Dein Code müsste funktionieren. =)

          diesbezüglich bin ich unsicher. PORTB referenziert auf eine Position im RAM. Es wird in der avr-libc mit #define PORTB 0x... definiert. Wie kann ich den Variablentyp ermitteln?

          Schöne Grüße
          Julian

          1. Hi Julian!

            diesbezüglich bin ich unsicher. PORTB referenziert auf eine Position im RAM. Es wird in der avr-libc mit #define PORTB 0x... definiert.

            Dies wird der Fehler sein.
            Ohje, da fällt es mir wie Schuppen aus den Haaren.
            Was macht #define? Richtig, es definiert eine KONSTANTE.
            Was macht der Compiler mit #define KONSTANTE foobar? Richtig, er ersetzt jedes Vorkommen von KONSTANTE mit foobar.
            Und was machst du? Du möchtest die Adresse von foobar ermitteln, die es jedoch nicht gibt. =)

            // global  
            uint8_t portB = PORTB;  
              
            uint8_t* a(void)  
            {  
                 return &portB;  
            }
            

            Wie kann ich den Variablentyp ermitteln?

            Da bin ich überfragt. Ich kenne mich mit C nicht sehr gut aus. =)

            Wozu brauchst du eigentlich einen Zeiger?

            MfG H☼psel

            --
            "It's amazing I won. I was running against peace, prosperity, and incumbency."
            George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
            Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
            1. Hi Hopsel!

              Was macht der Compiler mit #define KONSTANTE foobar? Richtig, er ersetzt jedes Vorkommen von KONSTANTE mit foobar.

              Kleine Berichtigung: KONSTANTE wird noch bevor die Datei durch den Compiler gejagt wird durch foobar ersetzt. Das bedeutet, für den Compiler ist der Code

                 #define KONSTANTE foobar  
                 //...  
                 type var = KONSTANTE;  
                 //...
              

              äquivalent zu

                 //...  
                 type var = foobar;  
                 //...
              

              .

              Bsp.:

              //...  
              /* Fehler! Adresse der Zahl 3?  
              Wenn eine per #define definierte  
              KONSTANTE dasteht, ändert das  
              gar nichts. Das Prinzip -  und  
              damit auch der Fehler - bleibt  
              gleich.  
              */  
              int *pPointer = &3  
              //...
              

              MfG H☼psel

              --
              "It's amazing I won. I was running against peace, prosperity, and incumbency."
              George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
              Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
              1. Hi Ich!

                /* Fehler! Adresse der Zahl 3?

                Wenn eine per #define definierte
                KONSTANTE dasteht, ändert das
                gar nichts. Das Prinzip -  und
                damit auch der Fehler - bleibt
                gleich.
                */

                  
                Mal davon abgesehen, dass ich das Semikolon vergessen habe. Wie man´s macht, macht man´s falsch... =)  
                  
                `int *pPointer = &3;`{:.language-c}  
                Jetzt ist es richtig falsch. ;-)  
                  
                MfG H☼psel
                
                -- 
                "It's amazing I won. I was running against peace, prosperity, and incumbency."  
                George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001  
                  
                [Selfcode](http://community.de.selfhtml.org/fanprojekte/selfcode.htm): ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                
            2. Hi,

              uint8_t portB = PORTB;

                
              error: initializer element is not constant  
                
              
              > Wozu brauchst du eigentlich einen Zeiger?  
                
              Funktion a soll einer Pinnummer die benötigten Register zuordnen, damit Funktion b mit diesem Pin arbeiten kann. Dann wird jeder Pin durch eine Nummer identifiziert, die Funktionen übergeben wird, die mit diesem Pin arbeiten sollen. Diese Funktionen rufen Funktion a auf um von dieser die Zuordnung der Register zur jeweiligen Nummer zu erhalten. So wird der Aufruf der häufiger verwendeten Funktionen im Hauptprogramm jeweils um 4 unübersichtliche Parameter vereinfacht.  
                
              Schöne Grüße  
              Julian
              
              -- 
              <http://lighttraffic.de> | <http://derjulian.net>
              
              1. Hi Julian!

                uint8_t portB = PORTB;
                error: initializer element is not constant

                Hast du es schon mit Typumwandlung versucht?
                Wie wird PORTB definiert?

                Bei mir funktioniert die Zuweisung problemlos. Welche Dateien hast du inkludiert?

                MfG H☼psel

                --
                "It's amazing I won. I was running against peace, prosperity, and incumbency."
                George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                1. Hi,

                  uint8_t portB = PORTB;
                  error: initializer element is not constant

                  Hast du es schon mit Typumwandlung versucht?

                  uint8_t portb = (uint8_t)PORTB; liefert das gleiche Ergebnis.

                  Wie wird PORTB definiert?

                  Bei mir funktioniert die Zuweisung problemlos. Welche Dateien hast du inkludiert?

                  #include <avr/io.h>

                  In dieser wird iom8.h speziell für meinen Mikrocontroller inkludiert, welche PORTB als Konstante definiert:
                  #define __SFR_OFFSET 0x20
                  #define _SFR_IO8(io_addr) ((io_addr) + __SFR_OFFSET)
                  #define PORTB   _SFR_IO8(0x18)

                  => PORTB = 0x38

                  Schöne Grüße
                  Julian

                  1. Hi Julian!

                    uint8_t portB = PORTB;
                    error: initializer element is not constant
                    Hast du es schon mit Typumwandlung versucht?
                    uint8_t portb = (uint8_t)PORTB; liefert das gleiche Ergebnis.

                    Okay. Ich habe einen letzten Lösungsvorschlag. Dann weiß ich auch nicht mehr weiter.

                    // global  
                    uint8_t portb;  
                      
                    uint8_t* a(void)  
                    {  
                         portb = PORTB;  
                         return &portB;  
                    }
                    

                    In C ist es nur erlaubt, globale Variablen mit Konstanten zu initialisieren. Ich hoffe, dass ich da keinen Mist erzähle. Warum dein Code dabei Probleme macht, ist mir zwar rätselhaft, aber theoretisch müssten wir das Problem mit obigem Code ja um(ge[1])schifft haben.

                    MfG H☼psel

                    [1] Ich find´ sowas witzig. =)

                    --
                    "It's amazing I won. I was running against peace, prosperity, and incumbency."
                    George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                    Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                    1. Hi,

                      // global

                      uint8_t portb;

                      uint8_t* a(void)
                      {
                           portb = PORTB;
                           return &portB;
                      }

                        
                      dein letzter Lösungsvorschlag funktioniert :) Ich bedanke mich ganz herzlich!  
                        
                      Schöne Grüße  
                      Julian
                      
                      -- 
                      <http://lighttraffic.de> | <http://derjulian.net>
                      
                      1. Hi Julian!

                        dein letzter Lösungsvorschlag funktioniert :)

                        Verwundert dich das? :-P

                        Ich bedanke mich ganz herzlich!

                        Gerne wieder. Halt mich auf dem Laufenden. =)

                        MfG H☼psel

                        --
                        "It's amazing I won. I was running against peace, prosperity, and incumbency."
                        George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                        Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                        1. Hi,

                          dein letzter Lösungsvorschlag funktioniert :)
                          Verwundert dich das? :-P

                          hehe. Ein wenig ja. Die Leute in ##c im Freenode-Netzwerk und zwei C-Experten die ich kenne konnten mir nicht helfen :)

                          Ich bedanke mich ganz herzlich!
                          Gerne wieder. Halt mich auf dem Laufenden. =)

                          Über meine C-Probleme? Hab genug. Kann dir täglich ein paar C-Rätsel schicken ;)

                          Schöne Grüße
                          Julian

                          1. Hi,

                            hab mich geirrt :(
                            Es geht doch nicht. Ich bekomme nur den Wert zurück. Möchte ich was reinschreiben, wird das nicht ins Register übernommen.

                            Schöne Grüße
                            Julian

                            1. Hi Julian!

                              Es geht doch nicht. Ich bekomme nur den Wert zurück. Möchte ich was reinschreiben, wird das nicht ins Register übernommen.

                              Du hast doch die globale Variable portb in die du munter hineinschreiben kannst. Zusätzlich hast du noch die Referenz auf die Variable portb, die du mit uint8_t* pPortB = a(); bekommen hast. Wofür auch immer sie gut sein soll... =) (Schließlich ist die Variable global und du kannst immer auf sie zugreifen. Deswegen auch meine Frage, wofür du den Zeiger überhaupt brauchst.)

                              //global  
                              uint8_t portB;  
                                
                              //...  
                              uint8_t *pPortB = a();  
                              *pPortB = wert;  
                              printf("%d",portb); //Ausgabe: wert  
                              //...
                              

                              Müsste doch funktionieren. Genauso natürlich auch umgekehrt.

                              MfG H☼psel

                              --
                              "It's amazing I won. I was running against peace, prosperity, and incumbency."
                              George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                              Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                              1. Hi,

                                //global

                                uint8_t portB;

                                //...
                                uint8_t *pPortB = a();
                                *pPortB = wert;
                                printf("%d\n",portb); //Ausgabe: wert
                                printf("%d\n",PORTB); //Ausgabe: wert
                                //...

                                  
                                das erste printf liefert ein anderes Ergebnis als das zweite.  
                                  
                                Ich habe Funktionen, die mit einem Pin am Mikrocontroller arbeiten, z. B. setze diesen als aktivierten Ausgang. Damit eine Funktion diese Aufgabe erfüllen kann müssen ihr zwei Register (DDRB, DDRC oder DDRD und PORTB, PORTC oder PORTD) übergeben werden und die Nummer des Pins, für den diese Änderung angewendet wird (PB15 ist z. B. Pin Nr. 1 an Port B). Insgesamt gibt es 23 Aus- bzw. Eingänge die jeweils PORTB, PORTC oder PORTD zugeordnet sind. Ein Port hat 7 bis 8 Pins. Das übergeben dieser Register sieht dann z. B. so aus: io\_set(&PORTB, &DDRB, 1); - äußerst unpraktisch, da sich nicht automatisch alle Pins in einer Scheife durchgehen lassen (bzw. wenn dann ginge es theoretisch nur innerhalb eines Ports, nicht für alle 23 Pins), ich nicht in EINER Konstante die Pinnummer festlegen kann, ich bei einer Pinänderung 3 Variablen ändern muss usw. Deshalb hätte ich gerne, dass ich die Funktion so aufrufe: io\_set(15); io\_set soll dann io\_info aufrufen und sich von io\_info die zu Pin 15 zugehörigen Register abholen. Das würde das Hauptprogramm ungemein übersichtlicher machen.  
                                  
                                Schöne Grüße  
                                Julian
                                
                                -- 
                                <http://lighttraffic.de> | <http://derjulian.net>
                                
                                1. Hi Julian!

                                  das erste printf liefert ein anderes Ergebnis als das zweite.

                                  Das verstehe ich nicht. Irgendein Mysterium muss daran schuld sein.
                                  Was liefert sizeof(PORTB)?
                                  Kann es sein, dass PORTB kein Makro, sondern eine Variable ist? Nach schnellem Überfliegen deiner Projektseite ist mir aufgefallen, dass du PORTB = 0xff; initialisierst. Vielleicht liegt da das Problem.

                                  Ich finde es schon sehr beeindruckend, was du da machst. Ich bin 20 und habe mich vor kurzem (rein theoretisch) mit einem Z80 herumgeschlagen. Das hat mir schon gereicht. =)

                                  Achja, das Schlüsselwort volatile ist ein Typqualifizierer und bittet den Compiler höflich darum, keine Optimierungen an Anweisungen, in denen so definierte Objekte vorkommen, vorzunehmen. Meistens braucht man das, wenn das Objekt zu einem beliebigen Zeitpunkt von außen verändert werden kann. Interrupts z.B. liegen außerhalb der Kontrolle des Programms.

                                  MfG H☼psel

                                  --
                                  "It's amazing I won. I was running against peace, prosperity, and incumbency."
                                  George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                                  Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                                  1. Hi,

                                    Hi Julian!

                                    das erste printf liefert ein anderes Ergebnis als das zweite.

                                    Das verstehe ich nicht. Irgendein Mysterium muss daran schuld sein.
                                    Was liefert sizeof(PORTB)?

                                    1

                                    Kann es sein, dass PORTB kein Makro, sondern eine Variable ist? Nach schnellem Überfliegen deiner Projektseite ist mir aufgefallen, dass du PORTB = 0xff; initialisierst. Vielleicht liegt da das Problem.

                                    Ich bilde mir fest ein, PORTB wäre ein 8-bit Register und 0x37 verweist auf eine Position im Speicher. In meinem momentan verwendeten Programm initialisiere ich PORTB nicht mit 0xff (das war ein Beispiel, das alle 8 Pins an Port B als Ausgang schaltet), sondern setze nur das Bit für meine Status-LED auf 1.

                                    Mittlerweile habe ich das Problem insofern umgangen, dass ich eine Funktion habe, der die Portnummer übergeben wird, die dann eine weitere Funktion mit den Registern als Parameter aufruft. Ist halt insofern sehr unpraktisch, dass sobald ich mehr Funktionen benötige, die mit den Pins arbeiten, ich den Zuordnungs-Teil kopieren müsste. Jetzt ruft man also Funktion b auf, diese ordnet der Nummer die Variablen zu und ruft Funktion a mit den Variablen als Parameter auf. Mein vorheriger, sinnvollerer Ansatz war exakt andersrum, nämlich das Funktion a die Variablen auf Anfrage zurückgibt. Trotzdem vielen Dank für deine liebe Hilfe und deine Geduld mit mir, meine C-Kenntnisse halten sich nämlich in Grenzen. Ich programmiere zwar relativ viel C, aber meistens einfachere Sachen, und ich habe das ganze letzte Jahr diese umständlichen Register übergeben. Jetzt schreibe ich grade eine Bibliothek, die das Hauptprogramm übersichtlicher machen soll. Sie kann jetzt auch schon Ausgänge setzen, Eingänge lesen, analoge Eingänge lesen, einen Neigungssensor einlesen, Servos ansteuern und über die serielle Schnittstelle mit dem Computer reden (sehr praktisch zum Debuggen) :)
                                    Die von dir gelesene Seite habe ich halt geschrieben, um das bisschen Wissen das ich habe anderen Anfängern mitzuteilen, damit diese leichter einsteigen können. Gerade den Anfang fand ich sehr schwierig, da selbst solche primitiven Informationen sehr verstreut sind, anständige Bücher zum Thema gibts kaum. Und so schwer ist es nicht - meinen Mikrocontroller programmiere ich mit sehr grundlegendem C. Das einzig stressige ist, sich für die Hardware-Funktionen im Datenblatt die Bedeutung der Register rauszusuchen.

                                    Schöne Grüße
                                    Julian

                                    1. Hi Julian!

                                      Ich bilde mir fest ein, PORTB wäre ein 8-bit Register und 0x37 verweist auf eine Position im Speicher.

                                      Wir reden aneinander vorbei. Entweder ist PORTB eine per #define bzw. Makro definierte Konstante oder es ist eine Variable. Trifft Ersteres zu [1], kannst du natürlich nicht schreiben, da der Präprozessor vor dem Kompilieren alle Makros und Konstanten einsetzt. Alloziiere doch explizit Speicherplatz für eine Variable PORTB (bzw. einen Zeiger uint8_t *pPortB = (uint8_t*) malloc(sizeof(uint8_t)); ). So hast du definitiv Zugriff auf den Speicherplatz und kannst damit anstellen, was du möchtest.

                                      [1] Was nich möglich ist, wenn du an Funktionen Parameter wie &PORTB übergibst. Das deutet eindeutig darauf hin, dass PORTB eine (globale?) Variable ist.

                                      MfG H☼psel

                                      --
                                      "It's amazing I won. I was running against peace, prosperity, and incumbency."
                                      George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                                      Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
                                      1. Hi,

                                        danke. Ich teste das im Laufe der nächsten Woche nochmal genau.

                                        Schöne Grüße
                                        Julian

                                2. Hallo Julian

                                  Ein wirklich tolles Projekt habt ihr da am laufen, Respekt!

                                  Deshalb hätte ich gerne, dass ich die Funktion so aufrufe: io_set(15); io_set soll dann io_info aufrufen und sich von io_info die zu Pin 15 zugehörigen Register abholen. Das würde das Hauptprogramm ungemein übersichtlicher machen.

                                  io_set() braucht von io_info() zwei Zeiger auf die Register, die verwendet werden sollen sowie die Nummer des Pins am Port. Die Register-Konstanten sind ja eigentlich auch nichts weiter die Adressen, wo sich die Register befinden, also solltest du diese direkt zurück geben können. Weil es mehrere Werte sind verwenden wir für die Rückgabewerte Parameter (Zeiger auf Zeiger). Hier der C-ähnliche Pseudocode (mangels Compiler nicht getestet):

                                  void io_info(int pin_id, int** pddreg, int** pvalreg, int* pin) {
                                    /* Pin von Port A */
                                    if (0 <= pin_id && pin_id <= 7) {
                                      *pddreg = DDRA;
                                      *pvalreg = PORTA;
                                      *pin = pin_id;
                                    } else
                                    /* Pin von Port B */
                                    if (8 <= pin_id && pin_id <= 15) {
                                      *pddreg = DDRB;
                                      *pvalreg = PORTB;
                                      *pin = pin_id - 8;
                                    } else { /* Unbekannter Pin */
                                      *pddreg = null;
                                      *pvalreg = null;
                                    }
                                  }

                                  void io_set(int pin_id) {
                                    int* pDDR;   // Adresse DDR
                                    int* pPORT;  // Adresse Port
                                    int nPin;    // Nummer des Pins
                                    io_info(pin_id, &pDDR, &pPORT, &nPin);
                                    if (pDDR != null && pPORT != null) {
                                      /* DDR auf Ausgang setzen (Annahme: 1 = Ausgang) */
                                      *pDDR |= nPin;
                                      /* Pin setzen */
                                      *pPORT |= nPin;
                                    }
                                  }

                                  Besser wäre noch, wenn du den Erfolg der Aktion über den Rückgabewert prüfbar machst. In deinem eigentlichen Programmcode definierst du dann Konstanten für die Pins, so dass du sie nach belieben vertauschen kannst (1x Kabel umhängen + 1x Konstante anpassen).

                                  Was du hier entwickelst verschönert nicht nur deinen Programmcode, es enkoppelt auch gleich die Programmlogik von der Hardware. Wenn du das konsequent durchziest hast du am Schluss ein sog. HAL, ein Hardware Abstraction Layer. Das hat den Vorteil, dass du deinen Programmcode auch direkt auf dem PC oder einem anderen uC laufen lassen kannst, wenn du dafür eine eigene Abwandlung der HAL-Funktionen schreibst.

                                  Gruss

                                  Tom2

                                  PS: Kennst du http://www.mikrocontroller.net?

                                  1. Hi Tom,

                                    Ein wirklich tolles Projekt habt ihr da am laufen, Respekt!

                                    dankeschön. Du kennst ja jetzt nur den softwaretechnischen Teil der Programmbibliothek, wüsstest du was wir geniales draus bauen fändest du das Projekt noch viel interessanter *g*. In dem nächsten 4 Monaten plane ich die 400 Zeilen C-Code inkl. Dokumentation auf meiner Internetseite zu veröffentlichen

                                    Besser wäre noch, wenn du den Erfolg der Aktion über den Rückgabewert prüfbar machst. In deinem eigentlichen Programmcode definierst du dann Konstanten für die Pins, so dass du sie nach belieben vertauschen kannst (1x Kabel umhängen + 1x Konstante anpassen).

                                    Ist schon so. Die momentane Lösung abstrahiert und funktioniert, lässt sich sauber ansteuern, ist nur programmtechnisch gesehen nicht perfekt, sobald weitere Funktionen benötigt werden, die IOs ansteuern (momentan habe ich nur io_set und io_get um Ein-/Ausgänge zu setzen und Eingänge zu lesen, Funktionen für den Analog-Digital-Konverter z. B. benötigen ja keine speziellen Register für den Pin, sondern nur eine Nummer, die sich aus der IO-Nummer direkt ableiten lässt, die für die Servos können io_set aufrufen, und müssen deshalb ebenfalls keine Register den Pins zuordnen). D. h. ich werde deinen Hinweis und den von Hopsel bei Gelegenheit und Zeit ausprobieren, da das jedoch keine Änderung an der Ansteuerung der Funktionen zur Folge hat und die Änderungen nur für zukünftige Entwicklungen einen Vorteil haben können ist es eigentlich nicht dringend. Danke natürlich für deine Ausführung.

                                    Was du hier entwickelst verschönert nicht nur deinen Programmcode, es enkoppelt auch gleich die Programmlogik von der Hardware. Wenn du das konsequent durchziest hast du am Schluss ein sog. HAL, ein Hardware Abstraction Layer. Das hat den Vorteil, dass du deinen Programmcode auch direkt auf dem PC oder einem anderen uC laufen lassen kannst, wenn du dafür eine eigene Abwandlung der HAL-Funktionen schreibst.

                                    Ja. Die Anpassung der Bibliothek wäre natürlich aber mit einem größeren Aufwand verbunden. Aber du hast recht, theoretisch könnte man einfach durch das Inkludieren einer anderen Datei die Sache mit einem anderen Mikrocontroller laufen lassen. Ein standadisiertes Interface und die Ausgliederung der Hardware-spezifischen Aspekte aus dem Hauptprogramm schadet sicher nicht,

                                    PS: Kennst du http://www.mikrocontroller.net?

                                    Klar. Ich habe in meinem Mikrocontroller-Tutorial (http://derjulian.net/pages/mikrocontroller) mehrmals drauf verwiesen, da das dortige AVR-GCC-Tutorial sehr gut und ausführlich ist.

                                    Schöne Grüße
                                    Julian

                          2. Hi Julian!

                            Über meine C-Probleme? Hab genug. Kann dir täglich ein paar C-Rätsel schicken ;)

                            Ich knobel gerne!

                            MfG H☼psel

                            --
                            "It's amazing I won. I was running against peace, prosperity, and incumbency."
                            George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
                            Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)
        2. Hi Hopsel!

          Da ich davon ausgehen kann, dass PORTB vom Typ uint8_t ist, fällt mir nichts weiter ein. Dein Code müsste funktionieren. =)

          Muss er natürlich nicht. Kann er ja auch gar nicht.

          MfG H☼psel

          --
          "It's amazing I won. I was running against peace, prosperity, and incumbency."
          George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
          Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)