Erstmal wünsche ich ein wunderschönes rest Ostern ;) bin gerade an einem Projekt welches ein Recht "aufwendiges" Menü benötigt. Ich verwende einen Atmega32 mit einem 4x20 Zeichen display. Da ich viele Menüs benötige.Viel Text usw. geht mir der Speicher so langsam zu neige obwohl im Prozessor bis jetzt kaum was ausser die Menüstruktut ist. Jetzt meine Frage nach abhilfe. Externer Speicher !? wie kann ich diesen dann ansprecher und quasi "programm teile aus dem Speicher in den Flash laden zum verarbeiten !?" hoffe ihr habt mein problem verstanden. so on, Gruß, Dennis
Klatsch' für deine Text- und Grafikdaten einfach einen I²C/TWI EEPROM an den 32er.
muss dazu sagen dass ich absoluter neuling bin auf dem gebiet. Kannst du mir grob sagen wie die ansteurung abläuft ? und wie ich den speicher bzw. zum beispiel die gespeicherten textzeilen dann im prozessor code verwenden kann ?
Die Ansteuerung wird über die TWI Schnittstelle stattfinden. Im Code wirst du die benötigten Speicherinhalte zum jeweiligen Zeitpunkt mit entsprechenden TWI-Routinen aus dem Baustein lesen (oder in eben diesen schreiben) und dann verwenden. Pseudocode:
1 | ... |
2 | |
3 | if (Benutzereingabe) |
4 | MenueBauen(); |
5 | |
6 | ... |
7 | |
8 | MenueBauen() |
9 | { |
10 | ... |
11 | |
12 | Puffer = DatenAusEEPROMLesen(PositionImEEPROM); |
13 | DatenZumDisplay(Puffer); |
14 | |
15 | ... |
16 | } |
17 | |
18 | ... |
Hm, der ATmega32 hat 32kiB Flash, was hast du denn für ein Riesending von einem Menü?! Versuch das besser mal zu vereinfachen, sonst blickt nachher kein Schwein durch die Bedienung ;)
Vielleicht liegen hier die Strings zusätzlich im RAM - ist man normales C gewohnt, kann einem das auf einem AVR dank der praktischen Harvard-Architektur passieren. Tip: Suche nach pgmspace.h
Hi, ich verwende hier ein
1 | lcd_puttext(strcpy_P(string20, PSTR("Hello world !"))); |
Welches nur Flash-Platz benötigt. Der string20 ist ein "Unversalstring", den ich nach Bedarf nutze ... Damit habe ich gute Erfahrungen gemacht ... Gruß Andreas
Vielen Dank schonmal ;) werde bei gelegenheit mal den Code posten.. vielleicht findet ihr ja den ein oder anderen Fehler ;) bin wie schon vermutet.. normales C gewohnt ;)
zum beispiel um ein LOGO darzustellen ::: // LOGO !!! void logo(void) { lcd_init(LCD_DISP_ON); // LCD initialisieren lcd_clrscr(); // Clear LCD int time=300; int l=0; while(l!=10) { lcd_gotoxy(1,0);// I !! lcd_puts("II"); _delay_ms(time); lcd_gotoxy(1,1); lcd_puts("II"); _delay_ms(time); lcd_gotoxy(1,2); lcd_puts("II"); _delay_ms(time); lcd_gotoxy(1,3); lcd_puts("II"); lcd_gotoxy(4,3);// M !! lcd_puts("M"); _delay_ms(time); lcd_gotoxy(4,2); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(4,1); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(4,0); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(5,0); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(6,1); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(7,0); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(8,0); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(8,1); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(8,2); lcd_puts("M"); _delay_ms(time); lcd_gotoxy(8,3); lcd_puts("M"); lcd_gotoxy(10,3);// B !! lcd_puts("B"); _delay_ms(time); lcd_gotoxy(10,2); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(10,1); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(10,0); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(11,0); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(12,0); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(13,1); lcd_data(0x7D); _delay_ms(time); lcd_gotoxy(13,2); lcd_data(0x7D); _delay_ms(time); lcd_gotoxy(12,3); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(11,3); lcd_puts("B"); _delay_ms(time); lcd_gotoxy(11,1); lcd_data(0x5F); _delay_ms(time); lcd_gotoxy(12,1); lcd_data(0x5F); lcd_gotoxy(15,3);// A !! lcd_puts("A"); _delay_ms(time); lcd_gotoxy(15,2); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(15,1); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(15,0); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(16,0); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(17,0); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(18,0); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(18,1); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(18,2); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(18,3); lcd_puts("A"); _delay_ms(time); lcd_gotoxy(16,1); lcd_data(0x5F); _delay_ms(time); lcd_gotoxy(17,1); lcd_data(0x5F); _delay_ms(50);_delay_ms(50);_delay_ms(50); lcd_clrscr(); time=0; l++; }
_delay_ms aus der util/delay.h darf nur mit konstanten und zur Compiler-Laufzeit bekannten Werten aufgerufen werden! Sonst wird erstens die ganze Gleitkomma-Lib mit eingebunden (und dann wundert mich ein volles Flash gar nicht, wenn die lib sonst nicht benötigt wird) und zweitens stimmen die Zeiten nicht mehr.
Dennis Henning wrote:
> zum beispiel um ein LOGO darzustellen :::
Sowas ist astreiner Spaghetticode (mit copy&paste endlos die gleichen
Sachen hintereinander).
Ein Speicherfresser erster Güte, da muß man unbedingt optimieren.
Das sind immer dieselben 3 Schritte, also mach ne Schleife daraus.
Und die Schleife holt sich die Position aus einem Byte und das Zeichen
aus dem nächsten. Eine ungültige Position kann man als Endekennzeichen
nehmen.
Diese Tabelle von Werten plaziert man im Flash und ein Pointer darauf
zählt munter hoch.
Wenn ich das richtig sehe, sinds jetzt 16 Byte pro Schritt und im Flash
dann nur noch 2 Byte, also 87% Einsparung!
Peter
>lcd_puts("B");
lcd_puts() für ein einzelnes Zeichen zu verwenden ist Verschwendung.
Da gibt es doch sicher auch ein lcd_putc().
lcd_putc('B');
Oder vieleicht lcd_data('B');
Ein paar Sachen könnte man auch noch mit Schleifen machen.
Meine Güte, da ist ja richtig was aufzuräumen ;)
Ach... herrje. Erster Punkt: Siehe Antwort von Johannes. Zweiter Punkt: Das was du da tust ist sowas Ähnliches wie händisches Loop-Unrolling. Macht man normalerweise zur Laufzeitoptimierung, ist hier aber definiv unnötig. Du könntest z.B. ein Array im Flash ablegen, das die Koordinaten für die einzelnen "Punkte" und das betreffende Zeichen beinhalten und dann in einer einfachen Schleife Zeichen für Zeichen ausgeben. Dürften dann nur noch etwa 10 Zeilen sein. Dritter Punkt: Konstante Strings gehören in's Flash. Es kann sich durchaus lohnen, eine Funktion "lcd_puts(char *s)" und eine "lcd_puts_S(prog_char *)" gleichzeitig zur Verfügung zu haben, dann entfällt z.B. bei
1 | lcd_puts_S(PSTR("blub")) |
die Initialisierung des Strings im RAM. Das wirkt sich üblicherweise positiv auf den RAM- und den Flash-Verbrauch aus. Vierter Punkt: Solche unnötigen Animationen sind doch einfach nur störend. Aber das ist wohl eher deine Entscheidung.
Johannes und Holger haben recht. Da liege ich mit meinen 87% Einsparung voll daneben, dürfte eher schon gegen 99% gehen. Peter
Wenn Du nach dem Optimieren den ATmega32 gegen nen ATmega8535 tauschen kannst, würde mich das überhaupt nicht wundern. Peter
oh man danke.. auch wenn das mit array und strings ablegen im flash für mich noch nach bahnhof klingt.. trotzdem danke für die vielen antworten ;) bin das von der einfachen consolenprogrammierung im DOS nicht gewohnt auf sowas zu achten ;)d as hat der lehrer damals höchstens als bemerkung bemängelt ;)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.