Hi alle,
sitze hier zur Zeit an einem Code, der den 10 bit ADC-Wert nach mV
umwandeln soll. Die Rechnung ist da ja prinzipiell einfach:
mv = 5000 * adc / 1024
gekürzt:
mv = 625 * adc / 128
Da adc nun aber bereits 10 bit breit ist, 625 nochmal 10 bit, könnte das
Ergebnis also 20 bit breit werden. Das passt nicht mehr in einen uint16,
also dachte ich, ich nehme einfach einen uint32 her.
Die Umwandlungsroutine sieht dann jetzt so aus:
1 | uint16_t adc2voltage(uint16_t adc_value)
|
2 | {
|
3 | return (625 * (uint32_t)adc_value) / 128;
|
4 | }
|
Verifizieren tu ich die Rechnung durch Ausgabe des Wertes auf einem
LC-Display und einer vorrangehenden Umwandlung des Ergebnisses in einen
String mit folgender Funktion:
1 | void dec2str(int32_t wert, uint8_t anzahl, uint8_t fuell, uint8_t *dest)
|
2 | {
|
3 | uint8_t i;
|
4 | uint8_t sign = fuell;
|
5 | if (wert < 0) {
|
6 | sign = '-';
|
7 | wert *= -1;
|
8 | }
|
9 | for (i = 0; i < anzahl; i++)
|
10 | {
|
11 | dest[anzahl - i - 1] = '0' + (wert % 10);
|
12 | wert /= 10;
|
13 | }
|
14 |
|
15 | for (i=0; i<(anzahl - 1); i++)
|
16 | {
|
17 | if (dest[i] == '0')
|
18 | dest[i] = fuell;
|
19 | else
|
20 | break;
|
21 | }
|
22 | dest[0] = sign;
|
23 | }
|
24 |
|
25 | int main() {
|
26 | ...
|
27 | uint32_t mv = adc2voltage(adc_value); // adc_value kommt von ADC
|
28 |
|
29 | uint8_t str[9];
|
30 | str[8] = 0;
|
31 | dec2str(adc_value, 8, ' ', str);
|
32 | lcd_gotoxy(12, 0);
|
33 | lcd_puts(str);
|
34 | ...
|
35 | }
|
Wenn ich nun die Codeoptimierung aus habe (-O0), dann funktioniert der
Code auch einwandfrei und es wird die korrekte Spannung angezeigt. Wenn
ich die Codeoptimierung aktiviere (egal welches Level), kommen ziemlich
krumme Werte raus. Aktuell zeigt mir das Display für einen ADC-Wert von
50 einen Spannungswert von 64049. Bei 49 kommt 62767.
Wenn ich bei aktivierter Optimierung allerdings adc_valze einen festen
Wert vor der Umwandlung zuordne (zB adc_value = 50), dann stimmt das
Ergebnis auch wieder (244 mV), allerdings scheint der Compiler dann die
Umwandlungsroutine einfach komplett wegzuoptimieren (nach meinen kurzen
einblicken in das Listung zu urteilen ;) ).
Version des AVR-GCC ist 4.3, irgendwo meine ich mal gelesen zu haben,
dass es da Probleme geben könnte ... Kommt nun wirklich der GCC einfach
nicht mit den 32 bit klar, oder ist da sonst irgendwas von mir falsch?
Grüße,
Chris