Ah, OK, so genau hatte ich mir das noch nicht angeschaut.
Jetzt habe ich dann mal Write_Zahl angesehen. Kein Wunder das die so
groß wird. 4 int plus 2 char als Parameter, das erzeugt schon mal
fleissig viel Code für den Zugriff auf den Stack. Dazu dann noch die
ganzen Deklarationen plus Initilaisierungen am Anfang der Routine. Sehr
schlecht das ganze. Auch die Berechnung/Zerlegung der Zahl in einzelne
Ziffern, nicht gut. Da wird sehr viel gemacht was so einfach unnötig
ist, da gibt es erheblichen Optimierungs-Spielraum.
So kann man die Berechnung einer einzelnen Ziffer der Zahl erheblich
optimieren. Zuerstmal definiert man sich zwei int oder long int, je nach
gewünschtem Zahlenbereich, plus einen char. Dann baut man sich eine
divmod Funktion, die eine Art Modulo plus Restwert macht. Hier mal ein
Beispiel aus dem Kopf für positive Zahlen bis max. einschliesslich
1000000:
1 | unsigned long value;
|
2 | unsigned long divisor;
|
3 | unsigned char number;
|
4 |
|
5 | void divmod(void)
|
6 | {
|
7 | number = 0;
|
8 | while(value >= divisor)
|
9 | {
|
10 | number++;
|
11 | value -= divisor;
|
12 | }
|
13 | }
|
14 |
|
15 | void print_value(unsigned long value_arg)
|
16 | {
|
17 | value = value_arg;
|
18 |
|
19 | // Ausgabe Million
|
20 | divisor = 1000000;
|
21 | divmod();
|
22 | put_char_lcd('0' + number);
|
23 |
|
24 | // Ausgabe Hunderttausender
|
25 | divisor = 100000;
|
26 | divmod();
|
27 | put_char_lcd('0' + number);
|
28 |
|
29 | // Ausgabe Zehntausender
|
30 | divisor = 10000;
|
31 | divmod();
|
32 | put_char_lcd('0' + number);
|
33 |
|
34 | // Ausgabe Tausender
|
35 | divisor = 1000;
|
36 | divmod();
|
37 | put_char_lcd('0' + number);
|
38 |
|
39 | // Ausgabe Hunderter
|
40 | divisor = 100;
|
41 | divmod();
|
42 | put_char_lcd('0' + number);
|
43 |
|
44 | // Ausgabe Zehner
|
45 | divisor = 10;
|
46 | divmod();
|
47 | put_char_lcd('0' + number);
|
48 |
|
49 | // Ausgabe Einer, keine weitere divmod nötig, da "value" bereits < 10
|
50 | put_char_lcd('0' + value);
|
51 | }
|
Wenn man auch negative Zahlen will, hat man als Argument dann halt eine
signed long, signed int, oder was auch immer. Als erstes packt man dann
anstelle der einfahcen Zuweisung "value = value_arg;" folgendes in die
Funktion:
1 | if(value_arg < 0)
|
2 | {
|
3 | value = -value_arg;
|
4 | put_char_lcd('-');
|
5 | }
|
6 | else
|
7 | {
|
8 | value = value_arg;
|
9 | put_char_lcd('+'); // oder was auch immer man bei pos. Zahlen will
|
10 | }
|
Für der Nummernausgabe der einzelnen Stellen kann man anstelle einer
einfache put_char_lcd() auch eine andere Funktion bauen die dann z.B.
führende Nullen normal ausgibt, oder als Leerzeichen, oder unterdrückt.
Auch dort sollte man das ganze sehr einfach halten, und lediglich die
Ziffer als Argument übergeben. Weitere Parameter wie z.B. ausgabe der
führenden Nullen, Dezimalpunkt, etc. sollte man dur eine einzelne
Funktion einstellen, die wiederum das ganze auch über "globale"
Variablen macht. So spart man sich diese elenden Rattenschwänze an
Parametern. Wenn man dann eine Zahl ausgeben will muss man einfach eine
Folge von Funktionen aufrufen, z.B.:
1 | lcd_set_cursor(cursor_x, cursor_y);
|
2 | print_num_style(leadingzero, decimal_at, ...);
|
3 | print_value(value);
|
Man kann natürlich auch eine "Meta-Funktion" machen die die gesamten
Parameter annimmt und dann ihrerseits die einzelne Funktionen aufruft.
Am wichtigsten ist aber das benutzen der eigenen divmod Funktion. Das
spart schonmal eine Menge Code und somit Platz, weil der ganze unnütze %
und / Kram nicht mehr benutzt wird.
Grüße,
Chris