Forum: Mikrocontroller und Digitale Elektronik Pointer an Funktion übergeben AVR C


von Jing P. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
Ich brauche eine Funktion, die einen String in ein Array schreibt. 
Dieses Array wird dann auf einen OLED Display ausgegeben (SSD1306). Dazu 
habe ich mir ein Testprogramm geschrieben (im Anhang), wobei die 
Funktion write_string_to_OLED_buffer jedoch nicht funktioniert.
Nach etwas testen kam ich zu dem Ergebnis, dass ich, wenn ich den Inhalt 
des Strings in der Funktion neu schreibe (über den Pointer), auch etwas 
ausgegeben bekomme.
Ebenfalls möglich ist es, Zeile 47 von
*buffer_pointer = font[*string_pointer][d];
zu
*buffer_pointer = font['A'][d];
zu ändern, halt mit der Wirkung, dass ich 5x ein A ausgegeben bekomme.
Zeile 32 & 33 dienen nur dem Test, ob der Rest funktioniert (was er 
tut).
In einem anderen Thread habe ich gelesen, dass evtl. der String nicht in 
den Speicher geschrieben wird. In meinem Makefile konnte ich nichts 
finden, was darauf schließen lässt, bin allerdings auch nicht sehr 
bewandert darin.
Es wäre schön, wenn mir da jemand bei helfen könnte.

viele Grüße,
Tristan

von Dirk B. (dirkb2)


Lesenswert?

Bist du dir bei *string_pointer++ wirklich zu 100% sicher?
(Das funktioniert zwar, aber der * ist überflüssig)

von René H. (Gast)


Lesenswert?

Das kann so nicht stimmen, würde ich sagen:
1
void write_string_to_OLED_buffer (unsigned char* buffer_pointer, char *string_pointer)
2
{
3
  for (int i = 0; i < 5; *string_pointer++, buffer_pointer++, i++)
4
  {
5
    for (unsigned char d=0; d < 5; d++, buffer_pointer++)
6
      *buffer_pointer = font[*string_pointer][d];
7
  }
8
}

würde wohl eher so sein müssen:
1
void write_string_to_OLED_buffer (unsigned char* buffer_pointer, char *string_pointer)
2
{
3
  for (int i = 0; i < 5; string_pointer++, buffer_pointer++, i++)
4
  {
5
    for (unsigned char d=0; d < 5; d++, buffer_pointer++)
6
      *buffer_pointer = font[string_pointer][d];
7
  }
8
}

Weshalb Du in der for Schleife <5 nimmst, erschliesst sich mir nicht....

von Stefan E. (sternst)


Lesenswert?

Wie viel RAM-Verbrauch (Font-Daten) steckt denn in 5x8_vertikal_LSB_1.h?

Denn ...
1
int main (void)
2
{
3
  unsigned char OLED_buffer[1024] = { 0 };
4
  unsigned char* buffer_pointer = &OLED_buffer[0];
5
  unsigned char ret_value = 0;
6
  unsigned char string [] = "Hello World";
... über 1k auf dem Stack zu allozieren, ist eine ganz schöne Hausnummer 
auf einem Controller, der insgesamt nur 2k RAM hat.

von Dirk B. (dirkb2)


Lesenswert?

Warum hast du in beiden for-Schleifen ein  buffer_pointer++ ?

von Falk B. (falk)


Lesenswert?

@Tristan V. (jing-peng)

>Ich brauche eine Funktion, die einen String in ein Array schreibt.

Das ist das kleine 1x1.

>Funktion write_string_to_OLED_buffer jedoch nicht funktioniert.

Logisch. Eher so.
1
void write_string_to_OLED_buffer (unsigned char* buffer_pointer, char *string_pointer)
2
{
3
  char c;
4
  int i;
5
6
  while(c = *string_pointer) {
7
    for (i=0; i < 5; i++, buffer_pointer++) {
8
      *buffer_pointer = font[c][d];
9
    }
10
    string_pointer++;
11
  }
12
}

von Isolde (Gast)


Lesenswert?

> würde wohl eher so sein müssen:void write_string_to_OLED_buffer
> (unsigned char* buffer_pointer, char *string_pointer)
> {
>   for (int i = 0; i < 5; string_pointer++, buffer_pointer++, i++)
>   {
>     for (unsigned char d=0; d < 5; d++, buffer_pointer++)
>       *buffer_pointer = font[string_pointer][d];
>   }
> }


Ist auch falsch!!!

von Dirk B. (dirkb2)


Lesenswert?

@Falk

bei Nicht-ASCII-Zeichen (über 127) kann c negativ werden (wenn char 
signed ist)
Das kommt als Index nicht ganz so gut.

von Fontspezialist (Gast)


Lesenswert?

Falk B. schrieb:
> *buffer_pointer = font[c][d];

Und wer weiss schon (Glaskugel?) ob der Font wirklich bei
Zeichen Null beginnt?

von Dirk B. (dirkb2)


Lesenswert?

Wenn das mit dem 'A' geklappt hat, kann man fast davon ausgehen.

von Jing P. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
erstmal danke für die vielen Antworten!

Dirk B. schrieb:
> Bist du dir bei *string_pointer++ wirklich zu 100% sicher?
> (Das funktioniert zwar, aber der * ist überflüssig)

das ist mir wohl bei der letzten Änderung reingerutscht, ändert aber 
nichts am nicht Funktionieren.

René H. schrieb:
> *buffer_pointer = font[string_pointer][d];

sicher dass das so funktionieren kann?. Ich bekomme einen Fehler vom 
Compiler (und hätte auch nicht erwartet, dass das geht).

René H. schrieb:
> Weshalb Du in der for Schleife <5 nimmst, erschliesst sich mir nicht....

das habe ich nur gemacht, weil *string_pointer != '\0' nicht geklappt 
hat

Fontspezialist schrieb:
> ob der Font wirklich bei
> Zeichen Null beginnt?

tut mir leid, habe vergessen das Headerfile (ist nicht von mir) zu 
posten.
Ist im Anhang.

Ist es evtl. möglich, dass ich statt der main.hex die main.elf flashen 
muss?

vielen Dank für die Antworten,
Tristan

von Stefan E. (sternst)


Lesenswert?

1
const char font[256][5]={
Wie vermutet, du versuchst mehr RAM zu benutzen, als überhaupt vorhanden 
ist, weshalb der Stack in deine statischen Daten rein wächst. Auch mit 
Korrektur der anderen kleinen Fehler wird es so also nicht 
funktionieren. Du musst die Font-Daten ins Flash verbannen und aus dem 
RAM raus halten.

von Joe S. (joesch)


Lesenswert?

1
#include <avr/pgmspace.h>
2
3
const char daten[] PROGMEM = { ..., ..., ... };
.
.
1
  int i;
2
  char c;
3
4
  i = 3;
5
  c = pgm_read_byte( daten + i );
.
.
bei mehrdimensionalen arrays entsprechend anpassen.

von Stefan E. (sternst)


Lesenswert?

Joe S. schrieb:
1
 #include <avr/pgmspace.h>
2
3
const char daten[] PROGMEM = { ..., ..., ... };

Ich würde ja __flash nehmen. Das macht das ganze deutlich transparenter, 
insbesondere bei mehrdimensionalen Arrays.

von Joe S. (joesch)


Lesenswert?

Stefan E. schrieb:
> Ich würde ja __flash nehmen. Das macht das ganze deutlich transparenter,
> insbesondere bei mehrdimensionalen Arrays.

Geht natürlich auch. Dachte für den TO so als Einstieg zum RAM sparen 
mal
an pgmspace.h.

von Jing P. (Gast)


Lesenswert?

Hi,
vielen Dank, jetzt klappt alles :)
So sieht die Funktion jetzt aus:
1
void write_string_to_OLED_buffer (unsigned char* buffer_pointer, char 
2
*string_pointer)
3
{
4
  for (; *string_pointer != '\0'; string_pointer++)
5
  {
6
    for (unsigned char d=0; d < 5; d++, buffer_pointer++)
7
      *buffer_pointer = pgm_read_byte(&(font[*string_pointer][d]));
8
  }
9
}
(Das Headerfile habe ich natürlich auch entsprechend geändert)
Danke nochmal, dass ihr die Flash-Funktionen mit ins Spiel gebracht 
habt, die werden mir bestimmt noch das ein oder andere Mal helfen!

Tristan

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
Noch kein Account? Hier anmelden.