Forum: Mikrocontroller und Digitale Elektronik Frage zu einem Code


von Birger M. (neulich)


Lesenswert?

Hallo,

ich habe eine Frage zu folgendem Programm-Code den ich als Beispiel-Code 
bei WinARM gesehen habe. Also der Code funktioniert!
1
while(1) {
2
3
ADCR  |= (1UL<<24);  /* Start A/D Conversion (START:0=1) */
4
while ((ADDR & (1UL<<31)) == 0); /* Wait for the conversion to complete (DONE=1)*/
5
val = ((ADDR >> 6) & 0x03FF);  /* Extract the A/D result */
6
chan = ((ADDR >> 24) &0x0007); /* Channel (should be 0)  */
7
    
8
iprintf ("AIN%i: Digital Value %4u = %01u.%04u Volts\n",
9
  chan, (unsigned) val,
10
  (unsigned) (val * VREF) >> 10,                          /* Output Integer Portion */
11
  (unsigned) ((val * VREF * 10000UL) >> 10UL) % 10000);   /* Output Decimal Portion */
12
13
} // while

Mich interessiert die iprintf-Ausgabe. Und zwar der letzte Teil wo:
((val  VREF  10000UL) >> 10UL) % 10000 steht.
Was geschieht hier genau?

Val ist meine Variable in der der Wert vom A/D-Board steht. VREF ist 
fest auf 345/100 definiert.

Ich bekomme beispielsweise bei val den Wert 420 und als umgerechnetes 
Ergebnis 1,4150V.

Die erste Rechnung mit (val * VREF) >> 10 kann ich noch nachvollziehen. 
In der würde 420 * 345/100 stehen und es kommt heraus = 1449. Nur warum 
dieses schiften um 10?

Und wer kann mir die letzte Berechnung erklären mit der 
Modulo-Anweisung? Ich komme einfach nicht auf die 1,4150V die mir das 
Programm errechnet hat.

Danke

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>>10 ist teilen durch 1024

Vielleicht nützlich, um die 1024 zu verstehen
Beitrag "Re: Divisions Rest wandeln"

von Birger M. (neulich)


Lesenswert?

Ah danke.
Mit der Teilung durch 1024 verstehe ich es endlich und komme auch auf 
das Ergebnis.

von Birger M. (neulich)


Lesenswert?

Könntest du mir vielleicht auch erklären warum die in ihrem Beispiel 
eine so komische Rechenart gewählt haben? Man hätte doch auch den 
analogen Wert (val) mit VREF (345/100) mal nehmen können.
Denn mit dieser Zusatzrechnung kommt man eher vom tatsächlichen 
Ergebnis, welche ich mit dem Messgerät nachgemessen habe ab.

von ozo (Gast)


Lesenswert?

Schieben geht schneller als Multiplikation/Division.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Meinem Link und dem Link dort drin bist du offensichtlich nicht gefolgt. 
Dort wird es erklärt. Die Autoren wollen die Fliesskommarechnung 
vermeiden und nur mit Ganzzahlrechnung arbeiten. Das kann sinnvoll sein, 
um den Platz für Fliesskommaroutinen im µC einzusparen und um schnelle 
Programme zu schreiben.

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

ob aber ein % 10000 auf einem ARM wirklich schneller ist als eine 
Fließkommamultiplikation die in Software emuliert wird?

Matthias

von A.K. (Gast)


Lesenswert?

Tempo kann's nicht sein, da im printf() sowieso beliebig oft dividiert 
wird. Je nach Platform spart das allerdings die Fliesskommaroutinen ein, 
und damit Platz im ROM. Allerdings m.W. beim WinARM nur dann, wenn man 
das printf() der newlib meidet.

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.