Pointer auf Strings im FLASH?

OP #284006
Lesenswert?
• ▲
▼
Hallo,
vielleicht kann mir jemand bei folgendem Problem helfen. An meinen
ATMEGA 128 habe ich ein LCD-Display angeschlossen, und in C die
Funktion Send_Data_2_LCD(char*) geschrieben, die das senden von Daten
an das LCD erleichtern soll. Der Funktion wird beim Aufruf ein Pointer
mit uebergeben, welcher auf eine Adresse im FLASH zeigt, wo dann die
entsprechende Zeichenkette stehen soll.

Der folgende Code funktioniert aber leider nicht:

main()
{
  static char Zeichenkette1[] PROGMEM = "Hallo Welt";
  :
  :
  Send_Data_2_LCD(Zeichenkette1);
  :
  return;
}

void Send_Data_2_LCD(char* Pointer)
{
  char* temp = Pointer;
  do
  {
    SPDR = *temp;
    :
    :
    ++ temp;
  } while(!temp);
  return;
}

Irgendwie geht beim Funktionsaufruf die Information verloren, wo der
Pointer hinzeigen soll, -RAM oder FLASH-.

Hat jemand eine Idee, wie man das realisieren kann.


Gruesse AstroNookie
Gast #284007
Lesenswert?
• ▲
▼
Hi!

Ich geb dir mal ne UART-Funktion:

const char pgmStartString[] PROGMEM = "ATmega32 online!";

int main (void)
{
   char cUseBuffer[30];

   UART_TxStr(strcpy_P(cUseBuffer, pgmStartString));
}

void UART_TxStr(unsigned char *p_pucString)
{
  while(*p_pucString!=0)
  {
     outp(*p_pucString, UDR);
     loop_until_bit_is_set(UCSRA, UDRE);
     p_pucString++;
  }
}

Kannst du dann für's LCD adaptieren.

Gruß Danyo
OP #284008
Lesenswert?
• ▲
▼
Hallo Danyo,
vielen Dank fuer die schnelle Antwort. Wenn ich das richtig
interpretiere, dann kopierst Du zuerst den String ins RAM, und
uebergibst dann einen Pointer, der ins RAM zeigt.
Daran habe ich auch schon gedacht! :-)

Das ist sicherlich eine Moeglichkeit, wie man das eigentliche Problem
umgehen kann. Aber gibt es denn nicht eine Loesung, wie man den Pointer
der in das FLASH zeigt "richtig" uebergeben kann? Im Prinzip muesste
das was AVR-spezifisches sein, da ja der AVR eine Harvard-Architektur
hat, und die Daten vom Program-Code getrennt sind. Hmmmmmm???

Vielen Dank nochmals Danyo

Beste Gruesse
AstroNookie
OP #284010
Lesenswert?
• ▲
▼
Hallo Joerg,
das mit den zwei Threads war keine Absicht, und da ich nicht weiss, wie
man einen Thread loeschen kann, gibt es nun dummerweise zwei Threads,
sorry. Falls es eine Moeglichkeit gibt den Thread zu loeschen, dann bin
ich ganz Ohr. :-)

Nochmal zum Thema, wie soll die routine putchar das Problem loesen? Was
ich moechte ist eine Funktion, der ich einen Pointer mit auf den Weg
gebe, der in das FLASH zeigt. Aber bislang habe ich so etwas noch nicht
gefunden.

Gruss
AstroNookie
Gast #284014
Lesenswert?
• ▲
▼
Du kannst es von mir aus auch mit einem Pointer auf ein einzelnes
Zeichen machen, aber das wär mir zu umständlich...

const char pgmStartString[] PROGMEM = "ATmega32 online!";

for (int i=0; i<sizeof(pgmStartString); i++) {
      UART_TxChar(pgm_read_byte(&pgmStartString[i]));
}
Gast #284016
Lesenswert?
• ▲
▼
Hallo Danyo,

prinzipiell ne gute Idee. Nur eins scheint mir hier nicht ganz zu
stimmen.

> const char pgmStartString[] PROGMEM = "ATmega32 online!";
> for (int i=0; i<sizeof(pgmStartString); i++) {


sizeof(pgmStartString) liefert Die die Länge des Pointers zurück.
Du brauchst aber die Stringlänge  -  also strlen()
Da strlen() aber nur im RAM geht, bräuchtest Du hier strlen_P()
OP #284020
Lesenswert?
• ▲
▼
Hallo alle,
vielen Dank für eure zahlreichen Tipps. Die ideale Lösung hab ich jetzt
gefunden. Ich kopiere zuerst die Zeichenkette vom FLASH ins RAM, und
übergebe der Funktion einen Pointer, welcher ins RAM zeigt. Zudem habe
ich noch folgenden Define eingefuehrt, damit der Funktionsaufruf noch
etwas uebersichtlicher wird.
   :
   #define Send(x) (Send_String_2_LCD(strcpy_P(StringInRAM, (x))));
   :
Der Funktionsaufruf vereinfacht sich dann zu
   :
   Send(T_Init);
   :
mit T_Init gleich
   :
   char T_Init[] PROGMEM =  "Dieser Text steht im FLASH";
   :
Die eigentliche Funktion die aufgerufen wird, sieht dann so aus.
   :
   void Send_String_2_LCD(char* Pointer)
   {
  char* P_temp = Pointer;
  char temp;

  while(*P_temp != 0)
  {
    SPDR =  temp;
    do {} while(!(SPSR & (1<<SPIF)));
    ++P_temp;
  }
  return;
}

Die Variante, die Zeichenkette direkt ins RAM zu legen geht auch, aber
warume wertvollen RAM speicher verschwenden, wenn man einen 128KB
Speicher hat.

Viele Gruesse,
und Danke

AstroNookie

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