- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 4 von 4

Thema: Aufteilung int16_t in zwei int16_t, Fehler durch 0ptimierung ?

  1. #1
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.678

    Aufteilung int16_t in zwei int16_t, Fehler durch 0ptimierung ?

    Anzeige

    Praxistest und DIY Projekte
    Bitte um Hilfe oder Erklärungen.

    Aufgabe:

    Eine Routine wird mit einem int16_t-Parameter aufgerufen, Beispiel 2008. Beliebige Werte unter 15 (hier die 8 ..) sollen in eine Variable int16_t Il* übernommen werden, Werte über 15 sollen sinngemäß in eine Variable int16_t Iv* übernommen werden. Beide Zielvariablen müssen 16 Bit breit sein.

    Mein Code läuft nur mit Tricks - möglicherweise wird etwas wegoptimiert, wahrscheinlicher finde ich meinen fehlerhaften Umgang mit C. Die folgenden Schnippsel zeigen zwei Versionen der betreffenden Routine, wobei nur die zweite Version mit einer Hilfsvariablen läuft.

    Der Offset von 1 bei der Umwandlung in den grösseren Wert ist möglicherweise in der Zahlendarstellung begründet, mir ist aber nicht klar, wieso das beim kleineren Wert ohne diese Korrektur geht.


    Code:
      volatile int16_t  Iv_sound;       // Sound - Vorgabe = maximaler Faktor => Tonhöhe
      volatile int16_t  Il_sound;       // Soundlänge in tupsi, wird in ISR..COMPB decrem.// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //Aufruf:
      beep ( 2008 );        // Soundausgabe zur Anmeldung                          inf
    
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      Version geht nicht
      void beep ( int16_t paramtr )         // Soundausgabe Einzelton, parameterisierbar
     {                                      //
      Iv_sound  = paramtr &= 0x000F;        // Soundfaktor (Tonhöhe)
      Il_sound  = paramtr &= 0xFFF0;        // Sounddauer
     }              // Ende von void beep ( int16_t paramtr )
    // Dabei ist Iv_sound 8 und Il_sound 0
    
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    //      Version geht
      void beep ( int16_t paramtr )         // Soundausgabe Einzelton, parameterisierbar
     {                                      //
      int16_t   dummy   = paramtr;
      Iv_sound = dummy &= 0x000F;           // Soundfaktor (Tonhöhe)
      Il_sound = (paramtr &= 0xFFF0) + 1;   // Sounddauer
     }              // Ende von void beep ( int16_t paramtr )
    // ============================================================================= =
    Ein C-Tutorial zur Bitmanipulation brachte mir keine Hilfe.
    Ciao sagt der JoeamBerg

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578
    Hi,

    ich glaube, der Fehler liegt darin, dass du bei
    Code:
    Iv_sound = paramtr &= 0x000F;
    die Variable paramtr veränderst?!
    So sollte es gehen:
    Code:
    Iv_sound = (paramtr & 0x000F);
    I1_sound = (paramtr & 0xFFF0);
    Gruß
    Chris

  3. #3
    shedepe
    Gast
    Ja genau. In deinem Code verundest du paramtr mit 0x000F weist das dann paramtr zu und weist dann das Ergebniss Iv_sound zu.

  4. #4
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.678
    ... der Fehler liegt darin, dass du ... die Variable paramtr veränderst?! ...
    Danke Chris. Das war superschnell und hilfreich. Ich hatte das schon mit ner Klammer probiert, aber eben dazu noch den Zuweisungsoperator.

    ABER : beim
    Code:
    Il_sound = (paramtr & 0xFFF0);
    kommt trotzdem eins weniger raus (Kopie der Terminalausgabe) siehe Nachtrag unten :
    HTML-Code:
     Beep Aufruf mit 2008
     Beep 8 1999


    .. In deinem Code verundest du ... weist das dann paramtr zu und weist dann das Ergebniss Iv_sound zu.
    Ach ja, "Vorrang und Assoziativität von Operatoren" im K&R - gibts ja ne Extra Tabelle die ich (natürlich - ähhh - leider) nicht im Kopf habe. Ist ja auch das vorletzte bedruckte Blatt . . .

    - - - - - - - -
    Nachtrag: Die "Eins weniger" ist geklärt. Die Variable wird anschließend in einer 50µs-ISR runtergetickert - und die testweise UART-Ausgabe braucht eben auch Zeit. Mit "cli();" und "sei();" an der richtigen Stelle passiert das nicht mehr.

    Danke für die Hilfe.
    Geändert von oberallgeier (09.11.2013 um 16:48 Uhr) Grund: Assoziativität und andere unbekannte Dinge/ Nachtrag
    Ciao sagt der JoeamBerg

Ähnliche Themen

  1. 7Segmentanzeige auslösen durch zwei Tasten in bestimmter Zeitfolge / Attiny 24
    Von Joschi1711 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 20.02.2012, 15:51
  2. itoa nimmt höchstens int16_t mit nem AVR??
    Von yaro im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 29.05.2009, 19:32
  3. RP6 Lib Aufteilung
    Von Lurchi im Forum Robby RP6
    Antworten: 1
    Letzter Beitrag: 14.05.2009, 21:07
  4. Antworten: 24
    Letzter Beitrag: 10.03.2008, 21:09

Berechtigungen

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

LiFePO4 Speicher Test