Hallo zusammen
Bin am verzweifeln. Wenn ich mein Program ohne Optimierung übersetze und
laufen lasse, ist alles ok, wenn ich es mit "-Os" übersetze und laufen
lassen geht's in die Hose.
Problemstellung: In dem Buffer "buffer" steht der variable Wert Knoten/h
aus einem GPS (NMEA 0183) Satz. Diesen möchte ich in Km/h umrechnen,
wenn möglich ohne Float-Werte zu benutzen.
avr-gcc : 4.3.0
avr-libc: 1.6.2
CPU : ATMEGA128 (Maveric IB Board von http://www.bdmicro.com)
Das Problem habe ich soweit eingegrenzt, als dass es etwas mit einer
Multiplikation zu tun hat. Hier eine abgewandelte Version meines Codes
als Beispiel:
1 | char buffer[20];
|
2 | char h_buf[5];
|
3 | uint8_t x =0;
|
4 | uint8_t h_count = 0;
|
5 | char uart_buffer[128];
|
6 | uint32_t speed_g = 0;
|
7 | uint32_t speed_n = 0;
|
8 | uint32_t km_1 = 0;
|
9 |
|
10 | // 1.39 Knoten/h sind ca. 2.574 Km/h
|
11 |
|
12 | sprintf(buffer,"1.39");
|
13 |
|
14 | while (1) {
|
15 |
|
16 | sprintf(uart_buffer,"\r\nBuffer: %s\r\n",buffer);
|
17 | uart_puts(uart_buffer);
|
18 |
|
19 | x =0;
|
20 | h_count = 0;
|
21 | km_1 = 0;
|
22 |
|
23 | // Zuerst mal alles vor dem Punkt (.) in den Hilfsbuffer h_buf schreiben, dabei die
|
24 | // Anzahl der Stellen in h_count zaehlen
|
25 |
|
26 | h_count = 0;
|
27 | while (buffer[x] != '.') {
|
28 | h_buf[h_count++] = buffer[x++];
|
29 | }
|
30 |
|
31 | // Nun auf Grund der gefundenen Stellen den Ganzahlteil der Variablen Speed fuellen
|
32 | // Achtung, h_count beginnt bei 0 also bedeutet 2, dass 3 Stellen vor dem Komma waren ;-)
|
33 |
|
34 | if (h_count == 3) {
|
35 | speed_g = (h_buf[0]-48)*100 + (h_buf[1]-48)*10 + (h_buf[2]-48);
|
36 | } else if (h_count == 2) {
|
37 | speed_g = (h_buf[0]-48)*10 + (h_buf[1]-48);
|
38 | } else {
|
39 | speed_g = (h_buf[0]-48);
|
40 | }
|
41 |
|
42 | // Jetzt kommt der Nachkommateil, der scheint immer zweistellig zu sein
|
43 |
|
44 | x++; // zuerst eines weiter, wir stehen sonst auf dem Dezimalpunkt
|
45 |
|
46 | speed_n = (buffer[x++]-48)*10;
|
47 | speed_n += (buffer[x++]-48);
|
48 |
|
49 | // Nun haben wir den Nachkommateil in "speed_n"
|
50 |
|
51 | sprintf(uart_buffer,"Step1: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
|
52 | uart_puts(uart_buffer);
|
53 |
|
54 | // Nun die Knoten in Km/h umrechnen
|
55 | // Bei 1.39 Knoten sollte speed_g = 1
|
56 | // speed_n = 39 sein
|
57 | //
|
58 | // 1 * 1852 = 1852 m/h
|
59 | // (39 * 1852)/100 = 722.28 m/h (.28 faellt weg)
|
60 | // = 2574 m/h
|
61 | // ergibt speed_g = 2
|
62 | // speed_n = 574
|
63 |
|
64 | km_1 = (speed_g * 1852) + ((speed_n * 1852) / 100);
|
65 |
|
66 | sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
|
67 | uart_puts(uart_buffer);
|
68 |
|
69 | speed_g = km_1 / 1000;
|
70 | speed_n = km_1 % 1000;
|
71 |
|
72 | sprintf(uart_buffer,"Step2: g: %lu n: %lu km_1: %lu \r\n",speed_g, speed_n, km_1);
|
73 | uart_puts(uart_buffer);
|
74 |
|
75 | ms_sleep(3000);
|
76 | }
|
Output ohne Optimierung:
Buffer: 1.39
Step1: g: 1 n: 39 km_1: 0
Step2: g: 1 n: 39 km_1: 2574
Step3: g: 2 n: 574 km_1: 2574
Output mit Optimierung (-Os):
Step1: g: 1 n: 39 km_1: 0
Step2: g: 1 n: 39 km_1: 0
Step3: g: 0 n: 0 km_1: 0
Warum funktioniert die Berechnung:
1 | km_1 = (speed_g * 1852) + ((speed_n * 1852) / 100);
|
unter der Optimierung nicht ? Ich habe alle möglichen Varianten
versucht, aber keine klappt. Bereits ein "km_1 = speed_g * 1852" ergibt
0 in km_1 ? Auch 1852L oder 1852UL in der Berechnung nützt nichts.
Irgendwie suche ich wohl am völlig falschen Ort ? Braucht das noch
andere Compiler/Linker Optionen als nur "-Os" ?
Für einen kleinen Wink mit dem Zaunpfahl wäre ich äusserst dankbar ;-)
Daniel