
Zitat von
Ceos
Aber man könnte es durch ( R & 0xF8 ) << ( 11-3 ) ersetzen und so wertvolle Takte sparen (kommt auf den Prozessor und seine Intructions an ob ein Bitshift nur einen oder mehrere Takte dauert) ... die 11-3 sollte man natürlich durch 8 ersetzen, damit es ein literal bleibt und nciht erst noch vom vompiler in eine formel verwandelt wird
Für G wäre dass dann ( G & 0xFC ) << 3
Ja, so meinte ich
Früher zu Zeiten, als IBM-Computer die ersten PCs waren und dort noch TTL-Schaltkreise verbaut waren, da war das sicher so, beim 286er glaub ich auch noch. Weil jeder Shift-Befehl normalerweise pro verschobenem Bit einen Takt benötigt. UND könnte daher schneller sein, wenn auf einmal alle Bits verknüpft werden. Allerdings weiß ich nicht, wie das heute ist. Ich könnte mir aber vorstellen, dass bei den neueren CPUs die Shift-Vorgänge auch schon in einem Taktzyklus erledigt werden. Bei Controllern weiß ich es nicht. Da muss mal jemand anders sagen, was schneller geht.
@HaWe
Code:
(R>>3<<11)
?
vermutlich das gleiche wie
((R>>3)<<11)
oder ?
In beiden Fällen passiert dasselbe, mit und ohne Klammer. Bloß wenn man noch mit UND, ODER etc. arbeitet, um Einzelergebnisse zu verknüpfen, sieht das wieder anders aus.
Code:
return (R>>3<<11) | (G>>2<<5) | (B>>3);
ist nicht gleichbedeutend mit
return R>>3<<11 | G>>2<<5 | B>>3;
------------------------------------------------------------
Aber, solch ein Ausdruck:
Code:
(color16 & 2016)/8)
ist logisch eindeutig. Wenn der Compiler gut ist, macht er aus diesem Ausdruck in Maschinensprache das, was auf der Zielhardware am schnellsten verarbeitet wird und setzt also selber Logikbefehle statt Arithmetischer ein. Dann wäre dieser Ausdruck der Universellste.
---------------------------------------------------------------
Sketch
---------------------------------------------------------------
Code:
uint16_t ColorRGB216bit(uint16_t R, uint16_t G, uint16_t B) {
return (R>>3<<11) | (G>>2<<5) | (B>>3); //Ersatzweise: ((R & 248)<<8) | ((G & 252)<<3) | (B>>3)
}
void Color16bit2colorRGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) {
R = (uint8_t) (color16 >> 11) << 3; //Ersatzweise: (color16 >> 8) & 248
G = (uint8_t)((color16 & 2016) >> 3); //Ersatzweise: (color16 >> 3) & 252
B = (uint8_t) (color16 & 31) << 3; //Ersatzweise: (color16 << 3) & 248
Serial.println("");
Serial.println("Unterprogramm color16 zu RGB:");
Serial.println( (String)"color16="+(String)color16);
Serial.println( (String)"R="+(String)R);
Serial.println( (String)"G="+(String)G);
Serial.println( (String)"B="+(String)B);
}
void setup() {
// put your setup code here, to run once:
uint16_t r=255, g=102, b=78,
col16=0; // 0xFF66B2; // Dark Pink (255,102,78)
Serial.begin(115200);
delay(3000);
Serial.println("Hauptprogramm vor Aufruf:");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
Serial.println("");
col16=ColorRGB216bit(r,g,b);
r=g=b=0; // Rücksetzen!
Serial.println("Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
Color16bit2colorRGB(col16, r, g, b);
Serial.println("");
Serial.println("Hauptprogramm nach col16 zu rgb:");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
}
void loop() {
// put your main code here, to run repeatedly:
}
Nochmal die andere (dritte) Variante:
Code:
uint16_t ColorRGB216bit(uint16_t R, uint16_t G, uint16_t B) {
return ((R & 248)<<8) | ((G & 252)<<3) | (B>>3); //Die Klammern müssen so sein, sonst stimmt die Logik nicht
}
void Color16bit2colorRGB(uint16_t color16, uint16_t &R, uint16_t &G, uint16_t &B) {
R = (uint8_t) (color16 >> 8) & 248; //Das funktioniert jetzt ohne zusätzliche Klammerung,
G = (uint8_t) (color16 >> 3) & 252; //weil schon nach dem Shift-Befehl die oberen 8 Bit nicht mehr von Bedeutung sind,
B = (uint8_t) (color16 << 3) & 248; //bzw. die Bits, die wir brauchen, in die unteren 8 Bit verschoben wurden. (uint8_t) richtet keinen "Schaden" mehr an.
Serial.println("");
Serial.println("Unterprogramm color16 zu RGB:");
Serial.println( (String)"color16="+(String)color16);
Serial.println( (String)"R="+(String)R);
Serial.println( (String)"G="+(String)G);
Serial.println( (String)"B="+(String)B);
}
void setup() {
// put your setup code here, to run once:
uint16_t r=255, g=102, b=78,
col16=0; // 0xFF66B2; // Dark Pink (255,102,78)
Serial.begin(115200);
delay(3000);
Serial.println("Hauptprogramm vor Aufruf:");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
Serial.println("");
col16=ColorRGB216bit(r,g,b);
r=g=b=0; // Rücksetzen!
Serial.println("Hauptprogramm nach rgb zu col16-Berechnung (rgb gelöscht):");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
Color16bit2colorRGB(col16, r, g, b);
Serial.println("");
Serial.println("Hauptprogramm nach col16 zu rgb:");
Serial.println( (String)"col16="+(String)col16);
Serial.println( (String)"r="+(String)r);
Serial.println( (String)"g="+(String)g);
Serial.println( (String)"b="+(String)b);
}
void loop() {
// put your main code here, to run repeatedly:
}
getestet sind die.
Lesezeichen