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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.