Hallo ich habe den obigen Beitrag gelesen und will mich auch daran halten. Aber mein Prozessor wohl nicht. Ich habe eine Schaltung mit einem Mega 16 aufgebaut. Die geht auch. Am Port PA0 will ich eine Spannung messen (Zwischen 0 und 5 Volt) Da die 5V aus 1024 Stücken bestehen, muss ich den ADC Wert *5 /1024 nehmen. Ich habe am Mega 16 auch eine JTAG Schnittstelle, so dass ich die Operationen verfolgen kann adc16 ist das Korrekte Ergebnis vom AD Programm (uint16_t) Der Wert soll * 5000 genommen werden und dann durch 1024 Dividiert werden Dann hat man das Ergebnis im mV adc16 = (adcval=ADC_Read_Avg(0,10)); Das geht bei fast 4V = 987 adc64 = (adc16 * 5000); adc64 uint64_t adc32 = (adc16 * 5000); adc32 uint32_t adcul = (adc16 * 5000); adcul unsigned long Nach dem schrittweisen Ausführen steht bei Wert (Watch Ansicht) bei allen 3 Variablen 19800 anstatt 4935000 ??? Kann mir jemand helfen was ist falsch? Ich brauche nur eine Zeile, die aber richtig rechnet.
Gast
#5575232
Frank G. schrieb: > Ich brauche nur eine Zeile, die > aber richtig rechnet. Nimm "float" und dann ist es gut!
versuch mal: adc64 = ((uint64_t)adc16) * 5000;
m.n. schrieb: > Nimm "float" und dann ist es gut! Meine Variablen volatile float adcf = 0; volatile uint64_t adc64 = 0; volatile uint32_t adc32 = 0; volatile uint16_t adc16 = 0; Wenn ich im Schritt durchgehe adc16 = 985 adcf adc64 adc32 alle 9800 ?? (ich hatte die Zeile adcf = adc16 * 5000); eingefügt
... unabhängig davon, dass ich den Sinn dieser Rechnerei nicht verstehe.... ein uint64_t gibts zwar beim avr-gcc... imho ist dieser allerdings dennoch bloß 32 Bit groß.
Sinn........... ich möchte einfach nur aus dem Wert z.B.985 die Spannung in mV ausrechnen und wenn bei einer Teiloperation (* 5000) schon Quatsch rauskommt, brauche ich mit dem Ergebnis nicht weiter rechnen.
Gast
#5575256
Nimm 5000UL, dann rechnet er die Multiplikation mit 32 Bit.
@Frank G. (frankg) >Sinn........... >ich möchte einfach nur aus dem Wert z.B.985 die Spannung in mV >ausrechnen Dann solltest du den Artikel Festkommaarithmetik noch einmal in Ruhe lesen, dort steht nämlich alles drin. 64 Bit Operationen braucht man dazu mal sicher NICHT, 32 Bit reichen. Expertentip . . . "Wichtig ist dabei, daß " etc. pp.
Falk B. schrieb: > noch einmal in Ruhe > lesen ....... mach ich, ich bin fast verzweifelt ABER 5000UL GEHT......Danke
Gast
#5575440
Viele Wege führen nach Rom: 1024 und 5000 kann man maximal um 8 kürzen, am besten durch 4, es bleiben 256 und 1250 d.h. statt der Division durch 256 lässt man das unterste Byte weg. Aber es gibt noch eine elegantere Lösung, wenn man sich die Bits und deren Wertigkeit ansieht:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
Alles aus dem Stegreif und ungetestet.
Ralph S. schrieb: > ein uint64_t gibts zwar beim avr-gcc... imho ist dieser > allerdings dennoch bloß 32 Bit groß. Das ist falsch. Wo ein int64 draufsteht, ist auch ein int64 drin. Aber: "double" und "float" sind auf dem AVR gleich.
Gast
#5575540
Wenn man bei adc 1023 5000mV angezeigt haben will:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
@eProfi (Gast)
>Alles aus dem Stegreif und ungetestet.
Und auch völlig daneben. Der Op wollte nicht mehr als einen ADC-Wert in
ein eine Meßgröße umrechnen und nicht irgendwelche Exkurse in die Welt
der Micro- und Nonsensoptimierung unternehmen. Das Ziel erreicht man mit
einer einfachen, übersichlichtlichen Zeile C-Code, die zu 99% auch
vollkommen ausreicht.
Gast
#5575611
Es geht noch schneller, wenn man die Reihenfolge umdreht und die ersten Additionen (solange die Summe in 8 Bit passt), mit 8 Bit ausführt:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
Um den vollen 16-bit-Wertebereich zu nutzen, kann man die addierten Werte mit 8 (nur 4 shifts), 10 (human readable), 13 (65535/5000=13,107), 16 (nur 4 shifts) oder 19 (65535/3300=19,859) multiplizieren (dadurch werden sie genauer) und nach den Additionen wieder dividieren, bringt aber fast nichts.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.