Progmem mit Zeigern auf Funktionen

OP #465576
Lesenswert?
• ▲
▼
Hallo,

ich habe ein kleines Problem mit Progmem.

folgender Kode ( Auszug):

>>>>>>>>>>>>>>>>>>>>>>>


static char  ERROR_USB_RP[]   PROGMEM = "USB Puffer voll";
glcd_write_string_p (ERROR_USB_RP);



/*********************************************************************** 
**********************************************
*Funktion zur Ausgabe eines Strings mit ASCII Zeichen aus dem Flash
*
*Die Zeichen müssen konvertiert werden, da die Anfangsadresse von " " 
die 0 ist ( Datum - 32 )
*  Die Länge des Strings wird durch das Nullbyte festgelegt
*  Die Ausgabe des Strings erfolgt mit dem Blockmodus
*
************************************************************************ 
*********************************************/


unsigned char glcd_write_string_p (char *z_string)
  {
  // Schreiben per Block mit Autoincrement einschalten
  glcd_write_byte (DATA_AUTO_WRITE,'C');
  // Alle Daten per Schleife zum GLCD übertragen, bis das Stringende 
erkannt wird
  while (*z_string != 0)
    {
    // aktuelles Datum aus String lesen, zum GLCD ausgeben
    // und danach den Zeiger auf den String inkrementieren
    glcd_write_byte ( pgm_read_byte (z_string ++) -32 ,'D');
    }
  // Schreiben per Block mit Autoincrement ausschalten
  glcd_write_byte (DATA_AUTO_RESET,'C');
  return 0;
  }

<<<<<<<<<<<<<<<<<<<<

( glcd_write_byte schreibt das jeweilige Datum auf das LCD )

Irgendwie funktioniert dieses nicht.
Eine fast identische Funktion zur Ausgabe eines Strings aus dem
RAM funktioniert tadellos.

-> char *z_string

Wenn ich char zu int mache, funktioniert es teilweise.
char zu klein ? (Inhalt von char die Flashspeicheradresse ?)
Jedes 2. Zeichen wird ausgegeben ( int inkrementieren = Adresse + 2 )
Das wäre ja noch verständlich.

Wie kann ich das am besten lösen, ohne mir ins Knie zu schießen ?


Jogibär
Gast #465582
Lesenswert?
• ▲
▼
Mehrere Probleme:

 while (*z_string != 0)  <==== Funktioniert nicht!
  steht ja im progmem. Zugriff nur über pgm_read_byte!

    pgm_read_byte (z_string ++);   <=== Das ++ "geht so ab und zu 
nicht".


Veränderungsvorschlag:
1
 char c;
2
 while ((c = pgm_read_byte(&z_string[0])) != '\0')
3
    {
4
      // aktuelles Datum aus String lesen, zum GLCD ausgeben
5
      // und danach den Zeiger auf den String inkrementieren
6
      glcd_write_byte ( c - 32 ,'D');
7
      z_string++;
8
    }

So (ähnlich) gehts bei mir ;-)
OP #465585
Lesenswert?
• ▲
▼
Werner B. wrote:
> Mehrere Probleme:
>
>  while (*z_string != 0)  <==== Funktioniert nicht!
>   steht ja im progmem. Zugriff nur über pgm_read_byte!
>
>     pgm_read_byte (z_string ++);   <=== Das ++ "geht so ab und zu
> nicht".
>

Hallo,

warum geht "while ..." nicht ?
Der Zeiger wird doch eigentlich im Ram angelegt und zeigt dann auf die
Programmspeicheradresse, oder ?


pgm_read_byte (z_string ++)

Warum geht das ab und zu nicht ?


Jogibär


OP #465598
Lesenswert?
• ▲
▼
Hallo,


>>>Der zeiger wird im while DEREFERENZIERT also auf den Inhalt zugegriffen.
>>>Das geht bei Zeigern in Progme nun einmal per pgm_read_byte/word/...

Wenn ich das richtig verstehe, zeigt der Zeiger ansonsten in den 
normalen
Ram Bereich.

Per  pgm_read_byte/word/... komme ich dann in den Flash.

Jogibär
Gast #465608
Lesenswert?
• ▲
▼
So isses!
Der Compiler/Prozessor weiss nicht wohin der Zeiger zeigt.
Einer Wert von 123 kann auf ein Speicherstelle im RAM, FLASH, oder ins 
EEPROM zeigen. Der Zeiger selbst ist immer 123 ohne Zusatzinformation. 
Den Speichertyp musst du (zumíndest bei AVR-GCC/WinAVR) dem Compiler 
mitteilen. Nachdem das Sternchen schon für RAM verbraten ist, haben sich 
die Jungs/Mädels die die AVR-LIBC gezaubert haben etwas anderes 
ausdenken müssen...

Werner

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren