www.mikrocontroller.net

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


Autor: Owen Senmeis (senmeis)
Datum:

Bewertung
0 lesenswert
nicht 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.
int16_t adc_result;
adc_result = ADC << 6 -32768;

Gibt's Gefahr vom Ueberlauf?

Gruss
Senmeis

Autor: doofi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hindert Dich eigentlich daran das mit dem Simulator mal 
auszuprobieren?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke Du müsstest das Zwischenergebniss auf int casten:
int16_t adc_result;
adc_result = (int16_t)(ADC << 6) - 32768;

Autor: Peter Dannegger (peda)
Datum:

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

Peter

Autor: Oliver (Gast)
Datum:

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

und dann reicht
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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
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
 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.
 int16_t adc_wert = (ADC-512) * 64;
dagegen geht.

Oliver

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oliver wrote:
>
> int 16_t adc_result = -ADC;
> 

Das ist völliger Quatsch.

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


Peter

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.