Forum: Mikrocontroller und Digitale Elektronik Wie Strings aus dem PROGMEM holen


von Peter Z. (Gast)


Lesenswert?

Hallo allerseits,
1
extern const char PROGMEM Text1;
2
/*
3
4
*/
5
  LCD_printf(0,0,pgm_read_byte(&(Text1)));
6
/*
7
8
*/
9
const char PROGMEM Text1[]="Programmspeicher";
Dies kann sooo nicht funktionieren, es müsste eine pgm_read_string oder 
so was geben. Wo finde ich diese Info?

Schon mal danke :-)

von Michael (Gast)


Lesenswert?

Erstes google-ergebnis "pgm_read_"
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html

da steht alles was du brauchst.

von Uwe (de0508)


Lesenswert?

Hallo,

pgm_read_byte

ließt nur das erste Byte (Zeichen) des Strings, Du musst also noch eine 
Schleife programmieren.

von da1l6 (Gast)


Lesenswert?

Hallo

Entweder du kopierst den String byte-weise in den RAM und gibst ihn dann 
aus, oder (besser) du ergänzt eine LCD_printf_P methode die 
pgm_read_byte verwendet um direkt aus dem Flash auszugeben. Schließlich 
wird das LCD sowieso Byte für Byte beschrieben.

da1l6

von Peter Z. (Gast)


Lesenswert?

YEAH it works!!!!
1
char string_0[] PROGMEM = "Dies ist im";
2
char string_1[] PROGMEM = "Programmspeicher";
3
char string_2[] PROGMEM = "gespeichert";
4
char string_3[] PROGMEM = "  Hallo Welt!  ";
5
char string_4[] PROGMEM = "* * Test 123 * *";
6
char string_5[] PROGMEM = "U=        V";
7
char string_6[] PROGMEM = "I=        A";
8
char string_7[] PROGMEM = " EA DOGS102W-6 ";
9
10
PGM_P string_table[] PROGMEM = 
11
{
12
  string_0,
13
    string_1,
14
    string_2,
15
    string_3,
16
    string_4,
17
    string_5,
18
    string_6,
19
    string_7
20
};
21
//*********************************************************************
22
int main(void)
23
{
24
  unsigned long long int Zahl = 0;
25
  char buffer[17];
26
  LCD_Init();
27
28
  for(unsigned char i = 0;i < 8;i++)
29
  {
30
    strcpy_P(buffer, (PGM_P)pgm_read_word(&(string_table[i])));
31
    LCD_printf(i,0,buffer);
32
  }
33
// usw...

Besten Dank :-)

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:

>     strcpy_P(buffer, (PGM_P)pgm_read_word(&(string_table[i])));
>     LCD_printf(i,0,buffer);

Das ist die 'schlechte' Methode, weil du vorab nicht weißt, wie groß du 
den Buffer allokieren musst. Und derartige Annahmen haben das Zeug dazu, 
irgendwann im Leben eines Programmes ungültig zu werden.

von Peter Z. (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und derartige Annahmen haben das Zeug dazu,
> irgendwann im Leben eines Programmes ungültig zu werden.

Genau,
deshalb werde ich versuchen die LCD_printf um das pgm_read_byte zu 
erweitern und der LCD_printf dann einen Pointer auf den gewünschten 
Nullterminierten String übergeben.

von Peter Z. (Gast)


Lesenswert?

Peter Zz schrieb:
> und der LCD_printf dann einen Pointer auf den gewünschten
> Nullterminierten String übergeben

und das nächste Problem, wie übergebe ich meiner LCD_printf
einen Pointer auf PROGMEM?

von Karl H. (kbuchegg)


Lesenswert?

Peter Zz schrieb:
> Peter Zz schrieb:
>> und der LCD_printf dann einen Pointer auf den gewünschten
>> Nullterminierten String übergeben
>
> und das nächste Problem, wie übergebe ich meiner LCD_printf
> einen Pointer auf PROGMEM?

Einfach als Pointer. PROGMEM brauchst du nur um bei der Definition die 
Werte ins Flash zu verschieben.

Aber zu Dokuzwecken. Wie hast du denn hier
1
PGM_P string_table[] PROGMEM = 
2
{
3
  string_0,
4
    string_1,
5
    string_2,
6
    string_3,
7
    string_4,
8
    string_5,
9
    string_6,
10
    string_7
11
};

ausgedrückt, dass string_table ein Array von Pointern ins Flash ist?

von Karl H. (kbuchegg)


Lesenswert?

> deshalb werde ich versuchen die LCD_printf um das pgm_read_byte
> zu erweitern

Wirf die originale Funktion nicht über Bord. Du wirst sie noch brauchen!

Bei solchen Sachen hat man normalerweise immer 2 Funktionen.
Die eine will normale Pointer ins SRAM haben, die andere Pointer ins 
Flash.

So wie zb
  strcpy          ( kopiert SRAM->SRAM )
  strcpy_P        ( kopiert Flash->SRAM )


Du hast dann eben ein
  LCD_printf      String kommt aus dem SRAM
  LCD_printf_P    String kommt aus dem Flash


Es scheint sich allerdings da auch eine andere Konvention durchzusetzen:
Die Funktion kriegt hinten einen Suffix _p, würde also

   LCD_printf_p

heißen.
Die Variante mit einem großen P würde bedeutet, dass sich dieser 
'Funktionsaufruf' selber darum kümmert, dass der String im Flash landet.

  LCD_printf_P( "Hallo" );

sorgt dann dafür, dass der Text "Hallo" im Flash liegt und ein 
entsprechender Flash-Pointer an die Funktion LCD_printf_p (diesmal mit 
kleinem p) übergeben wird. Gemacht ist es so
1
#define LCD_printf_P(x)   LCD_printf_p( PSTR(x) )

Das PSTR Makro sorgt dafür, dass der konstante Text im Flash bleibt.

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.