Forum: Mikrocontroller und Digitale Elektronik Bitweise Shiften


von Thorsten (Gast)


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!?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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

von Falk B. (falk)


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

von Karl H. (kbuchegg)


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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von Thorsten (Gast)


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??

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.