PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Bitte um Erläuterung dieses Codes



RCO
12.12.2004, 21:47
Also da ich ein echter C-Noob bin und auch relativ wenig Ahnung von den gazen registern der verschiedenen AVRs habe, würde ich mich freuen, wenn mir jemand den folgenden Ausschnitt erklären könnte.
Es geht dabei um die Konvertierung eines ADC-werts in eine Variable deren einzelne Bits quasi verschiedene Stufen sind. Das war jetzt vermutlich ziemlich undeutlich, deshalb versuche ich es mit einem Beispiel:
Wird z.B. ein bestimmter Wert an den ADC gelegt, so wird nciht der Wert zurück geliefert, sondern je nach höhe des Wertes eben nur das entsprechende bit in einem Byte.
Da es insgesamt nur 7 mögliche Eingangssignale, jedoch alle auch durcheinander gemischt gibt, wird dann jedem Wert, falls angelegt, quasi das entsprechende Bit zugeordnet.
Ich hoffe das war verständlich :-)


unsigned char PollSwitch (void)
{
unsigned int i;

DDRD |= SWITCHES; // Switches as Output
SWITCH_ON; // Output HIGH for measurement
ADMUX = (1 << REFS0) | SWITCH; // AVCC reference with external capacitor
Sleep(10);

ADCSRA |= (1 << ADSC); // Start conversion
while (!(ADCSRA & (1 << ADIF)));// wait for conversion complete
ADCSRA |= (1 << ADIF); // clear ADCIF
i = ADCL + (ADCH << 8 ) ;

SWITCH_OFF;

return ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));
}

Mein größtes Problem ist dabnei das verständniss dieses Auszugs:

i = ADCL + (ADCH << 8);

und dieser anschließenden Berechnung

((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5)

Soweit ich weiß handelt es dabei um einen 10 Bit-ADC, deshalb vermutlich die 1024.

Falls hier wichtige Teile oder Informationen fehlen sollten, sagt mir bitte bescheid.

Ich würde mich sehr über eure Hilfe freuen, deshalb schon mal Danke im Voraus.

P.S.: Wem das ganze bekannt vorkommt, es ist ein Auszug aus der Asuro.c-Datei.

MFG Moritz

12.12.2004, 22:06
Hallo

Der AD Wandler gibt einen 10 Bit Wert zurück, der nach der Wandlung in ADCL und ADCH steht.

In ADCL stehen die unteren 8 Bits, in ADCH die oberen 2 Bits.

Mit unsigned int i; wird eine 16 Bit Variable definiert.

i = ADCL + (ADCH << 8 ) ; sorgt dafür, das der AD Wert wieder richtig in der Variablen i steht. Dafür wird ADCH 8 Bits nach links geschoben in der Variablen i und danach ADCL addiert.


MFG
Dieter

RCO
12.12.2004, 22:18
Danke, das klingt einleuchtend.
Der gesamt Teil bis zu return dient also nur der Bestimmung einen 10-Bit ADC-werts, oder?

Wie aber ist die genaue Reihenfolge der Umrechnung unten und was meint float mittendrin?

Ist die Reihenfolge so reichtig:

Erg=1024/i
Erg=Erg-1
Erg=Erg x 63
Erg= Erg+0,5

MFG Moritz

13.12.2004, 07:22
Warum nicht einfach das Datenblatt konsultieren, zu einfach?

#define VREF 5
unsigned short ad_wert = 0;
float spannung = 0;
ad_wert = ADC; //Verwendung von ADCH und ADCL ist überflüssig

spannung = ((float) ad_wert)/1024 * VREF;

Steht aber auch alles im Datenblatt ...

RCO
13.12.2004, 08:34
Wie gesagt, ich bin ein C-noob und muss die Anweisung erstmal kapieren um zuverstehen, was in dieser Funktion überhaupt vor sich geht, bevor ich mich dransetzen kann um das Problem anders zu lösen. Mir ist z.B. immer noch nicht klar, was das float mitten in der Berechnung meint.
Was meint denn genau "ADMUX = (1 << REFS0) | SWITCH" bzw. welche Bits von admux werden hier gesetzt?

MFG moritz

13.12.2004, 11:41
Warum suchst du nicht einfach mal im Datenblatt nach REFS0? Das sollte dir die Erleuchtung bringen.

Dann fehlt dort Code, denn SWITCH ist nirgendwo definiert (es fehlt auch eine Klammer).

Wenn du noch nicht einmal weißt, warum man beim Arbeiten mit Brüchen zwangsläufig keine Ganzzahlen mehr rausbekommt also eine Gleitkommadarstellung braucht, dann würde ich dir ein C-Buch zum Einstieg empfehlen.

RCO
13.12.2004, 20:49
Also wie auch immer, ich habe es jetzt hinbekommen, nachdem ich stundenlang durch internetseiten geforstet bin.

@ Gast:
Man muss ja zumindest mal wissen, das float dann einfach so da stehen darf, und worauf es sich bezieht. Das entscheidende, wobei ich vermutet habe, dass es irgendwo in den ganzen mir fremden Pseudonymen steht, ist dass bei der Umrechnung nicht bestimmt Werte nur rauskommen können, sondern alles von dem Eingang abhängt. Hier bin ich einfach von anderen Gegebenheiten ausgegangen, deshalb auch meine etwas blöde Nachfragerei.
Switch habe ich auch im restlichen Code nciht gefunden, deshalb bin ich ja davon ausgegeangen, dass es eine bedeutung in C hat, aber scheinbar schaltet es nur einen bestimmten Pin ein.
Das ist es ja gerade, ich wollte mich nicht mit einem C-Buch beschäftigen müssen, um dieses bisschen zu verstehen.

Wie dem aus sei... danke für die Hilfe.

MFG Moritz

martin
13.12.2004, 21:43
Hallo RCO,


spannung = ((float) ad_wert)/1024 * VREF;

(float) ist ein sogenannter Typecast, der benutzt wird, um ad_wert von integer auf float zu 'casten'. Sonst würde bei der Berechnung ein ganzzahliger Wert rauskommen, der ziemlich klein sein kann. Bei Integer dann 0 :-(

Da du das nicht willst, castest du vorher ad_wert auf float, somit ist das Ergebnis auch Float und kann der Float-Variable spannung richtig zugewiesen werden.

Grüsse, Martin

RCO
13.12.2004, 22:21
Ja, das hab ich vermutet, aber war mir nicht ganz sicher.
Soweit ich weiß gibt es in Bascom keine Befehle dazu, oder. Aber das ist vermutlich auch das falsche Forum dafür.

MFG Moritz