Optimierungsproblem bei avr-gcc

OP #955069
Lesenswert?

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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren