mikrocontroller.net

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


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte AVR-libc lesen:

http://savannah.nongnu.org/download/avr-libc/doc/a...

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

Autor: Christian (Gast)
Datum:

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

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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/a...

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habs mal so versucht klappt aber leider nicht ganz

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

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Beispiel auf AVR-Libc FAQ:
http://savannah.nongnu.org/download/avr-libc/doc/a...

--------------------------
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;
}
------------------------

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tut mir leid peter das hatte ich übersehen...DANKE

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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(;;);
}

Autor: Christian (Gast)
Datum:

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

DANKE...

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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]);

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)
{

}

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Fleury (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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(;;);
}

Autor: Christian (Gast)
Datum:

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

Autor: Kjion (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Joerg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du solltest erstmal C-Syntax lernen. ;-)

Da fehlt genau ein Paar geschweifter Klammern drumrum...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.