Hallo,
zur Zeit verwende ich folgende Routine um auf einem 4x27char LCD mit
benutzerdefinierte Zeichen und Sonderzeichen große Zahlen (über alle 4
Zeilen) auszugeben.
Die Routine funktioniert einwandfrei, belegt jedoch einen großen Teil
des Speichers meines Tiny26.
Gibt es irgendeine Möglichkeit die 4 switch-Anweisungen so zu
optimieren, dass sie weniger Speicher benötigen oder gibt es eurer
Meinung nach keine Möglichkeit mehr die Routine noch sinnvoll zu
optimieren ?
Tobias Paul wrote:
> Gibt es irgendeine Möglichkeit die 4 switch-Anweisungen so zu> optimieren, dass sie weniger Speicher benötigen oder gibt es eurer> Meinung nach keine Möglichkeit mehr die Routine noch sinnvoll zu> optimieren ?
Ich sach nur: Tabellen
1
uint8_tZeile1[14][3]={
2
{0,1,2},// 0
3
{0,1,32},// 1
4
{0,1,2},// 2
5
{0,1,2},// 3
6
{1,32,32},// 4
7
{1,1,1},// 5
8
...etc...
9
};
10
11
uint8_tZeile2[14][3]={
12
..dasselbeinGrünfürdie2.Zeile
13
};
14
15
uint8_tZeile3[14][3]={
16
..undnochmalfürdie3.Zeile
17
};
18
19
uint8_tZeile4[14][3]={
20
..undnochmalfürdie4.Zeile
21
};
22
23
voidlcd_big(uint8_tzahl,uint8_tspalte)
24
{
25
// Zeile 1
26
lcd_gotoxy(spalte,0);
27
lcd_putc(Zeile1[zahl][0]);
28
lcd_putc(Zeile1[zahl][1]);
29
lcd_putc(Zeile1[zahl][2]);
30
31
// Zeile 2
32
lcd_gotoxy(spalte,1);
33
lcd_putc(Zeile2[zahl][0]);
34
lcd_putc(Zeile2[zahl][1]);
35
lcd_putc(Zeile2[zahl][2]);
36
37
// Zeile 3
38
lcd_gotoxy(spalte,2);
39
lcd_putc(Zeile3[zahl][0]);
40
lcd_putc(Zeile3[zahl][1]);
41
lcd_putc(Zeile3[zahl][2]);
42
43
// Zeile 4
44
lcd_gotoxy(spalte,3);
45
lcd_putc(Zeile4[zahl][0]);
46
lcd_putc(Zeile4[zahl][1]);
47
lcd_putc(Zeile4[zahl][2]);
48
}
Die nächste Optimierungsstufe würde darin bestehen, die Tabellen
im Flash zu belassen.
Ein paar Bytes können immer noch eingespart werden, indem
man den eigentlichen Ausgabeteil, der ja 4 mal identisch nur
mit anderen Zahlenwerten auftritt, in eine eigene Funktion
auslagert
Jetzt hab ich zwar mehr Programmspeicher frei.
Die Arrays belegen jetzt allerdings zu viel RAM.
vorher:
AVR Memory Usage:
-----------------
Device: attiny26
Program: 1902 bytes (92.9% Full)
(.text + .data + .bootloader)
Data: 1 bytes (0.8% Full)
(.data + .bss + .noinit)
nachher:
AVR Memory Usage:
-----------------
Device: attiny26
Program: 1474 bytes (72.0% Full)
(.text + .data + .bootloader)
Data: 157 bytes (122.7% Full)
(.data + .bss + .noinit)
Wollte dann das Array mit PROGMEM in den Flash-Speicher verschieben, wie
hier im Forum beschrieben, allerdings meckert dann mein Compiler:
Compiling: user_io.c
avr-gcc -c -mmcu=attiny26 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wa,-adhlns=user_io.lst -std=gnu99 -MD -MP -MF
.dep/user_io.o.d user_io.c -o user_io.o
user_io.c: In function 'lcd_big':
user_io.c:55: warning: '__progmem__' attribute ignored
user_io.c:70: warning: '__progmem__' attribute ignored
user_io.c:85: warning: '__progmem__' attribute ignored
user_io.c:100: warning: '__progmem__' attribute ignored
1
voidlcd_big(uint8_tzahl,uint8_tspalte)
2
{
3
4
uint8_tzeile1[13][3]PROGMEM={
5
{0,1,2},
6
{0,1,32},
7
{0,1,2},
8
{0,1,2},
9
{1,32,32},
10
{1,1,1},
11
{0,1,2},
12
{1,1,1},
13
{0,1,2},
14
{0,1,2},
15
{0,1,2},// ° - Zeichen
16
{0,1,2},// C
17
{32,32,32}};// , - Zeichen
18
19
uint8_tzeile2[13][3]PROGMEM={
20
{255,32,255},
21
{32,255,32},
22
{0,1,3},
23
{32,0,3},
24
{255,1,255},
25
{255,1,2},
26
{255,1,2},
27
{32,0,3},
28
{255,1,255},
29
{255,1,255},
30
{255,32,255},// ° - Zeichen
31
{255,32,32},// C
32
{32,32,32}};// , - Zeichen
33
34
uint8_tzeile3[13][3]PROGMEM={
35
{255,32,255},
36
{32,255,32},
37
{255,32,32},
38
{32,5,4},
39
{32,32,255},
40
{32,32,255},
41
{255,32,255},
42
{32,255,32},
43
{255,32,255},
44
{32,32,255},
45
{5,6,7},// ° - Zeichen
46
{255,32,32},// C
47
{32,32,32}};// , - Zeichen
48
49
uint8_tzeile4[13][3]PROGMEM={
50
{5,6,7},
51
{6,6,6},
52
{6,6,6},
53
{5,6,7},
54
{32,32,6},
55
{6,6,7},
56
{5,6,7},
57
{32,6,32},
58
{5,6,7},
59
{5,6,7},
60
{32,32,32},// ° - Zeichen
61
{5,6,7},// C
62
{32,6,32}};// , - Zeichen
63
64
65
// Zeile 1
66
lcd_gotoxy(spalte,0);
67
lcd_putc(pgm_read_byte(&(zeile1[zahl][0])));
68
lcd_putc(pgm_read_byte(&(zeile1[zahl][1])));
69
lcd_putc(pgm_read_byte(&(zeile1[zahl][2])));
70
71
// Zeile 2
72
lcd_gotoxy(spalte,1);
73
lcd_putc(pgm_read_byte(&(zeile2[zahl][0])));
74
lcd_putc(pgm_read_byte(&(zeile2[zahl][1])));
75
lcd_putc(pgm_read_byte(&(zeile2[zahl][2])));
76
77
// Zeile 3
78
lcd_gotoxy(spalte,2);
79
lcd_putc(pgm_read_byte(&(zeile3[zahl][0])));
80
lcd_putc(pgm_read_byte(&(zeile3[zahl][1])));
81
lcd_putc(pgm_read_byte(&(zeile3[zahl][2])));
82
83
// Zeile 4
84
lcd_gotoxy(spalte,3);
85
lcd_putc(pgm_read_byte(&(zeile4[zahl][0])));
86
lcd_putc(pgm_read_byte(&(zeile4[zahl][1])));
87
lcd_putc(pgm_read_byte(&(zeile4[zahl][2])));
88
89
}
90
91
92
voidshow_temperature(uint8_ttemp)
93
{
94
uint8_thunderter=0,zehner=0,einer=0;
95
while(temp>100){temp-=100;hunderter++;}
96
while(temp>9){temp-=10;zehner++;}
97
einer=temp;
98
99
lcd_big(hunderter,2);
100
lcd_big(zehner,6);
101
lcd_big(13,9);// ,
102
lcd_big(einer,12);
103
lcd_big(11,18);// °
104
lcd_big(12,22);// C
105
106
}
@ Peter Dannegger:
Das ganze dient dazu auf einem normalen Text LCD (HD44780) übergroße
Zahlen, die über 4 Zeilen gehen anzuzeigen.
Die Ziffern selbst bestehen dabei aus Sonderzeichen und
benutzerdefinierten Zeichen.
Tobias Paul wrote:
> Wollte dann das Array mit PROGMEM in den Flash-Speicher verschieben,> wie hier im Forum beschrieben, allerdings meckert dann mein Compiler:
Wenn du mal genau mein Beispiel anschaust, dann wirst
du feststellen, dass ich die Arrays global angelegt habe
und nicht in die Funktion hinein gezogen habe.
Jetzt sieht mein Speicherverbrauch schon wesendlich besser aus,
Program: 1444 bytes (70.5% Full)
(.text + .data + .bootloader)
Data: 1 bytes (0.8% Full)
(.data + .bss + .noinit)
ABER jetzt habe ich allerdings Probleme mit der Darstellung der
einzelnen
Zeichen. Obwohl ich in der Funktion show_temperature();, die die
Formatierung und Ausrichtung auf dem Display bestimmt, nicht verändert
hab, sind die Zeichen plötzlich leicht verschoben.
Anstatt 22.5°C steht jetzt 22$5 C. da.
(Wobei das $ für ein misratenes Zeichen stehen soll.)
Du musst in den Tabellen einen Dummy Eintrag
für den Index 10 machen!
In deinem switch-case hast du den Fall zahl==10
ausgelassen.
In der Tabelle muss er aber vorhanden sein!
Genau aus dem Grund waren meine ursprünglichen
Tabellen auch 14 Einträge gross, weil du Code Zahlen
0 bis 13 verwendest und das sind nun mal 14 Stück.
Ohh mein Fehler. Ich vergas was wichtiges.
vorher hatte ich 11,12,13 für die ° , C , . -Zeichen
jetzt durch das Array hab ich 10,11,12.
Jetzt gehts wieder, danke für die Hilfe.
@ Horst (Gast)
>wenn man sich deine Tabellen so anschaut, gibt es da nur>19 verschiedene Eintraege ( statt jetzt 52):>da liesse sich dann auch noch etwas einsparen:>--> 1 Tabelle mit 19x3 und 52 Zeiger auf den jeweiligen Index.
52 Zeiger brauchen weniger Platz?
MFG
Falk