Text in 2D Arrays, stm32f4xx

OP #3571676
Lesenswert?

Guten Tag

Bei meinem Projekt(c, mdk5, Keil, stm32f4xx) geht es darum eine kleine 
Bedienung zu erstellen. Es soll ein Display angesteuert werden. Die 
Texte sollen in ein FRAM abgelegt werden. Da sechs Sprachen erforderlich 
sind, dachte ich an ein 2D Array. Das Display hat 2 Zeilen, 16 Zeichen, 
ASCII-Code. Um es einfach zu halten stelle ich mir folgendes vor:



Dies wäre die Struktur, die dann ins FRAM abgelegt wird. (Auszugsweise)
1
#define STRING_LENGTH 17
2
#define CNT_LANGUAGES 6
3

4

5
typedef struct  {
6
                  size_t        SetupVersion;
7
                  char          txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH];
8
                }
9
                tSetup;
10

11

12
// ---- exported data --
13

14
extern tSetup      setup;


Und im Init_Setup würde dann das Array beschrieben.
1
void Setup_Init(void)
2
{
3
   setup.txt_run_RunOpen[0][0] = {{'M'}};
4
   setup.txt_run_RunOpen[0][1] = {{'a'}};
5
   setup.txt_run_RunOpen[0][2] = {{'c'}};
6
   setup.txt_run_RunOpen[0][3] = {{'h'}};
7
   setup.txt_run_RunOpen[0][4] = {{'i'}};
8
   setup.txt_run_RunOpen[0][5] = {{'n'}};
9
   setup.txt_run_RunOpen[0][6] = {{'e'}};
10
   setup.txt_run_RunOpen[0][7] = {{' '}};
11
   setup.txt_run_RunOpen[0][8] = {{'R'}};
12
   setup.txt_run_RunOpen[0][9] = {{'u'}};
13
   setup.txt_run_RunOpen[0][10] = {{'n'}};
14
   setup.txt_run_RunOpen[0][11] = {{' '}};
15
   setup.txt_run_RunOpen[0][12] = {{'o'}};
16
   setup.txt_run_RunOpen[0][13] = {{'p'}};
17
   setup.txt_run_RunOpen[0][14] = {{'e'}};
18
   setup.txt_run_RunOpen[0][15] = {{'n'}};
19
}
usw.

Micht dünkt dies sehr aufwendig! Andererseits ist das Senden der ASCII 
Zeichen auf den i2c Bus einfach.
1
for(x = 0;x <= 15; x++)
2
  {
3
    LCD_wr_Data(setup.txt_run_RunOpen[0][x]);
4
  }

Hat jemand eine Idee, wie man dies vereinfachen kann.

Vielen Dank schon mal
OP #3572586
Lesenswert?

oder andere Frage, wie kriege ich
1
#define STRING_LENGTH 17
2
#define CNT_LANGUAGES 6
3

4
typedef struct  {
5
                  size_t        SetupVersion;
6
                  char          txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH];
7
                }
8
                tSetup;
9

10
extern tSetup      setup;
11

12

13
setup.txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH] = 
14
{{"Machine run open"},
15
 {"Anlage oeffnet  "},
16
 {"Macchina aprire "},
17
 {""},
18
 {""},
19
 {""}};

dazu, dass ich ASCII Zeichen ausgeben kann?
1
for(x = 0;x <= 15; x++)
2
  {
3
    LCD_wr_Data(setup.txt_run_RunOpen[0][x]);
4
  }

Welche Methode ist speichertechnisch die beste Lösung?

Vielen Dank

Grüsse
OP #3573029
Lesenswert?

@ Dr. Sommer

Ja, diesbezüglich habe ich meine Meinung auch geändert. Die Texte werden 
ja nicht mehr verändert und es muss nur darauf zugegriffen werden.

@Route66
1
setup.txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH] = 
2
{{"Machine run open"},
3
 {"Anlage oeffnet  "},
4
 {"Macchina aprire "},
5
 {""},
6
 {""},
7
 {""}};

wie geb ich jetzt einzelne Zeichen des Strings aus? Ich hab da einen 
Knopf in der Leitung.
1
for(x = 0;x <= 15; x++)
2
  {
3
    LCD_wr_Data(setup.txt_run_RunOpen[0][x]);
4
  }
1
void LCD_wr_Data(uint8_t data)
2
{
3
  LCD_wr(true, data);
4
}
1
void LCD_wr(bool dataReg, uint8_t data)
2
{
3
  ExtPort.pin.P14_RS       = dataReg;
4
  ExtPort.pin.P15_R_nW     = false;
5
  ExtPort.pin.P16_E       = true;
6
  ExtPort.pin.P10_Dnibble = data / 0x10;
7
  xferToPortexpander();
8
  
9
  ExtPort.pin.P16_E       = false;
10
  xferToPortexpander();
11
  
12
  ExtPort.pin.P16_E       = true;
13
  ExtPort.pin.P10_Dnibble = data & 0x0f;
14
  xferToPortexpander();
15
  
16
  ExtPort.pin.P16_E       = false;
17
  xferToPortexpander();
18
}

so erhalte ich nur schwarze Zeichen auf dem Display!

Vielen Dank und Gruss
#3573058
Lesenswert?

MC Bu schrieb:

> wie geb ich jetzt einzelne Zeichen des Strings aus?

So wie immer.

> Ich hab da einen
> Knopf in der Leitung.
>
>
1
> for(x = 0;x <= 15; x++)
2
>   {
3
>     LCD_wr_Data(setup.txt_run_RunOpen[0][x]);
4
>   }
5
>

Im Prinzip schon richtig.
Nur gibt man halt nicht einfach fix 15 Zeichen aus. Schliesslich sagt ja 
kein Mensch, dass alle Texte 15 Zeichen lang sind.

C definiert, dass ein String genau dort zu Ende ist, wo sich das '\0' 
Zeichen befindet.

Also
1
   x = 0;
2
   while( setup.txt_run_RunOpen[0][x] != '\0' )
3
   {
4
     LCD_wr_Data(setup.txt_run_RunOpen[0][x]);
5
     x++;
6
   }

oder ein wenig intelligenter unter Verwendung der Pointer-Schreibweise
1
    const char* ptr = &setup.txt_run_RunOpen[0][0];
2

3
    while( *ptr != '\0' )
4
      LCD_wr_Data( *ptr++ );


> so erhalte ich nur schwarze Zeichen auf dem Display!

Wenn dein allererstes Original funktioniert hat, dann muss auch das 
gehen.


char str[8] = "test";

ist schliesslich auch nichts anderes als

str[0] = 't';
str[1] = 'e';
str[2] = 's';
str[3] = 't';
str[4] = '\0';

nur dass der Compiler die ganze Arbeit für dich in der 
Initialisierungsphase macht.
#3573063
Lesenswert?

Zeig doch bitte mal den Originalcode.

Denn das hier
1
typedef struct  {
2
                  size_t        SetupVersion;
3
                  char          txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH];
4
                }
5
                tSetup;
6

7
extern tSetup      setup;
8

9

10
setup.txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH] = 
11
{{"Machine run open"},
12
 {"Anlage oeffnet  "},
13
 {"Macchina aprire "},
14
 {""},
15
 {""},
16
 {""}};

kann er recht offensichtlich nicht sein. Das compiliert nämlich mit 
Sicherheit nicht. Du kannst nicht setup.txt_run_RunOpen einzeln 
initialisieren.
OP #3573111
Lesenswert?

Stimmt, hab ich nicht compiliert. Dies bedeutet ich muss den String bei 
der definition initialisieren. Oder ich kann nur einzelne Zeichen laden?
1
Setup.startup_Text_line1[0][0] = 'M';



Ich möchte aber alle Textelemente in einem Struct vereinen. Wie kann ich 
dies lösen?

Ansonsten funktioniert es so sehr gut.

Vielen, vielen Dank!

Grüsse

MC Bu
#3573131
Lesenswert?

MC Bu schrieb:
> Stimmt, hab ich nicht compiliert. Dies bedeutet ich muss den String bei
> der definition initialisieren.

Es ist das vernünftigste.

> Oder ich kann nur einzelne Zeichen laden?

Kannst du auch. Aber dann ist es erstens keine Initalisierung mehr und 
zweitens machst du dir eine Menge Arbeit

>
1
> Setup.startup_Text_line1[0][0] = 'M';
2
>

kann man machen. Man kann aber auch

   strcpy( Setup.startup_Text_line1[0], "Meine Idee" );

machen :-)

Ist ein bischen einfacher.
Vielleicht solltest du doch erst mal im C-Buch deiner Wahl nachlesen, 
wie Stringverarbeitung in C überhaupt funktioniert?

> Ich möchte aber alle Textelemente in einem Struct vereinen. Wie kann ich
> dies lösen?

Genau so, wie das da oben gemacht wurde.
Gast #3573138
Lesenswert?

Karl Heinz schrieb:
> kann er recht offensichtlich nicht sein. Das compiliert nämlich mit
> Sicherheit nicht. Du kannst nicht setup.txt_run_RunOpen einzeln
> initialisieren.
man kann aber
1
typedef struct  {
2
                  size_t        SetupVersion;
3
                  char          txt_run_RunOpen[CNT_LANGUAGES][STRING_LENGTH];
4
                }
5
                tSetup;
6

7
extern tSetup      setup;
8

9
tSetup setup = {  42,
10
        {{"Machine run open"}, 
11
        {"Anlage oeffnet  "},
12
        {"Macchina aprire "}, 
13
        {""},
14
        {""},
15
        {""}}};
 machen.
OP #3573163
Lesenswert?

Ich kann aber nicht die Stringkette in einem Struct anlegen und 
gleichzeitig initialisieren!
1
typedef struct  {
2
                  size_t        SetupVersion;
3
                  char          startup_Text_line1[STRING_LENGTH];
4
                }
5
                tSetup;
Ausser wie es Dr.Sommer vorgemacht hat! Dies würde ja Sinn machen, da 
ich den struct nur für die Texte anlege. Diese Lösung finde ich 
praktikabel.

Das beste wird es sein, ich lese über struct ebenfalls nach. ich 
beschäftige mich leider bisschen zu wenig mit c.

Vielen Dank für Eure Hilfe!

Grüsse

MC Bu
#3573174
Lesenswert?

MC Bu schrieb:
> Ich kann aber nicht die Stringkette in einem Struct anlegen und
> gleichzeitig initialisieren!

Wo genau machst du das denn?

> Ausser wie es Dr.Sommer vorgemacht hat!

Ja, genau das ist ja auch der Normalfall.

> Das beste wird es sein, ich lese über struct ebenfalls nach. ich
> beschäftige mich leider bisschen zu wenig mit c.

Sieht fast danach aus.
OP #3573207
Lesenswert?

Niergends! Das war nur eine Überlegung!


Jetzt siehts bei mir so aus:

im Text.h
1
typedef struct  {
2
                  char  startup_Text_line1[STRING_LENGTH];
3
                  char  operation_Text_line1[STRING_LENGTH];
4
                  char  operation_Text_line2[STRING_LENGTH];
5
                }
6
              tTxt;
7

8
extern  tTxt Text;


im Text.c
1
void Init_Texte(void)
2
{
3
  tTxt Text = {  {"Hallo Welt"},
4
                 {"Operation is"},
5
                 {"running"}
6
              };
7
}
Gast #3573211
Lesenswert?

MC Bu schrieb:
> Jetzt siehts bei mir so aus:
Das klappt nicht. Zuweisungen von structs gehen in C nicht. Nur 
initialisierungen, wie ich sie oben gezeigt hab. Wenn deine Texte im 
Flash sind, kannst du sie eh nicht ändern/zuweisen. Braucht man ja auch 
nicht, da 1x initialisieren und im Read-Only-Flash zu lassen ja reicht.
#3573224
Lesenswert?

im Text.h
1
typedef struct  {
2
                  char  startup_Text_line1[STRING_LENGTH];
3
                  char  operation_Text_line1[STRING_LENGTH];
4
                  char  operation_Text_line2[STRING_LENGTH];
5
                }
6
              tTxt;
7

8
extern  tTxt Text;

im Text.c
1
#include "Text.h"
2

3
tTxt Text = {  "Hallo Welt",
4
               "Operation is",
5
               "running"
6
            };

und die Funktion Init_Texte braucht keiner.

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