Forum: Compiler & IDEs Zugriff auf Strings im Flash


von Karl (Gast)


Lesenswert?

Hallo Zusammen!

Folgendes Code Beispiel funktioniert nicht:

#include <avr/pgmspace.h>

const char LCD_Line0[] PROGMEM = "Zeile0";
const char LCD_Line1[] PROGMEM = "Zeile1";

PGM_P LCD_Screen[2] PROGMEM =
{
    LCD_Line0,
    LCD_Line1
};

int main (void)
{
  char buf[16];
  for (i = 0; i < 2; i++)
  {
    strcpy_P (buf, array[i]);
  }
  return (0);
}

Wenn ich die Variable "i" beim Zugriff auf das Array-Element durch
z.B. die "1" ersetze dann klappt es. Ich suche eine Lösung um es mit
der Variablen zu bewerkstelligen.

Besten Dank schon mal,
Karl

von Volkmar (Gast)


Lesenswert?

So ganz verstehe ich es nicht: In Deiner Schleife verwendest Du
'array' aber definiert hast Du es nicht. Ich denke, Du meinst
'LCD_Screen' an dieser Stelle, oder?

Egal, um auf Deine eigentliche Frage zurückzukommen:
Da Du nicht nur die Texte ins Flash gelegt hat, sondern auch das Array
mit den Pointern dazu, mußt Du diese auch erst aus dem Flash auslesen.
D.h. statt
    strcpy_P (buf, array[i]);
brauchst Du
    strcpy_P (buf, pgm_read_word(array[i]));

Ist hier auch schon mehrfach besprochen worden. ZB hier:
http://www.mikrocontroller.net/forum/read-2-137055.html#137164

von Thomas (Gast)


Lesenswert?

naja, was heisst denn eigentlich "funktioniert nicht" und "klappt" ?
heisst das "kompiliert schon gar nicht" oder "der uC geht in flammen
auf" ?

von Karl (Gast)


Lesenswert?

@Volkmar:
Ja, dass Array heißt nicht array[] sondern LCD_Screen[]. Mein
Fehler...
Ich hab zwar schon nach verwandten Themen gesucht aber dieses nciht
gefunden. Ich werd es heute Abend gleich mal testen. Besten Dank!

@Thomas:
"Funktioniert nicht" heißt, dass ich den String via LCD-Display
anzeigen möchte und das LCD nur wild flackert und überhaupt nichts mehr
funktioniert.
"Klappt" heißt, dass die Anzeige auf´s LCD ohne Probleme
funktioniert.
Du hast recht, ich hätte das besser erklären müssen.

von Tobias Tetzlaff (Gast)


Lesenswert?

Hallo,

ich weiß zwar nicht, ob es weiterhilft, aber

#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/pgmspace.h>

// Eine Möglichkeit Daten in den Programmspeicher zu legen
prog_char Tabelle_1[]={0x30,0x31,0x32,0x33,0x34,0x35};
prog_char Tabelle_2[]={0x41,0x42,0x43,0x44,0x45};

// Noch eine Möglichkeit
const char Text_1[]PROGMEM="TextText 11111";
const char Text_2[]PROGMEM="TestText 22222";


void main(void);

//-------------------------------------

void main(void)
{
  char  i;

  for(i=0; i<5; i++)
  {
    // Lesen (Daten der Tabelle_1 plus Offset (i) )
    // und PortB Zuweisen
    PORTB = PRG_RDB(Tabelle_1 + i);
    // Tabelle_2 nach PortC
    PORTC = PRG_RDB(Tabelle_2 + i);
  }

  for(i=0; i<5; i++)
  {
    // Auf PortD werden 5 Zeichen vom Text_1 ausgegeben
    PORTD = PRG_RDB(Text_1 + i);
  }
}


Gruß Toby

von Jörg Wunsch (Gast)


Lesenswert?

Da du es mehr als einmal gepostet hast:

PRG_RDB gibt's nicht mehr.

Bitte nimm pgm_read_byte.

von Karl (Gast)


Lesenswert?

Ich habe es wie folgt umgebaut und es funktioniert immer noch nicht!

#include <avr/pgmspace.h>

const char LCD_Line0[] PROGMEM = "Zeile0";
const char LCD_Line1[] PROGMEM = "Zeile1";

PGM_P LCD_Screen[2] PROGMEM =
{
    LCD_Line0,
    LCD_Line1
};

int main (void)
{
  char buf[16];
  for (i = 0; i < 2; i++)
  {
    strcpy_P (buf, pgm_read_word(LCD_Screen[i]));
  }
  /* Hier steht Code, der im 50 ms Zyklus dafür sorgt, dass die 2
Zeilen des LCD´s beschrieben werden.*/

  return (0);
}

Nach dem Flashen flackert das LCD nur wild und zeigt nichts an.

Was mache ich falsch??????

von A.K. (Gast)


Lesenswert?

strcpy_P (buf, pgm_read_word((&LCD_Screen[i]));

von Karl (Gast)


Lesenswert?

Das hatte ich ebenfalls ausprobiert. Ohne Erfolg! Wenn ich es so mache
wie Du vorschlägst bekomme ich zusätzlich folgende Compilerwarnung:
-> warning: passing arg 2 of `strcpy_P' makes pointer from integer
without a cast

von A.K. (Gast)


Lesenswert?

Die Warnung sollte eigentlich immer kommen - pgm_read_word liefert
integer, strcpy will Pointer.

von Karl (Gast)


Lesenswert?

Und was bedeutet das jetzt?
Muss ich mit der Warnung leben?

Mitlerweile bin ich wirklich am Verzweifeln. Ich bin ja nicht der erste
der dieses Problem hier hat. Die Lösungen bei anderen funktionieren
scheinbar (zumindest schreiben Sie es). Ich möchte lediglich über einen
Index auf Array-Elemente zugreifen die im Flash stehen und diese dann
via LCD anzeigen lassen.

-> Was mache ich falsch???!!!???

von A.K. (Gast)


Lesenswert?

Die Warnung geht weg mit
  strcpy_P (buf, (PGM_P) pgm_read_word(&LCD_Screen[i]));
ist aber nicht das Problem.

Das Problem kann ich in dem gezeigten Code nicht erkennen.

von Karl (Gast)


Lesenswert?

Kann es daran liegen, dass ich pgm_read_byte (..) anstatt
pgm_read_word(..) verwenden muss?

von A.K. (Gast)


Lesenswert?

Nein. Es geht ja um den Pointer. Auf den String greift strcpy_P zu.

von Jens (Gast)


Lesenswert?

Hallo,

Ich haette da ein entfernt aehnliches Problem, vielleicht kann mir da
jemand den entscheidenden Tip geben:

struct cmdtab_st
{
    /* comand token */
    PGM_P CmdToken;
    /* comand description */
    PGM_P CmdDescr;
};

const struct cmdtab_st cmdtab[] = {
    { PSTR("help"), PSTR("print help message\r\n")}
};

wird nicht uebersetzt, es waeren keine Klammern innerhalb eines
Ausdruckes erlaubt. Ich nehme mal an das er die PSTR(..) Anweisungen
nicht mag, aber wie kann ich eine Tabelle von Struct's im
Programmspeicher ablegen ohne die Strings alle einzeln definieren zu
muessen.

Jens

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
Noch kein Account? Hier anmelden.