Hallo Ihr, ein Anfänger hat ein Problem mit einem Stringarray im Flash. Randbedingungen: Compiler Avr-GCC MCU: Atmega103 -------Code------- const char text1[] PROGMEM = "Parameter laden "; const char text2[] PROGMEM = "Parameter ändern "; const char text3[] PROGMEM = "Parameter senden "; PGM_P dmenu[9] PROGMEM = { text1, text2, text3}; int main(void) { char buffer[10]; strcpy_P( buffer, dmenu[1] ); lcd_putc(buffer) for(;;); } So funktioniert es, wenn ich nun aber das Array im Progmem nicht direkt anspreche [1], sondern über einen Variablenindex [var], dann geht es nicht mehr. Also so: int main(void) { unsigned int disp; char buffer[10]; disp=1; strcpy_P( buffer, dmenu[disp] ); lcd_putc(buffer) for(;;); } Kann mir jemand helfen,was ich falsch mache? Gruss Günter
Sorry, mit nicht funktionieren meine ich, dass der String der aufs Display geschrieben wird versaut ist. Also irgendwelche zeichen, aber nicht die gewollten. Also zugriffsfehler im Speicher.
Das hier: dmenu[1] will etwas aus dem RAM lesen. Du hast aber explizit gesagt, daß das im ROM sein solle. Da mußt Du Dich vorher mit __lpm_inline drum kümmern, daß es aus dem ROM erstmal in (temporären) RAM kommt. Oder aber, Du läßt zwar die Strings selbst im ROM, aber das Array nicht. 6 Bytes RAM dafür sind ja nicht gerade viel. Du würdest mehr RAM sparen, wenn Du das nicht erst mit strcpy_P() in einen temporären RAM-Puffer kopieren müßtest, sonder gleich ein lcd_putc_P() noch lieferst, das die Strings direkt aus dem Flash verarbeiten kann.
Hallo Jörg, nun hast Du mich ganz verwirrt... Aber trotzdem mal: Hab die LCD-Routinen von Peter Fleury verwendet. Dort ist ja auch ein lcd_puts_p dabei, das ein String stück für stück aus dem Progmem liest und dann aufs Display schickt. Aber auch da hab ich das selbe Problem. Soll heissen, ich kann mein Stringarray direkt addressieren, in dem ich die lcd_putc_p routine, wie auch oben beim strcpy_P, mit ner Zahl als Index aufrufe. Aber sobald ich die Zahl mit ner variablen ersetze, springt er mir zum Teufel... Begreif das im Moment noch nicht... wo ist der Unterschied zwischen dmenu(2) und dmenu(test), mit test=2; Oder steh ich jetzt so gnadenlos auf dem Schlauch? Gruss Günter
Nein, was Du noch nicht begriffen hast ist, daß Du das Herauspopeln aus dem Flash grundsätzlich erstmal selbst vornehmen mußt, wenn Du etwas im Flash ablegst. Der Compiler tut das nicht für Dich. Von daher ist es keine sonderlich praktische Idee, das Array selbst im Flash anzulegen, sondern laß für das Array all die PROGMEM & Co weg, dann funktioniert es.
Für dieses kleine Array kann es schon sinnvol sein, das Array im RAM abzulegen. Aber z.B. bei einer komplexen Menu-Struktor sollte das Array und der Text im Flash abgelegt werden. Wenn der Index eine konstante ist (dmenu[2]), kann der Compiler der Flash-Adresse einfügen: lcd_puts_p( dmenu[1] ); Wenn der Index aber eine Variable ist, muss man die Adresse mittels LPM Befehlen herauslesen: for (i=0; i<3; i++) lcd_puts_p( PRG_RDW(&dmenu[i]) ); Im <avr/pgmspace.h> gibt es zwar ein PRG_RDB() Makro, aber kein PRG_RDW() Makro, ich habe deshalb folgendes definiert: #define PRG_RDW(a) (PRG_RDB((a))+0x100*PRG_RDB((uint16_t)(a)+1)) Besser wäre allerding wenn man PRG_RDW() als Inline-Asm realiseren würde und <avr/pgmspace.h> ergänzen würde. p = (char *)PRG_RDW(&menu[menuState].text); lcd_puts_p(p);
Hallo Joerg und Peter, vielen Dank fürs "unter die Arme Greifen"... nun hab ichs geschnallt... und siehe da: ES funktioniert! Jubel. Nochmals Danke.... Grüssle Günter
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.