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
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 ;-)
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
Der zeiger wird im while DEREFERENZIERT also auf den Inhalt zugegriffen. Das geht bei Zeigern in Progme nun einmal per pgm_read_byte/word/... RAM => c = *data; PROGMEM => c = pgm_read_byte(data); EEPRO => c = eeprom_read_byte(data); Siehe http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29
> Warum geht das ab und zu nicht ?
Ich tippe darauf: Weil pgm_read_byte ein macro ist.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.