Forum: Compiler & IDEs String ausschliesslich im flash...


von Christian (Gast)


Lesenswert?

hallo zusammen,

ich versuche gerade ein string array auschliesslich im flash zu 
belassen..habe aber so meine probleme. kann mir einer helfen? sollte so 
aussehen:

das sollte nur im flash stehen:

const unsigned char stra[4][8]
{
   "Test1",
   "Test2",
   "Test3",
   "Test4"
};

und sollte ich es irgendwie wieder ausgeben sollen:

lcdputstring(stra[i][0]);

danke schon mal

von Peter Fleury (Gast)


Lesenswert?

Bitte AVR-libc lesen:

http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/FAQ.html#faq_rom_array

Eine lokale Kopie dieser Doku befindet sich in
C:\WinAVR\doc\avr-libc\avr-libc-user-manual

von Christian (Gast)


Lesenswert?

hab ich schon..aber ich werde daraus leider nicht schlau..:(

von Peter Fleury (Gast)


Lesenswert?

Du must eine zweite lcdputstring_P Routine schreiben, die die character 
einzeln auf dem Program-Memory liest

Siehe Beispiel debug_P:

http://savannah.nongnu.org/download/avr-libc/doc/avr-libc-user-manual/FAQ.html#faq_flashstrings

von Christian (Gast)


Lesenswert?

mhh...genau das hab ich schon gesehen aber ich lege ja keine string im 
flash ab sondern ein array...ich hab keine ahnung wie diesen blöde array 
auschliesslich im flash abgelegt wird..
ich habe das mal so gemacht:

PGM_P unsigned char menu[4][8]
{
   "Test1",
   "Test2",
   "Test3",
   "Test4"
};

bekomme aber dann jede menge warnings:

lcdtest.c:15: warning: missing braces around initializer
lcdtest.c:15: warning: (near initialization for `menu[0]')
lcdtest.c:13: warning: unused variable `menu'  <-- der ist klar

die frage ist jetzt wäre dann jetzt noch wie ich einen pointer auf eines 
dieser felder erzeugen kann und an diese
__lpm_inline((unsigned short)addr++))) funktion übergeben kann

von Christian (Gast)


Lesenswert?

habs mal so versucht klappt aber leider nicht ganz

lcdputstrP(PSTR(menu[0][0]));

von Christian (Gast)


Lesenswert?

in meinem vorletzte post war ein fehler sieht so aus:


PGM_P menu[4][8]
{
   "Test1",
   "Test2",
   "Test3",
   "Test4"
};

und für die ausgabe so.

lcdputstrP(PSTR(menu[0][0]));
aber es klappt wie gesagt schon nicht mit dem anlegen im flash

von Peter Fleury (Gast)


Lesenswert?

Siehe Beispiel auf AVR-Libc FAQ:
http://savannah.nongnu.org/download/avr-libc/doc/avr-libcuser-manual/FAQ.html#faq_rom_array

--------------------------
include <avr/pgmspace.h>

const char foo[] PROGMEM = "Foo";
const char bar[] PROGMEM = "Bar";

PGM_P array[2] PROGMEM = {
    foo,
    bar
};

int main (void)
{
    char buf[32];
    strcpy_P (buf, array[1]);
    return 0;
}
------------------------

von Christian (Gast)


Lesenswert?

tut mir leid peter das hatte ich übersehen...DANKE

von Christian (Gast)


Lesenswert?

oh gott...habs jetzt so gemacht:

const char text1[] PROGMEM = "Test1";
const char text2[] PROGMEM = "Test2";
const char text3[] PROGMEM = "Test3";
const char text4[] PROGMEM = "Test4";

PGM_P menu[4] PROGMEM = { text1, text2, text3, text4 };

der compiler meckert weiter:

lcdtest.c: In function `main':
lcdtest.c:13: warning: `__progmem__' attribute ignored
lcdtest.c:14: warning: `__progmem__' attribute ignored
lcdtest.c:15: warning: `__progmem__' attribute ignored
lcdtest.c:16: warning: `__progmem__' attribute ignored
lcdtest.c:18: warning: `__progmem__' attribute ignored

von Peter Fleury (Gast)


Lesenswert?

@Christian, ich habe dir ein Beispiel  gemacht:

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

const char text1[] PROGMEM = "Test1";
const char text2[] PROGMEM = "Test2";
const char text3[] PROGMEM = "Test3";
const char text4[] PROGMEM = "Test4";

PGM_P menu[4] PROGMEM = { text1, text2, text3, text4 };


int main(void)
{
    DDRB  = 0xff;


    char buffer[10];

    strcpy_P( buffer, menu[1] );

    PORTB=~buffer[4];   /* output '2' from "Test2" */
    for(;;);
}

von Christian (Gast)


Lesenswert?

danke peter...
ich hab den fehler gefunden...
ich hab das ganze in der main routinen definiert.
sollte das nicht auch gehen??

DANKE...

von Christian (Gast)


Lesenswert?

ach nochwas...sorry...

aber ist es auch möglich ein datenfeld direkt aus dem flash zu schreiben 
ohne das ganze vorher noch in ein buffer zu schreiben?

von Peter Fleury (Gast)


Lesenswert?

Natürlich, dazu muss man byte für byte mit einer speziellen Function 
(Macro) aus dem Flash auslesen:

PORTB=~PRG_RDB(&menu[1][4]);

von Christian (Gast)


Lesenswert?

ok...oh gott..:)..

hab das einfach mal mit PRG_RDB ausprobiert und es 
funktioniert...:)....aber warum ist das in der docu nicht drin? ist auch 
egal ich hab jetzt ein letztes problem und zwar hab ich ja jetzt mit 
dieser zeile "PGM_P menu[4]" ein pointer generiert mein problem ist, das 
ich zwar so mit dem arbeiten kann wie z.B PORTB = PRG_RDB(menu[0][2]) 
aber ich kann den nicht an eine funktion übergben wie z.b


machwas(menu[0][1]);


void machwas(unsigned char *data)
{

}

von Christian (Gast)


Lesenswert?

was ich zumindest möchte, das ist einen pointer auf eines dieser felder 
übergeben und das ganze dann mit PRG_RDB in einer funktion ausgeben.

von Peter Fleury (Gast)


Lesenswert?

Hier ein komplettes Beispiel, siehe Funktion my_strcpy_P()
Wie bereits in meinen früheren Beitragen wie auch in AVR-Libc FAQ 
erwähnt muss eine Funktion die ProgMem String verarbeiten will, diesen 
String Zeichen für Zeichen mit dem Makro PRG_RDB auslesen.


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


const char text1[] PROGMEM = "Test1";
const char text2[] PROGMEM = "Test2";
const char text3[] PROGMEM = "Test3";
const char text4[] PROGMEM = "Test4";

PGM_P menu[4] PROGMEM = { text1, text2, text3, text4 };

static char *my_strcpy_P( char *p, const char *progmem_addr );


/* Copy SRC to DEST. (SRC = Program Memory) */
extern char *
my_strcpy_P( char *__dest, const char *__progmem_src )
{
    char *d = __dest;

    /* we need to copy each byte from program memory */
    while ( (*d++ = PRG_RDB(__progmem_src++)) );

    return __dest;
}


int main(void)
{
    DDRB  = 0xff;


    char buffer[10];

    my_strcpy_P( buffer, menu[1] );

    PORTB=~buffer[4];   /* output '2' from "Test2" */
    PORTB=~PRG_RDB(&menu[1][4]);
    for(;;);
}

von Christian (Gast)


Lesenswert?

ich danke dir für deine geduld und dein bemühen.jetzt läuft alles so wie 
es soll.

von Kjion (Gast)


Lesenswert?

Hi

wieß einer wie jetzt nur einzelne Hex Werte auf die Gleiche Art 
ablege...

const char foo[] PROGMEM = 0xff, 0xaa, 0xff, 0xaa;

so was funktioniert nicht

gruß
Kjion

von Joerg Wunsch (Gast)


Lesenswert?

Du solltest erstmal C-Syntax lernen. ;-)

Da fehlt genau ein Paar geschweifter Klammern drumrum...

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.