-
        

Ergebnis 1 bis 9 von 9

Thema: Variablentyp bei Präprozessor

  1. #1

    Variablentyp bei Präprozessor

    Anzeige

    Hallo an Alle!

    Ich kämpfe jetzt schon ein paar Tage lang (mal wieder, muss ich leider sagen) mit dem Präprozessor. Den Ladewert eines Timers möchte ich in Abhängigkeit von der Taktfrequenz durch den Präprozessor berechnen lassen. Ich hatte schon mal ein ähnliches Problem, seinerzeit war das Variablenformat das Problem.

    Code:
    #define Systemtakt              100
    #define F_CPU               14745600
    #define LadewertTimer0       (256-((F_CPU/1024)/Systemtakt))
    
    #if (LaderwertTimer0 == 112)
        #warning "Alles klar!!"
    #endif
    sollte eigentlich als Ergebniss 112 ergeben. Tut es aber nicht. Hier liegt vermutlich auch das Problem beim Variablenformat. F_CPU ist eine uint32_t. Daher wird auch das Ergebniss als uint32_t gespeichert (?). Es reicht aber eine uint8_t. Wie kann man eine entsprechende Zuweisung erzwingen? Cast-Operator, vielleicht? Aber welcher bei uint8_t?

    Bei der Gelegenheit. Gibt es einen eleganteren Weg um das Ergebniss von Präprozessorberechnungen zu prüfen oder vielleicht sogar im Klartext an zu zeigen?

    Bin wie immer für jeden Tip dankbar.


    Viele Grüße

    Bot-Builder
    Legasteniker on Board!
    gefundene Rechtschreibfehler dienen der Belustigung des Lesers und dürfen von diesem behalten werden.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381
    [POSTEDIT]ARRGH mein fehler alten Post gelöscht

    Der Präprozessor kann garnicht rechnen!!!

    er ersetzt nur den Ausdruck vorne durch den Ausdruck hinten

    jetzt hab ich mich aber aufs Glatteis führen lassen!

    wenn du im Programm irgendwo den ausdruck

    LadewertTimer0

    schreibst, wird der stumpf durch den Ausdruck
    (256-((F_CPU/1024)/Systemtakt))

    ersetzt, logischerweise kommt da bei

    LadewertTimer0 == 112 ein Falsch raus!

    LadewertTimer0 == (256-((F_CPU/1024)/Systemtakt)) würde ein Wahr ergeben


    Der Präprozessor ist nur dafür da, dass du deinen Quelltext selber besser lesen kannst und der Compiler ihn noch verstehen kann. Der Präprozessor entfernt alle whitespaces und newlines aus dem Text, ersetzt alle definierten Symbole durch die Ausdrücke die du festgelegt hast (dazu zählt auch #include, die Dateien werden deinem Include entsprechend einfach zu einer großen Textdatei zusammengesetzt) und gibt dann den Ergebnistext an den Compiler! Der Präprozessor macht nur tExtarbeit und rechnet nicht! Er vergleicht bei #if nur ob der Textinhalt derselbe ist nicht den Wert
    Geändert von Ceos (19.09.2011 um 13:09 Uhr)
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  3. #3
    Hallo Ceos!

    Da habe ich leider wieder einmal den Wald vor lauter Bäumen nicht gesehen!

    Zitat Zitat von Ceos Beitrag anzeigen
    Der Präprozessor kann garnicht rechnen!!!
    Habe ich eigentlich im Prinzip gewußt. Was sich aber daraus ergibt, habe ich nicht gesehen.
    Zitat Zitat von Ceos Beitrag anzeigen
    LadewertTimer0 == 112 ein Falsch raus!

    LadewertTimer0 == (256-((F_CPU/1024)/Systemtakt)) würde ein Wahr ergeben
    Ist nun klar.

    Vielen Dank für den Schubs in die richtige Richtung. Habe gerade meinen Code angepasst. Und er funktioniert einwandfrei.


    Viele Grüße

    Bot-Builder
    Legasteniker on Board!
    gefundene Rechtschreibfehler dienen der Belustigung des Lesers und dürfen von diesem behalten werden.

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381
    ich hab mich aber im ersten Moment auch total aufs Glatteis führen lassen und mich fürstlich hingelegt XD ... der Origignalpost war peinlich XD
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  5. #5
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Ceos Beitrag anzeigen
    Der Präprozessor kann garnicht rechnen!!!

    er ersetzt nur den Ausdruck vorne durch den Ausdruck hinten

    jetzt hab ich mich aber aufs Glatteis führen lassen!

    wenn du im Programm irgendwo den ausdruck

    LadewertTimer0

    schreibst, wird der stumpf durch den Ausdruck
    (256-((F_CPU/1024)/Systemtakt))

    ersetzt, logischerweise kommt da bei

    LadewertTimer0 == 112 ein Falsch raus!

    LadewertTimer0 == (256-((F_CPU/1024)/Systemtakt)) würde ein Wahr ergeben
    Das stimmt nicht.
    Er rechnet nicht in Bezug auf das Verändern des C-Codes, da ersetzt er nur stumpf.
    Er rechnet aber sehr wohl innerhalb seines eigenen Gültigkeitsbereichs, also in einer #if-Zeile.

    Das Beispiel im Ursprungsbeitrag scheitert einzig und alleine daran, dass das "LaderwertTimer0" in der #if-Zeile falsch geschrieben ist.
    MfG
    Stefan

  6. #6
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.381
    ... ich sollte meine Kenntnisse mal wieder auffrischen ... ist ja schrecklich was man alles vergisst wenn man mal n Jahr lang nicht mehr damit umgeht!
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  7. #7
    Ich habe gestern Abend die #if Zeile ohne weiteres prüfen rausgenommen. Und Sie gerade wieder reingemacht.

    Code:
    #define F_CPU              1475600    // im makefile definiert
    #define Systemtakt            50
    #define VorteilerTimer0        1024
    #define LadewertTimer0        (256-((F_CPU/VorteilerTimer0)/(Systemtakt*2)))
    
    #if (LadewertTimer0 == 112)
        #warning "Alles klar!"
    #endif
    ....
    ISR (TIMER0_OVF_vect)
    {
        TCNT0 = LadewertTimer0;
    ...
    Die Warnung wird tatsächlich ausgegeben! Als rechnet der Präprozessor bei der Vergleichoperation tatsächlich doch. Und vergleicht nicht nur die reine Textform.

    @Stefan
    Du hast mal in einem anderen Thread erklärt, wie man dem Ergebniss einer Präprozessorberechnung einen Variablentyp aufzwingen kann.

    Code:
    #define        ocr_Wert        ((F_CPU / (1024 * 2 * 50L)) - 1)
    Du hast damals erklärt, des der Ausdruck (1024 * 2 * 50) als int16_t berechnet wird und dann nach uint32_t promotet wird, was zu einem falschen Ergebniss führt. (1024 * 2 * 50L) hingegen wird als int32_t berechnet und damit richtig.

    Hilf mir mal bitte, damit ich das verstehe. F_CPU ist vom Typ int32_t, VorteilerTimer0 ist vom Typ int16_t, das Divisionsergebniss ist ebenfalls vom Typ int16_t. Soweit richtig? Systemtakt ist vom Typ int8_t, das dann folgende Divisonsergebnis ebenfalls int8_t. Und die Differenz dann auch int8_t und damit passend für das Register TCNT0. Habe ich dann richtig verstanden, dass auch für Zwischenergebnisse einer Präprozessorberechnung immer der kleinste benötigte Variablentyp verwendet wird?

    Welches "Symbol" wird verwendet um eine int16_t bzw. eine unit16_t zu erzwingen? L bedeutet int32_t (long) und UL unit32_t (unsinged long), das hast Du schon mal erklärt. int8_t bzw. unit8_t zu erzwingen macht vermutlich keinen Sinn? Und sowas gibt es dann auch nicht?

    Ich weiss, die Fragen sind rein akademisch. Wäre aber schön, wenn Du mich da aufklären könntest. Vielleicht hilft es noch jemand anderem.

    Danke.

    Viele Grüße


    Bot-Builder
    Legasteniker on Board!
    gefundene Rechtschreibfehler dienen der Belustigung des Lesers und dürfen von diesem behalten werden.

  8. #8
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    wie man dem Ergebniss einer Präprozessorberechnung einen Variablentyp aufzwingen kann.
    So was gibt es nicht.
    Der Präprozessor rechnet in seinem eigenen Bereich (#if-Zeilen) nach seinen eigenen Regeln. Mit denen bin ich nicht vollständig vertraut, aber ich bin mir ziemlich sicher, dass er nicht mit unterschiedlichen Typen arbeitet.

    Bei dem ganzen "Typen-Zeug" geht es um C-Berechnungen im Allgemeinen. Dabei spielt es überhaupt keine Rolle, ob ein Teil der Berechnung per Präprozessor-Textersetzung eingebracht wurde, oder nicht. Der Begriff "Präprozessorberechnung" ist hier daher völlig unangebracht und missverständlich.

    Code:
    #define F_CPU              1475600    // im makefile definiert
    #define Systemtakt            50
    #define VorteilerTimer0        1024
    ...
    TCNT0 = (256-((F_CPU/VorteilerTimer0)/(Systemtakt*2)));
    F_CPU ist vom Typ int32_t
    Ja.

    VorteilerTimer0 ist vom Typ int16_t,
    Ja.

    das Divisionsergebniss ist ebenfalls vom Typ int16_t
    Nein, int32_t.

    Systemtakt ist vom Typ int8_t
    Nein, int16_t.

    das dann folgende Divisonsergebnis ebenfalls int8_t
    Nein, int32_t.

    Und die Differenz dann auch int8_t
    Nein, int32_t.

    damit passend für das Register TCNT0
    Bei der Zuweisung wird dann das int32_t Ergebnis auf uint8_t zurechtgestutzt.

    Bei Berechnungen werden die Typen der beiden Operanden aneinander angepasst, wobei der größere Typ den Takt vorgibt (mindestens int), und das (Zwischen-)Ergebnis hat den gleichen Typ.

    Welches "Symbol" wird verwendet um eine int16_t bzw. eine unit16_t zu erzwingen?
    int16_t ist es bereits per Default. "50" ist ein int (äquivalent zu int16_t bei AVR). Ein unsigned macht man daraus mit U. "50U" ist ein unsigned int (äquivalent zu uint16_t bei AVR).
    MfG
    Stefan

  9. #9
    Hallo Stefan,

    danke für Dein Erklärungen:

    Zitat Zitat von sternst Beitrag anzeigen
    Bei Berechnungen werden die Typen der beiden Operanden aneinander angepasst, wobei der größere Typ den Takt vorgibt (mindestens int), und das (Zwischen-)Ergebnis hat den gleichen Typ.
    int16_t ist es bereits per Default.
    Das brings dann ja wohl auf den Punkt.

    Viele Grüße

    Bot-Builder
    Legasteniker on Board!
    gefundene Rechtschreibfehler dienen der Belustigung des Lesers und dürfen von diesem behalten werden.

Ähnliche Themen

  1. Funktion und Variablentyp
    Von steep im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 20.07.2011, 17:36
  2. Welchen Variablentyp bei 'Textinhalten'....
    Von popi im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 16.06.2006, 19:23
  3. Nur Nummern in Array / nur Variablentyp byte als Array?
    Von Crashmichl im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 28.04.2006, 00:15
  4. Binär-Dezimal Präprozessor für Linux gcc
    Von danst im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 26.10.2005, 09:52
  5. Variablentyp von Ports und Pins
    Von timpleton im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 24.10.2005, 11:02

Berechtigungen

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