Forum: Compiler & IDEs 10Bit-ADC-Werte in 16Bit-Werte des Zweierkompliments konvertieren


von Owen S. (senmeis)


Lesenswert?

Servus,

ich möchte mit dem AVR-GCC 10Bit-ADC-Werte in 16Bit-Werte des 
Zweierkompliments konvertieren, und zwar left adjusted.

Formel: adc_result = ADC*2^6 - 2^15.

Beispiele:
ADC-Wert = 0h -> Zweierkompliment-Wert = 8000h;  niedrigster Wert
ADC-Wert = 200h -> Zweierkompliment-Wert = 0h;  mitteler Wert
ADC-Wert = 3FFh -> Zweierkompliment-Wert = 7FC0h; höchster Wert

Die Frage ist, ob die folgenden Zeilen dafür geeignet sind.
1
int16_t adc_result;
2
adc_result = ADC << 6 -32768;

Gibt's Gefahr vom Ueberlauf?

Gruss
Senmeis

von doofi (Gast)


Lesenswert?

Was hindert Dich eigentlich daran das mit dem Simulator mal 
auszuprobieren?

von Peter (Gast)


Lesenswert?

Ich denke Du müsstest das Zwischenergebniss auf int casten:
1
int16_t adc_result;
2
adc_result = (int16_t)(ADC << 6) - 32768;

von Peter D. (peda)


Lesenswert?

Das Schieben ist überflüssig, für left adjusted einfach nur das Bit des 
ADC setzen.

Peter

von Oliver (Gast)


Lesenswert?

>Das Schieben ist überflüssig, für left adjusted einfach nur das Bit des
>ADC setzen.

und dann reicht
1
int 16_t adc_result = -ADC;

um das zu erreichen, was du möchtest.

Das das 2-er Komplement ja nichts anderes ist, als Darstellung negativer 
Zahlen. Das umrechnen machten Compiler bzw. Prozessor schon für dich.


Oliver

von Oliver (Gast)


Lesenswert?

Nachtrag:

>...um das zu erreichen, was du möchtest.

ist allerdings beim genaueren Hinsehen doch etwas diffus.

>ich möchte mit dem AVR-GCC 10Bit-ADC-Werte in 16Bit-Werte des
>Zweierkompliments konvertieren, und zwar left adjusted.

hat nichts mit

>ADC-Wert = 0h -> Zweierkompliment-Wert = 8000h;  niedrigster Wert
>ADC-Wert = 200h -> Zweierkompliment-Wert = 0h;  mitteler Wert
>ADC-Wert = 3FFh -> Zweierkompliment-Wert = 7FC0h; höchster Wert

Mein Beispiel
1
int 16_t adc_result = -ADC;
bei "right-adjustedtem" Ausgabewert des ADC konvertiert die ADC-Werte 
left adjusted in das entsprecheden 2er-Komplement, und zwar ALLE. Das 
wäre die Lösung zu deine ersten Problembeschreibung

ADC 0 -> 0
ADC 1-> -1 = 0xFFFF
...
ADC 1023 -> -1023 = 0xFC01

Wenn du, wie dein Beispiel zeigt, der niedrigste Wert 0x8000 sein soll, 
und der mittlere 0x00, wäre es eine Verschiebung des Wertebereichs mit 
Skalierung.

ADC 0 -> -32768 = 0x8000
ADC 512 -> 0 = 0x0000
ADC 1023 -> 32704 = 0x7FC0

Bei der nahe liegenden Formel
1
 int16_t adc_wert = ADC * 64 - 32768;
gibt es bei Rechnung mit int16_t tatsächlich einen Überlauf, da alles 
größer 511*64 nicht mehr als int darstellbar ist.
1
 int16_t adc_wert = (ADC-512) * 64;
dagegen geht.

Oliver

von Peter D. (peda)


Lesenswert?

Oliver wrote:
>
1
> int 16_t adc_result = -ADC;
2
>

Das ist völliger Quatsch.

Also:
1
ADMUX |= 1<<ADLAR;
2
adc_result = ADC - 0x8000;


Peter

von Oliver (Gast)


Lesenswert?

>>Das ist völliger Quatsch.

ist auch Quatsch. Es erfüllt wörtlich die Anforderung

>ich möchte mit dem AVR-GCC 10Bit-ADC-Werte in 16Bit-Werte des
>Zweierkompliments konvertieren, und zwar left adjusted.

was allerdings nicht das ist, was eigentlich gewünscht ist.

Oliver

von Karl H. (kbuchegg)


Lesenswert?

Oliver wrote:
>>>Das ist völliger Quatsch.
>
> ist auch Quatsch. Es erfüllt wörtlich die Anforderung
>
>>ich möchte mit dem AVR-GCC 10Bit-ADC-Werte in 16Bit-Werte des
>>Zweierkompliments konvertieren, und zwar left adjusted.
>
> was allerdings nicht das ist, was eigentlich gewünscht ist.

Wobei ich mich frage, was denn eigentlich gewünscht wird.

von Peter D. (peda)


Lesenswert?

Karl heinz Buchegger wrote:
> Wobei ich mich frage, was denn eigentlich gewünscht wird.

Das hatter doch unmißverständlich hingeschrieben:

Owen Senmeis wrote:
> ADC-Wert = 0h -> Zweierkompliment-Wert = 8000h;  niedrigster Wert
> ADC-Wert = 200h -> Zweierkompliment-Wert = 0h;  mitteler Wert
> ADC-Wert = 3FFh -> Zweierkompliment-Wert = 7FC0h; höchster Wert



Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.