www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitweise Shiften


Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

wir haben im Rahmen der Vorlesung Mikroprozessortechnik ein ATMega128 
Evaluation Board bekommen und arbeiten zu Zeit an einer Umsetzung des 
DTMF Verfahrens. Ich lese mit dem ADC und einem Soundeingang Werte ein 
und unser Prof hat uns gesagt, dass man den Wert den man vom ADC bekommt 
erst in einer singed variable speichert und dann folgende Operation 
ausführen muss:

//variablendeklaration
signed int value;

//codeabschnitt
value = ADC;
value = ((value<<6)>>6);

Der ADC-Wandler ist ein 10Bit Wandler, also das Ergebnis steht praktisch 
in 2 8Bit Registern.

Ich verstehe nicht ganz den Sinn dieser Operation, da beim schieben nach 
links einfach Nullen von rechts nachgeschoben werden und wenn man nun 
eine signed Variable nach rechts verschiebt von links Einsen 
nachgeschoben werden.
Diese Operation soll ja dem Erhalt des Vorzeichens dienen wenn ich das 
richtig verstanden habe. Aber dann würde das Vorzeichen ja bei jeder 
Zahl eine 1 sein oder nicht???

Kann mir da bitte jemand helfen!?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:
> Ich verstehe nicht ganz den Sinn dieser Operation
Zeichne dir das mal auf und denk dran:
das MSB im 10-Bit-Wort ist das Vorzeichen

1.) im ADC
0000 0011 1001 1111
2.) nach <<6
1110 0111 1100 0000
3.) und jetzt wird (hoffentlich Vorzeichenkorrekt) >>6 gemacht
1111 1111 1001 1111

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Thorsten (Gast)

>erst in einer singed variable

Hmm, das wär mir neu.

>value = ADC;
>value = ((value<<6)>>6);

Was soll das bringen? Hat der AVR nicht genug zu tun?

>Diese Operation soll ja dem Erhalt des Vorzeichens dienen

Das macht der C-Compiler auch alleine. Aber der Wert vom ADC ist ohne 
Vorzeichen.

MFG
Falk

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

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:

> //variablendeklaration
> signed int value;
>
> //codeabschnitt
> value = ADC;
> value = ((value<<6)>>6);
>
> Der ADC-Wandler ist ein 10Bit Wandler, also das Ergebnis steht praktisch
> in 2 8Bit Registern.
>
> Ich verstehe nicht ganz den Sinn dieser Operation,

Ich auch nicht.
Besser ist es, eine mathematische Operation auch als solche auszudrücken 
anstatt sich da mit Bitschieberein selbst ein Bein zu legen.

Wenn man den Zahlenbereich 0 - 1023 so umformen will, dass sich Zahlen 
von -512 bis +511 ergeben, man also den 0-Punkt in die Mitte des 
Intervalls bringen will, dann zieht man einfach 512 ab und spart sich da 
das Rumgeschiebe.

Denn wenn man das mal auf Biteben mit ein paar Zahlen durchprobiert, 
sieht man nämlich, dass da ein ziemlicher Blödsinn rauskommt.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:
> Diese Operation soll ja dem Erhalt des Vorzeichens dienen wenn ich das
> richtig verstanden habe. Aber dann würde das Vorzeichen ja bei jeder
> Zahl eine 1 sein oder nicht???
Das würde nur Sinn machen, wenn es ein 10-Bit AD-Wandler wäre, bei dem 
Werte über 512 negativ wären...
Mag sein, dass dein Prof sowas mal eingesetzt hat, und sich dann seine 
Hirnwindungen zerknotet und auf dieses gloriose Konsturkt gekommen ist.

In der Praxis ist es aber besser, den AD-Wert zu nehmen und mit 
"normalen" Rechenfunktionen zum gewüschten Ergebnis hinzuführen. das 
kapiert man auch noch nach einem halben Jahr...

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schonmal Danke Leute für eure Hilfe!

Allerdings hatte ich noch vergessen zu sagen dass ich eine 
differentielle Messung mache also ADC0 - ADC1 multipliziert mit einer 
Verstärkung von 10.
An ADC0 hängt ein Poti mit dem man den Offset einstellen kann.

Also meine Initialisierung des ADC sieht folgendermaßen aus:

void init_adc(void)
{
  ADMUX = 9;  //differential conversion ADC1-ADC0
  ADCSR |= BIT(ADEN) | BIT(ADFR); //enable ADC, free running
  ADCSR |= BIT(ADPS2) | (ADPS1) | (ADPS0); //set prescaler 125kHz
  ADCSR |= BIT(ADIE); //enable interrupt
  ADCSR |= BIT(ADSC); //start conversion
}

Hat es vielleicht damit was zu tun dass er diese Operation durchführt??

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.