Forum: Mikrocontroller und Digitale Elektronik Schleifenproblem


von Marci (Gast)


Lesenswert?

Hallo, liebe Gemeinde,

da ich zu meinem Grafik-Display noch keinerlei Libraries für 
Schriftarten gefunden habe (falls es so etwas überhaupt schon gibt), hab 
ich mir mal eine kleine Routine für eigens angelegte Fonts geschrieben. 
Das Problem ist nur, dass ich mit einer verschachtelten Schleife etwas 
Probleme habe:
1
...
2
...
3
void lcdString(char strLcdString)
4
{
5
    char _xEnd;
6
    uint8_t arrZeichensatz[][7] =
7
    {
8
        {'H',   0x7F, 0x08, 0x08, 0x08, 0x7F, _xEnd}, // H
9
        {'a',   0x78, 0x44, 0x44, 0x24, 0x7C, _xEnd}, // a
10
        {'l',   0x7F,                         _xEnd}, // l
11
        {'o',   0x38, 0x44, 0x44, 0x44, 0x38, _xEnd}  // o
12
    };
13
14
    //uint8_t *byteZeichensatz = arrZeichensatz;
15
    
16
    char arrLcdString[] = {strLcdString};
17
    
18
    uint8_t nZeichen = 0;
19
    uint8_t nLine = 0;
20
    uint8_t nColumn = 0;
21
22
    while(nZeichen <= (sizeof(arrLcdString)/sizeof(uint8_t)))
23
    {
24
        while(nLine <= 3)
25
        {
26
            if(arrZeichensatz[nLine][nColumn] == arrLcdString[nZeichen])
27
            {
28
                nColumn++;
29
                while(arrZeichensatz[nLine][nColumn] != _xEnd)
30
                {
31
                    lcdSendData(arrZeichensatz[nLine][nColumn]);
32
                    nColumn++;
33
                }
34
                nColumn = 0;
35
            }
36
            nLine++;
37
        }
38
        nLine = 0;
39
        nColumn = 0;
40
        nZeichen++;
41
    }
42
    //if(arrLcdString[0] == 'H') lcdSendData(0x7F);
43
    //if(sizeof(arrLcdString)/sizeof(uint8_t) == 1) lcdSendData(0x7F);
44
};
45
...
46
...
47
48
//Aufruf im Programm
49
...
50
... lcdString("Hallo");
51
...

Ich bekomme damit ausschießlich den ersten Buchstaben (arrLcdString[0]) 
ausgegeben, der Rest bleibt mir irgendwo verborgen...
Hat da draußen vielleicht jemand einen Rat?

LG, Marcel

von Karl H. (kbuchegg)


Lesenswert?

Kauf dir ein C-Buch

In deinem Code gibt es so viele Problemstellen, dass man gar nicht weiß 
wo man anfangen soll.


PS: Der ganze Ansatz, wie du das mit den Fonts machen willst, ist 
verkorkst.

Mach dir eine Funktion, die 1 zeichen ausgeben kann (also alle Spalten). 
Und die rufst du dann für jedes Zeichen deines Strings einzeln mit dem 
jeweiligen Buchstaben auf.

Aber vorher nachlesen, wie das mit den Strings wirklich funktioniert.


Die Idee mit dem _xEnd ist keine gute Idee. Damit schränkst du dich in 
den Möglichkeiten ein, was du mit deinen Fonts alles anzeigen kannst. 
Beschränke dich erst mal auf Fonts, bei denen für jedes Zeichen gleich 
viele Bytes auszugeben sind. Und wenn du die im Griff hast, dann lass 
jede Buchstabenbeschreibung mit der Anzahl der zu diesem Buchstaben 
gehörenden Bytes beginnen.

von Marci (Gast)


Lesenswert?

Hallo Karl-Heinz,

... sag mal... schreibt ihr jetzt unter JEDE Antwort, dass man sich ein 
C-Buch kaufen soll?;-)))

Ich habe ganze FÜNF C/C++Bücher, etliche eBooks UND Galileo-Press-Werke. 
Dennoch bin ich aber in C ein Anfänger!;-)))

Ich wollte es anfangs ganz schlicht über eine switch-Anweisung machen 
(übersichtlicher geht´s eigentlich gar ned), ich fände es aber sehr viel 
eleganter, wenn ich es über eine Schleife und ein einziges Array 
erreichen könnte. Zumal dieses Array (wie man oben sieht) auch sehr gut 
zu managen wäre.

LG, Marcel

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:
> Hallo Karl-Heinz,
>
> ... sag mal... schreibt ihr jetzt unter JEDE Antwort, dass man sich ein
> C-Buch kaufen soll?;-)))

Wenn es notwendig ist: Ja

> Ich habe ganze FÜNF C/C++Bücher, etliche eBooks UND Galileo-Press-Werke.
> Dennoch bin ich aber in C ein Anfänger!;-)))

Dann LIES sie! Udn mach die Übungen (auf einem PC)

Insbesondere die Kapitel über Arrays und Strings und Funktionen!

Wenn dein Code so anfängt
1
void lcdString(char strLcdString)

dann hast du Strings bzw. Arrayverarbeitung und wie das bei 
Funktionsaufrufen funktioniert, nicht kapiert!

Deine Funktion bekommt so nur ein einzelnes Zeichen und keinen String. 
Und das wird auch nicht besser, wenn du dich hier

    char arrLcdString[] = {strLcdString};

ins eigene Bein schiesst.

von Heinz (Gast)


Lesenswert?

Hallo,

1.
void lcdString(char strLcdString)
Deine Funktion erwartet einen character, sprich ein Zeichen.

void lcdString(char *strLcdString)
So erwartet die Funktion einen String, wie du ihn übergibst.


2.
(sizeof(arrLcdString)/sizeof(uint8_t))
Das ergibt bei einer 8 Bit Maschine immer 1, egal wie lang der String 
ist, da du hier ein sizeof auf den Pointer machst.

Die Länge von einem String bekommst du mit strlen(arrLcdString) aus 
string.h.

Das warn mal die Sachen die mir schnell aufgefallen sind.

lg Heinz

von Karl H. (kbuchegg)


Lesenswert?

Zum Rest, wie du das ganze angehen kannst, hab ich mich hier
Beitrag "Re: Schleifenproblem"
ja schon geäussert.

Alles beginnt mit einer Funktion, die 1 Zeichen (nicht String) ausgeben 
kann. Darauf aufbauend ist dann eine Stringfunktion ein Kinderspiel.

von Marci (Gast)


Lesenswert?

Hm...... ich hab jetzt den String mal in Hochkommata gesetzt. Das Wort 
wird zwar in die Funktion geladen, aber nur zwei Buchstaben werden 
angezeigt. Der letzte zuerst, dann folgt der Erste. Macht das einen 
Sinn?

Ps.: Und ja, es kann gut sein, dass ich noch fehlendes Wissen dazu habe. 
Allein schon der Gedanke an die fast 1000 Seiten eines jeden C-Buches in 
meinem Schrank, machen mir große Sorgen...)§/&!"&§&(§/!46!734 ;-)))))

LG, Marcel

von Marci (Gast)


Lesenswert?

Klingt eigentlich ganz gut! Werd ich mir gleich anschauen.

LG

Ps.: Ich wollte halt gern eine Funktion, die man einfach bedienen kann 
(xxx("...")).

von Stefan E. (sternst)


Lesenswert?

> Alles beginnt mit einer Funktion, die 1 Zeichen (nicht String) ausgeben
> kann. Darauf aufbauend ist dann eine Stringfunktion ein Kinderspiel.

Und wenn du (Marci) diese Funktion schreibst, dann verabschiede dich 
bitte ganz schnell davon, den Zeichensatz in einer nicht statischen 
lokalen Variable zu speichern. Das ist HORREND ineffektiv.

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:

> Ps.: Ich wollte halt gern eine Funktion, die man einfach bedienen kann
> (xxx("...")).

Kriegst du auch!
Aber eines nach dem anderen. Zuerst die 'einfachere' Funktion und dann 
darauf aufbauend die Funktion, die mit komplizierteren Daten umgehen 
kann.

Hier ist sie
1
void lcd_string( const char* string )
2
{
3
  char c;
4
5
  c = *string;
6
  while( c != '\0' ) {
7
    lcd_char( c );
8
    c = *string;
9
    string++;
10
  }
11
}

(So gesehen ist die "kompliziertere" Funktion die C-technisch 
einfachere. Aber du brauchst eine Funktion lcd_char als Grundlage, damit 
du darauf aufbauend die Funktion für Strings schreiben kannst. Daher 
fängt man zuerst mit der Funktion lcd_char an)

von Marci (Gast)


Lesenswert?

@Stefan: Warum denn genau?

Mit Speichergrößen, etc. kenn i mi no ned so aus... bzw. wohl eher gar 
ned.;-))

LG

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Hier ist sie

Bitte die letzten beiden Zeilen der while-Schleife tauschen. ;-)

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Karl Heinz Buchegger schrieb:
>> Hier ist sie
>
> Bitte die letzten beiden Zeilen der while-Schleife tauschen. ;-)

Oops. Hast recht.
Das hat man davon, wenn man nicht in der C-üblichen dichten Form 
schreiben will :-)
1
void lcd_string( const char* string )
2
{
3
  while( *string )
4
    lcd_char( *string++ );
5
}

von Marci (Gast)


Lesenswert?

Hui... ihr seid´s ja schnell! Supi!;-)

Jepp, mach ich.

Hmmmm... kann ich das nicht irgendwie ohne Zeiger machen - ich glaub, 
des is noch zu hoch für mich.;-)))

LG

von Heinz (Gast)


Lesenswert?

@ Karl Heinz
wird wohl nicht compilierbar sein.
const char* string -> string++;

const bedeutet konstant, daher kann string nicht verändert werden.

void lcd_string( const char* string )
{
  char *c;

  c = string;
  while( c != '\0' ) {
    lcd_char( *c );

    c++;
  }
}

lg heinz

von Heinz (Gast)


Lesenswert?

das noch vergessen:
while( *c != '\0' )

void lcd_string( const char* string )
{
  char *c;

  c = string;
  while( *c != '\0' ) {
    lcd_char( *c );

    c++;
  }
}

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:
> Hui... ihr seid´s ja schnell! Supi!;-)
>
> Jepp, mach ich.
>
> Hmmmm... kann ich das nicht irgendwie ohne Zeiger machen - ich glaub,
> des is noch zu hoch für mich.;-)))

kann man.
Aber
  es ist für den µC mehr Aufwand
  man muss einen Datentyp für einen Index einführen, was man nur
  ungern tut. Denn: wie gross macht man ihn denn?
  die meisten String-Operationen gewinnen durch Zeiger. Also kein
  Grund Zeiger links liegen zu lassen.
  Irgendwann musst du sowieso an Zeiger rann. Arrays und Strings ohne
  Zeiger ist wie ein Fisch ohne Wasser.

1
void lcd_string( const char* string )
2
{
3
  size_t i = 0;
4
  while( string[i] != '\0' )
5
    lcd_char( string[i] );
6
    i++;
7
  }
8
}


Daher auch die Sache weiter oben mit dem Buch. Denn in JEDEM Buch werden 
solche Dinge im Kapitel über Strings bis zur Vergasung geübt! Eben WEIL 
es wichtige Grundlagen sind.

von Heinz (Gast)


Lesenswert?

Ineffizient ist es deswegen, da dieses Array bei jedem Aufruf der 
Funktion im RAM angelegt wird und dann mit den Werten aus dem Flash 
befüllt wird.
Wenn es global und const ist, liegt es im Flash und nur dort.

lg Heinz

von Stefan E. (sternst)


Lesenswert?

Heinz schrieb:
> @ Karl Heinz
> wird wohl nicht compilierbar sein.
> const char* string -> string++;
>
> const bedeutet konstant, daher kann string nicht verändert werden.

Unsinn. Nicht string ist konstant, sondern das, worauf string zeigt.

von Karl H. (kbuchegg)


Lesenswert?

Heinz schrieb:
> @ Karl Heinz
> wird wohl nicht compilierbar sein.
> const char* string -> string++;
>
> const bedeutet konstant, daher kann string nicht verändert werden.

Nö

Die Zeichen sind konstant, aber nciht der Zeiger.
Ein const char* ist etwas anderes als ein char * const

von Marci (Gast)


Lesenswert?

@Karl Heinz:

Und WIE wende ich deine erste Version nun auf den Font an???????

von Marci (Gast)


Lesenswert?

Ps.: Ich steh grad auf dem Schlauch.;-)

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:
> @Karl Heinz:
>
> Und WIE wende ich deine erste Version nun auf den Font an???????

Indem du eine Funktion schreibst
1
//
2
// gib ein einzelnes Zeichen aus
3
//
4
void lcd_char( char c )
5
{
6
7
  // suche im Font Array nach den Code-Bytes für den Buchstaben in c
8
9
  // Wenn gefunden:
10
  // gib die entsprechenden Bytes per SPI aus
11
}

Ein bischen was musst du schon auch selber programmieren, sonst kann ich 
dir ja gleich alles schreiben.


Zum Testen
1
void lcd_char( char c )
2
{
3
   .... dein Code
4
}
5
6
int main()
7
{
8
  // was auch immer
9
10
11
  lcd_char( 'H' );
12
  lcd_char( 'W' );
13
14
  while( 1 )
15
  {
16
  }
17
}

und wenn das dann klappt, kommt der große Augenblick
1
void lcd_char( char c )
2
{
3
   .... dein Code
4
}
5
6
void lcd_string( const char* string )
7
{
8
  size_t i = 0;
9
  while( string[i] != '\0' )
10
    lcd_char( string[i] );
11
    i++;
12
  }
13
}
14
15
int main()
16
{
17
  // was auch immer
18
19
20
  lcd_string( "Hallo World" );
21
22
  while( 1 )
23
  {
24
  }
25
}

von Heinz (Gast)


Lesenswert?

Tschuldigung, meinte char const *string
Mein Fehler

von Stefan E. (sternst)


Lesenswert?

Heinz schrieb:
> Tschuldigung, meinte char const *string
> Mein Fehler

Dumm nur, dass dafür das gleiche gilt. Auch hier ist der Pointer nicht 
konstant. ;-)

von Marci (Gast)


Lesenswert?

Hab ich des jetzt richtig verstanden? Mein Font-Array soll erhalten 
bleiben??????

Aber dann geht ja dein \0\-Vergleich GAR NED!? Dies bedeuted ja ein 
0-Byte... es gibt ja aber auch z.B. das Zeichen ", und dann habe ich 
mittendrin ein 0-Byte, worauf die Schleife vorzeitig verlassen würde?! 
Richtig???

LG

von Karl H. (kbuchegg)


Lesenswert?

Heinz schrieb:
> Tschuldigung, meinte char const *string
> Mein Fehler

:-)

Ein "char const *" ist dasselbe wie ein "const char *"

const wirkt immer auf den Teil links von ihm. Es sei denn es steht schon 
ganz links, dann wirkt es auf den Teil rechts von ihm

char * const
   links vom const steht der *.  Also ist der Pointer const

char const *
   links vom const steht das char. Also sind die char const

const char *
   links vom const steht .... nichts mehr. Also wirkst das const
   auf das rechts von ihm stehende char. Die Zeichen sind const

char const * const
   Sowohl der Zeiger, als auch die Character sind const

von Marci (Gast)


Lesenswert?

Ps.: Oder hab ich die Funktion noch nicht begriffen?;-)

von Qwertz (Gast)


Lesenswert?

>Hab ich des jetzt richtig verstanden?

Nein. Am besten tief durchatemen. Darjeeling trinken. Nochmal lesen. 
Lange drüber nachdenken. Nochmal lesen. Nochmal denken.

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:
> Hab ich des jetzt richtig verstanden? Mein Font-Array soll erhalten
> bleiben??????

Natürlich. Irgendwo müssen ja die Pixel für ein Zeichen des Fonts 
abgespeichert sein. Aber was interessiert das die String-Ausgabe wie 
genau die Einzelzeichenausgabe zu ihren Ergüssen kommt? Genau. Gar 
nicht.

> Aber dann geht ja dein \0\-Vergleich GAR NED!?

Warum nicht?
AUf dieser Ebene innerhalb der lcd_string sind wir doch noch gar nicht 
bei den Pixel. Da ist noch immer von einzelnen Zeichen die Rede. Und da 
in C jeder String ausnahmslos immer mit einem '\0' Zeichen aufhört, kann 
man das natürlich benutzen, wenn man in einem String ein Zeichen nach 
dem anderen zur Verarbeitung herausholen will.
Ob ich dann dieses eine Zeichen per UART verschicke oder auf ein 
Text-LCD ausgebe oder wie in deinem Fall einer Funktion übergebe, die 
für das Zeichen entsprechende Pixel auf ein Grafik-LCD hinmalt, ändert 
ja nichts daran, wie ich in einem String an ein Zeichen nach dem anderen 
komme.

> es gibt ja aber auch z.B. das Zeichen ", und dann habe ich
> mittendrin ein 0-Byte, worauf die Schleife vorzeitig verlassen
> würde?!
> Richtig???

Falsch.
Auch wenn es dir nicht gefällt. Das steht alles in deinen Büchern.

von Marci (Gast)


Lesenswert?

Tee ist gekocht!;-)))))))

Ok. Ich glaub, ich setz mich jetzt erstmal zur Bearbeitung hin. Danke 
Jungs!;-)

LG, Marcel

Ps.: Wenn ich mich ned mehr melden sollte, hat mich die Funktion dann 
wahrscheinlich innerlich zerlegt.;-)))))

von Anfänger (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> const wirkt immer auf den Teil links von ihm. Es sei denn es steht schon
> ganz links, dann wirkt es auf den Teil rechts von ihm
Für diesen Krempel sollte man K&R mal leicht verhauen...

> char const * const
>    Sowohl der Zeiger, als auch die Character sind const
Wäre const char const * auch richtig?

von Marci (Gast)


Lesenswert?

Ps.: JAAAAAAAAaaaaaaaaaa. ICH werde LESEN!!! Versprochen!!!!!!!!;-))

LG und Herzlichen Dank.;-)

von Karl H. (kbuchegg)


Lesenswert?

Marci schrieb:
> Ps.: JAAAAAAAAaaaaaaaaaa. ICH werde LESEN!!! Versprochen!!!!!!!!;-))

Am besten wäre:
Die Übungen im Buch nach jedem Kapitel auf einem PC durchmachen.

von Karl H. (kbuchegg)


Lesenswert?

Anfänger schrieb:
> Karl Heinz Buchegger schrieb:
>> const wirkt immer auf den Teil links von ihm. Es sei denn es steht schon
>> ganz links, dann wirkt es auf den Teil rechts von ihm
> Für diesen Krempel sollte man K&R mal leicht verhauen...

Da können K&R nichts dafür. Zu ihrer Zeit gab es noch kein const.

>> char const * const
>>    Sowohl der Zeiger, als auch die Character sind const
> Wäre const char const * auch richtig?

Das wäre doppelt gemoppelt. Beide const beziehen sich auf dasselbe: auf 
die char

von Qwertz (Gast)


Lesenswert?

>Die Übungen im Buch nach jedem Kapitel auf einem PC durchmachen.

Full Ack

von Anfänger (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Da können K&R nichts dafür. Zu ihrer Zeit gab es noch kein const.
Achso? Auch gut.

> Das wäre doppelt gemoppelt. Beide const beziehen sich auf dasselbe: auf
> die char
Argh, ich muss mir wohl die Bibel (steht K&R drauf) nochmal zu Gemüte 
führen. :-(

Man könnte natürlich das const auch einfach ganz weglassen... duckundweg

von Michael S. (schiko)


Lesenswert?

Marci schrieb:
> Hab ich des jetzt richtig verstanden? Mein Font-Array soll erhalten
> bleiben??????

nicht so, wie es da steht.

Global:
char myFont[][] = {
{ ..... },..
};

Fang z.B. mit 'A' an und subtrahiere in
lcd_char( char c )
'A' von c für den Indexzugriff auf Dein Font,
und achte auf die Indexgrenzen


> Aber dann geht ja dein \0\-Vergleich GAR NED!?

Der Dein Vergleich funktionierte vorher auch nur per Zufall, weil Du die 
\0 nicht _xEnd nicht initialisiert hast.
Sicher funktioniert aber Karl Heinz Vergleich.


Übrigens sollte man Unterstriche am Bezeichneranfang lieber lassen.
(Findest Du auch in Deinen C/C++-Büchern warum)

> Hmmmm... kann ich das nicht irgendwie ohne Zeiger machen - ich glaub,
> des is noch zu hoch für mich.;-)))

Basic?

von Marci (Gast)


Lesenswert?

Danke.

Mit Basic krieg ich aber nix auf meinen µC.;-)

LG

von Karl H. (kbuchegg)


Lesenswert?

Michael Schikora schrieb:

> Der Dein Vergleich funktionierte vorher auch nur per Zufall, weil Du die
> \0 nicht _xEnd nicht initialisiert hast.

Ach, das hab ich ja noch gar nicht gesehen.


Wie gesagt: In der ersten Version würde ich mal einen Fixed Font machen. 
Alle Zeichen gleich viele Bytes.

Und bei variablen Fonst dann kein Ende Zeichen, sondern als erstes Byte 
die Anzahl der Codebytes für dieses Zeichen.

Und der Buchstabe .... der sollte dort sowieso nicht im Array sein. Die 
Reihenfolge der Buchstaben ist ja durch den ASCII Code sowieso 
festgelegt.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ach, das hab ich ja noch gar nicht gesehen.

Für mich war es neu, dass in der Initialisierung für eine nicht 
statische lokale Variable andere Variablen stehen können. Wenn ich die 
Tage mal etwas Langeweile habe, werde ich mal checken, ob das so im 
Standard steht, oder ob das eine C-Extension vom GCC ist.
Oder weißt du das zufällig so aus dem Stegreif?

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Karl Heinz Buchegger schrieb:
>> Ach, das hab ich ja noch gar nicht gesehen.
>
> Für mich war es neu, dass in der Initialisierung für eine nicht
> statische lokale Variable andere Variablen stehen können. Wenn ich die
> Tage mal etwas Langeweile habe, werde ich mal checken, ob das so im
> Standard steht, oder ob das eine C-Extension vom GCC ist.
> Oder weißt du das zufällig so aus dem Stegreif?

nicht 100% sicher

In C dürfte das nicht erlaubt sein.
In C++ schon.

In C müssen Initialiser Compiler-Time Konstanten sein, während in C++ 
eine Expression (also auch ein Funktionsaufruf) erlaubt ist.

Aber wie gesagt: 100% sicher bin ich mir auch nicht.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> In C müssen Initialiser Compiler-Time Konstanten sein, während in C++
> eine Expression (also auch ein Funktionsaufruf) erlaubt ist.

Eben, das war auch mein Kenntnisstand.
Aber ich habe doch gleich mal nachgeschaut, und seit C99 ist das vom 
Standard abgedeckt. Und wenn ich etwas darüber nachdenke, dann habe ich 
das auch schon öfter benutzt, ohne es zu merken:
(du wahrscheinlich auch ;-)
1
for (int i = SomeVar; i; i--) {

von Marci (Gast)


Lesenswert?

Hey Leute,

... nochmal DANK an alle! Hab´s nun so gelöst:

Der Font:
1
// Initialisierung des Standard-Font:
2
// Die Bytes liegen senkrecht von links nach rechts, dann zeilenweise nach unten
3
// in jedem Byte liegt Bit0 oben und Bit7 unten
4
// Array-Werte: {Bits(in Bytes)}, ASCII(Dez.)Okt. und Charakter-Bezeichnung
5
6
char myFont[][8] =
7
{
8
...
9
    {5, 0x3F, 0x40, 0x40, 0x40, 0x3F            }, // ( 85)125 U
10
    {5, 0x1F, 0x20, 0x40, 0x20, 0x1F            }, // ( 86)126 V
11
    {5, 0x3F, 0x40, 0x30, 0x40, 0x3F            }, // ( 87)127 W
12
    {5, 0x63, 0x14, 0x08, 0x14, 0x63            }, // ( 88)130 X
13
    {5, 0x03, 0x44, 0x78, 0x44, 0x03            }, // ( 89)131 Y
14
    {5, 0x61, 0x51, 0x49, 0x45, 0x43            }, // ( 90)132 Z
15
    {2, 0x7F, 0x41                              }, // ( 91)133 [
16
    {5, 0x01, 0x06, 0x08, 0x30, 0x40            }, // ( 92)134 "\"
17
    {2, 0x41, 0x7F                              }, // ( 93)135 ]
18
    {                                           }, // ( 94)136 ^
19
    {5, 0x40, 0x40, 0x40, 0x40, 0x40            }, // ( 95)137 _
20
    {                                           }, // ( 96)140 ’
21
    {5, 0x78, 0x44, 0x44, 0x24, 0x7C            }, // ( 97)141 a
22
...
23
};
... und die Routinen:
1
void lcdChar8(char c) // c ist hier zugleich der jeweilige ASCII-Wert (z.B.: "A">65) des gesendeten Charakters
2
{
3
    for(uint8_t nColumn=1; nColumn<=7; nColumn++)
4
    {
5
        lcdSendData(myFont[c][nColumn]);
6
        if(nColumn == myFont[c][0]) // wenn das Ende des Charakters im Array erreicht ist...
7
        {
8
            lcdSendData(0x00); // ... ein 0-Byte (leere Spalte) senden...
9
            break; // ... und Funktion verlassen (bzw. nächsten Charakter einlesen)
10
        }
11
    }
12
}
13
// Bildung einer Zeichenkette aus den einzelnen Charaktern:
14
void lcdString8(const char* string)
15
{
16
    char *c;
17
18
    c = string;
19
    while(*c != '\0')
20
    {
21
        lcdChar8(*c);
22
        c++;
23
    }
24
}
25
//-----------------------------------------------------------------------------------------------------
26
27
int main()
28
{
29
30
    lcdString8("Hallo, ich bin ein Hase!");
31
...
32
};

Es funktioniert zwar reibungslos, ich bekomme aber ganze 3 
Warnmeldungen:

1. array subscript has type 'char';
   Zeile: lcdSendData(myFont[c][nColumn]);
2. array subscript has type 'char';
   Zeile: if(nColumn == myFont[c][0])
3. assignment discards qualifiers from pointer target type;
   Zeile: c = string;

von Marci (Gast)


Lesenswert?

Fast vergessen:

LG, Marci  ;-)))

von Marci (Gast)


Lesenswert?

Hallöchen, ich bin´s nochmal,^^

... es geht doch noch ned!:(
Es lässt sich nur eine Zeile ausgeben. Dann streikt das Programm völlig 
und zeigt nix mehr an.
Scheinbar liegt der Fehler in lcdString8() und event. auch an falschen 
Typendeklarationen.

Jemand einen Rat???????

LG, Marcel

von Bernd N (Gast)


Lesenswert?

Machst du das Ganze für AVR und mit dem GCC ? Dann geht dir vermutlich 
der Speicher (RAM) aus.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Array_aus_Strings_im_Flash-Speicher

von Marci (Gast)


Lesenswert?

Hallo Bernd,

... am RAM kann´s ned liegen. Der ist nur mit 0,8% belegt. (ATmega2560)

Ich hab die Funktion jetzt ein wenig umgebaut, und,... vóila... OHNE 
eine einzige Fehler- oder Warnmeldung.
1
void lcdChar8(int cInt) // c ist hier zugleich der jeweilige ASCII-Wert (z.B.: "A">65) des gesendeten Charakters
2
{
3
    //uint8_t cInt = c+1; // explizite Typenumwandlung (>ASCII)
4
    for(uint8_t nColumn=1; nColumn<=7; nColumn++)
5
    {
6
        lcdSendData(myFont[cInt][nColumn]);
7
        if(nColumn == myFont[cInt][0]) // wenn das Ende des Charakters im Array erreicht ist...
8
        {
9
            lcdSendData(0x00); // ... ein 0-Byte (leere Spalte) senden...
10
            break; // ... und Funktion verlassen (bzw. nächsten Charakter einlesen)
11
        }
12
    }
13
}
14
15
void lcdString8(char *string)
16
{
17
    char c[20];
18
    strncpy(c,  string,  sizeof(c));
19
    for(uint8_t nChar=0; nChar <2; nChar++)
20
    {
21
        lcdChar8(c[nChar]);
22
    }
23
}

LG, Marcel

von Marci (Gast)


Lesenswert?

Upps... gab doch noch ein Problem:
1
void lcdString8(const char *data)
2
{
3
    while( *data != '\0' )
4
        lcdChar8( *data++ );
5
}

Jetzt aber!;-))

LG

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.