Forum: Mikrocontroller und Digitale Elektronik Selbstdefinierte Zeichen


von Achim S. (achims)


Lesenswert?

Hallo
mit diesem kleinen Programm kann ich bis zu 8 Zeichen darstellen
1
static const PROGMEM unsigned char copyRightChar[] =
2
{
3
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00,  
4
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x03, 0x03, 0x03,
5
  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  
6
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
7
  0x03, 0x03, 0x03, 0x1f, 0x1f, 0x00, 0x00, 0x00,   
8
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,   
9
  0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
10
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f   
11
};
12
13
int main(void)                // Beginn hauptprogramm
14
  {
15
    unsigned char i;     
16
    lcd_init(LCD_DISP_ON);    
17
    for (;;) 
18
      {                                   
19
    lcd_command(_BV(LCD_CGRAM));  
20
    for(i=0; i<64; i++)
21
     {
22
      lcd_data(pgm_read_byte_near(&copyRightChar[i]));
23
     }
24
        lcd_clrscr();   
25
        lcd_gotoxy(7,1);  
26
    
27
       lcd_gotoxy(4,1);
28
       lcd_puts("Roboterxxxx");
29
       
30
     lcd_gotoxy(2,0);
31
     
32
       lcd_putc(5); lcd_putc(0);
33
       lcd_putc(0); lcd_putc(0);
34
     lcd_putc(0); lcd_putc(0);
35
     lcd_putc(0); lcd_putc(0);
36
     lcd_putc(0); lcd_putc(0);
37
     lcd_putc(0); lcd_putc(0);
38
     lcd_putc(0); lcd_putc(0);
39
     lcd_putc(1);
40
     
41
     lcd_gotoxy(2,2);
42
     
43
     lcd_putc(6); lcd_putc(0);
44
     lcd_putc(0); lcd_putc(0);
45
     lcd_putc(0); lcd_putc(0);
46
     lcd_putc(0); lcd_putc(0);
47
     lcd_putc(0); lcd_putc(0);
48
     lcd_putc(0); lcd_putc(0);
49
     lcd_putc(0); lcd_putc(0);
50
       lcd_putc(4);
51
    
52
     lcd_gotoxy(2,1); lcd_putc(3);  
53
     lcd_gotoxy(16,1); lcd_putc(2); 
54
     lcd_gotoxy(14,3); lcd_puts("by as");
55
     _delay_ms(5000);
56
              
57
    }
58
}

So weit klar.
Was muss ich machen, wenn ich im weiteren Programm andere Zeichen 
darstellen will. Reicht es aus, wenn ich einfach das copyRightChar 
auszutauschen?

lcd_data(pgm_read_byte_near(&copyRightChar[i]));

bzw. es mit neuem Namen aufzurufen? Beispiel: Einen Satz mit 
Sonderzeichen Graphik, einen mit Sonderzeichen Bedienung, einen mit 
Sonderzeichen Anlage
Es kann jeweils nur ein Zeichesatz mit 8 Zeichen geladen werden, ist 
klar.
Gibt es eine bessere Methode um das viele lcd_putc(0) einfacher 
darzustellen?
achim

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Achim Seeger schrieb:
> Gibt es eine bessere Methode um das viele lcd_putc(0) einfacher
> darzustellen?

Eine for-Schleife?

von Mark B. (markbrandis)


Lesenswert?

Möglicherweise geht auch ein lcd_puts("0000000000000");

von Georg G. (df2au)


Lesenswert?

Mark Brandis schrieb:
> Möglicherweise

ist 0x00 etwas anders als '0'.

von Mark B. (markbrandis)


Lesenswert?

Georg G. schrieb:
> Mark Brandis schrieb:
>> Möglicherweise
>
> ist 0x00 etwas anders als '0'.

Na dann eben:

1
    for (i=0; i<13; i++)
2
    {
3
        lcd_putc(0);
4
    }

von Achim S. (achims)


Lesenswert?

Keiner eine Idee für den mehrfachen Aufruf ?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Äh: Sowohl ich als auch Mark haben genau das gepostet: Eine Idee für 
den mehrfachen Aufruf.

Natürlich kannst Du Dir auch eine Funktion basteln, die das kapselt, à 
la
1
void lcd_putc_multi(char c, int anz)
2
{
3
  int i;
4
 
5
  for (i = 0; i < anz; i++)
6
    lcd_putc(c);
7
}

aber das ist trivial.

von Achim S. (achims)


Lesenswert?

Sorry, meinte noch was anderes.
Möchte die 8 Sonderzeichen mehrfach verschieden aufrufen. So wie das 
erste mal 8 Zeichen für einen Displayaufbau, wie striche, Ecken usw. 
Beim zweiten mal Sonderzeichen für Gebäude, z.B. Anzeige ob Ausgang 
An/aus, Gerät ein / aus. Als dritte Anzeige 8 Sonderzeichen z.B. über 
Gefahren. Das andere ist klar
achim

von spess53 (Gast)


Lesenswert?

Hi

>Möchte die 8 Sonderzeichen mehrfach verschieden aufrufen.

Dann musst du halt jedes mal die passenden Sonderzeichen in den 
Displaycontroller laden.

MfG Spess

von Digitalzwerg (Gast)


Lesenswert?

@ Achim Seeger

Theoretisch solltest Du, wenn Du einen Zeichensatz definieren kannst, 
denselben Vorgang auch für andere Zeichensätze beliebig oft und an 
beliebigen Stellen durchführen können, resp. ein solches Programm 
schreiben können.

Das setzt natürlich voraus, das Du C kannst, die Technik der 
Unterprogramme kennst und ein gewisses theoretisches Verständis vom 
Begriff der Abstraktion in Bezug auf die Programmierung hast. Was ist 
jetzt im Detail Dein Problem?


Beachte allerdings, das Du, (ich hoffe ich irre mich da nicht), immer 
nur EINEN eigenen Satz aus 8 Zeichen gleichzeitg anzeigen kannst.
D.h. es ist NICHT möglich, erstmal einen Zeichensatz mit 8 verschiedenen 
Häusern (mit und ohne Balkon, Schornstein und Terasse) zu definieren, 
diese alle anzuzeigen und danach einen neuen Zeichensatz mit 
Gartenzwergen zu definieren (mit und ohne Hacke, Giesskanne und Bart) zu 
definieren und während noch die Häuser angezeigt werden, jeweils einen 
besonderen Gartenzwerg davorzustellen. War das Deine Frage?

von Achim S. (achims)


Lesenswert?

Das sehe ich auch so. Habe ca. mehrere Zeichensätz mit Sonderzeichen. 
Das erste mal ist klar. Für das nächste mal muss ich neu laden, mit 
einem anderen Namen.

lcd_data(pgm_read_byte_near(&copyRightChar[i]));

Das erste mal mit diesem. Das zweite und mehr einen anderen Namen. Da 
der Zeichesatzziemlich am Anfang geladen wird, muus ich den anderen 
aufrufen, wenn er gebraucht wird. Und genau diese Stelleist mir nicht 
ganz klar. Wie kann ich ihn erneut aufrufen. z.B. so

void zeichensatz2
{
Zeichensatz
}
und beim nächsten genau so mit Zeichensatz 3?
achim

von Digitalzwerg (Gast)


Lesenswert?

1
void zeichensatz2
2
{
3
   Zeichensatz
4
}

Es wäre vielleicht sinnvoll, das Du mal ausführlich erklärst wie Du 
darauf kommst, das da eine Verschachtelung notwendig ist. Das scheint 
mir ein grundlegendes Verständnisproblem bei der Programmierung zu sein.

Jedenfalls läuft es dann etwas so:
1
static const PROGMEM unsigned char Zeichensatz1[] =
2
{
3
  0x00, ...  
4
};
5
6
static const PROGMEM unsigned char Zeichensatz2[] =
7
{
8
  0x00, ...  
9
};
10
11
static const PROGMEM unsigned char Zeichensatz3[] =
12
{
13
  0x00, ...  
14
};
15
16
main {
17
   ...
18
19
   for(i=0; i<64; i++)
20
   {
21
      lcd_data(pgm_read_byte_near(&Zeichensatz1[i]));
22
   }
23
   
24
   // Verwendung von Zeichensatz 1
25
26
   for(i=0; i<64; i++)
27
   {
28
      lcd_data(pgm_read_byte_near(&Zeichensatz2[i]));
29
   }
30
31
   // Verwendung von Zeichensatz 2
32
33
   for(i=0; i<64; i++)
34
   {
35
      lcd_data(pgm_read_byte_near(&Zeichensatz3[i]));
36
   }
37
38
   // Verwendung von Zeichensatz 3
39
40
   ...
41
}

Im übrigen könnte es nützlich sein, wenn Du verstehst, das Du NICHT 
jedesmal den kompletten Zeichensatz austauschen musst. Du kannst auch 
einzelne Zeichen im LCD austauschen.

von Digitalzwerg (Gast)


Lesenswert?

Da fehlt vor den Schleifen natürlich jeweils noch:
1
lcd_command(_BV(LCD_CGRAM));

Sorry. Mein Fehler.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

vor allem musst du den überblick behalten wann welcher zeichensatz aktiv 
und damit nutzbar ist und darfst den zeichensatatz/ das zeichen nur 
tauschen wenn es gerade nicht angezeigt wird.

von Digitalzwerg (Gast)


Lesenswert?

>Für das nächste mal muss ich neu laden, mit einem anderen Namen.

>Das erste mal mit diesem. Das zweite und mehr einen anderen Namen.

Mir ist nicht so ganz klar, warum Du hier so deutlich auf die "Namen" 
abfährst. Die Namen wovon genau?

Der einzige "Name" der hier eine Rolle spielt ist der Name der 
Variablen, die Deinen Zeichensatz enthält.

Das Inhalte über den Namen der Variablen identifiziert werden (im 
Kontext der Programmierung nennt man das Variablenname), ist eigentlich 
Grundlage der Programmierung. Verschiedene Werte werden über den Namen 
der sie enthaltenden Variablen unterschieden.

Vielleicht erklärst Du mal, was es für Dich mit den Namen auf sich hat.

von Digitalzwerg (Gast)


Lesenswert?

> ... darfst den zeichensatatz/ das zeichen nur tauschen wenn es gerade >nicht 
angezeigt wird.

Wobei noch zu ergänzen wäre, Winfried, dass es technisch durchaus 
möglich ist, die Zeichendefinition zu ändern, während es angezeigt wird.

Natürlich ist es seltsam, wenn sich bei einer Anzeige auf einmal ein 
Zeichen ändert. Es kann dann sein, dass die Anzeige auf einmal keinen 
Sinn mehr ergibt.
Darauf bezogst Du Dich wahrscheinlich, Winfried.

Ich merke das hier nur an, weil Deine Verwendung von "darfst" einem 
Anfänger möglicherweise suggeriert, das es andernfalls zu Fehlfunktionen 
oder gar Defekten kommt.

von Peter D. (peda)


Lesenswert?

Man kann immer nur 8 verschiedene Sonderzeichen darstellen.

Kürzlich war ein Thread, wo mehr dargestellt wurden. Dann ist aber die 
CPU zu 100% beschäftigt, ist also praktisch nutzlos.

von Digitalzwerg (Gast)


Lesenswert?

@ Peter Dannegger

> Man kann immer nur 8 verschiedene Sonderzeichen darstellen.

Nanu? Das ist hier schon geschrieben worden:
Beitrag "Re: Selbstdefinierte Zeichen"

Oder war etwas missverständlich?

von spess53 (Gast)


Lesenswert?

Hi

@ Achim Seeger (achims)

Vielleicht solltest du mal über die Verwendung eines Grafikdisplays 
nachdenken.

Das

http://www.pollin.de/shop/dt/NTE0OTc4OTk-/Bauelemente_Bauteile/Aktive_Bauelemente/Displays/LCD_Datavision_DG_12232.html

würde einem 20x4 Textdisplay entsprechen.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Achim Seeger schrieb:
> Das sehe ich auch so. Habe ca. mehrere Zeichensätz mit Sonderzeichen.
> Das erste mal ist klar. Für das nächste mal muss ich neu laden, mit
> einem anderen Namen.
>
> lcd_data(pgm_read_byte_near(&copyRightChar[i]));
>
> Das erste mal mit diesem. Das zweite und mehr einen anderen Namen. Da
> der Zeichesatzziemlich am Anfang geladen wird, muus ich den anderen
> aufrufen, wenn er gebraucht wird. Und genau diese Stelleist mir nicht
> ganz klar. Wie kann ich ihn erneut aufrufen. z.B. so
>
> void zeichensatz2
> {
> Zeichensatz
> }
> und beim nächsten genau so mit Zeichensatz 3?

Was genau ist dir daran unklar?

Selbstverständlich kannst du dir 3 Funktionen machen, die dir den 
Vorgang des Ladens der 8 Zeichen kapseln.
1
static const PROGMEM unsigned char graphicsChars[] =
2
{
3
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00,  
4
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x03, 0x03, 0x03,
5
  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  
6
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
7
  0x03, 0x03, 0x03, 0x1f, 0x1f, 0x00, 0x00, 0x00,   
8
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,   
9
  0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
10
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f   
11
};
12
13
static const PROGMEM unsigned char guiChars[] =
14
{
15
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00,  
16
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x03, 0x03, 0x03,
17
  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  
18
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
19
  0x03, 0x03, 0x03, 0x1f, 0x1f, 0x00, 0x00, 0x00,   
20
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,   
21
  0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
22
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f   
23
};
24
25
static const PROGMEM unsigned char buildingChars[] =
26
{
27
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00,  
28
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x03, 0x03, 0x03,
29
  0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,  
30
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,  
31
  0x03, 0x03, 0x03, 0x1f, 0x1f, 0x00, 0x00, 0x00,   
32
  0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18,   
33
  0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00,
34
  0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f   
35
};
36
37
void LoadGraphicsChars()
38
{
39
  lcd_command(_BV(LCD_CGRAM));  
40
  for( uint8_t i = 0; i < 64; i++ )
41
  {
42
    lcd_data( pgm_read_byte_near(&graphicsChars[i] ));
43
  }
44
}
45
46
void LoadGUIChars()
47
{
48
  lcd_command(_BV(LCD_CGRAM));  
49
  for( uint8_t i = 0; i < 64; i++ )
50
  {
51
    lcd_data( pgm_read_byte_near(&guiChars[i] ));
52
  }
53
}
54
55
void LoadBuildingChars()
56
{
57
  lcd_command(_BV(LCD_CGRAM));  
58
  for( uint8_t i = 0; i < 64; i++ )
59
  {
60
    lcd_data( pgm_read_byte_near(&buildingChars[i] ));
61
  }
62
}

und eine dieser Funktionen aufrufen, ehe du dann die entsprechenden 
Zeichen benutzt.
1
#define OK_SYMBOL          1
2
#define LEFT_ARROW_SYMBOL  2
3
4
....
5
6
void Menu1()
7
{
8
  lcd_clrscr();
9
  LoadGUIChars();
10
11
  lcd_putc( OK_SYMBOL );
12
  lcd_string( "erster Punkt" );
13
14
  lcd_putc( LEFT_ARROW_SYMBOL );
15
  lcd_string( "zweiter Punkt" );
16
}
(die #define wird man sinnvollerweise zu den Zeichensatzdefinitionen mit 
dazu nehmen)


Du stehst jetzt an einem Punkt, an dem die Sprache C immer unwichtiger 
wird und die Kombinationen und die Möglichkeiten die dir die Sprache 
gibt immer wichtiger werden. Jetzt fängt programmieren erst richtig an! 
Du bist der Programmierer, du kombinierst die Elemente der Sprache zu 
einem Programm. Genau aus dem Grund predige ich hier im Forum wieder und 
immer wieder: lernt die Grundlagen eurer Sprache. Aber lernt sie gut! 
Denn ansonsten werdet ihr von der Programmiersprache erschlagen. Man 
muss seine Sprache in Summe gut beherrschen - es reicht nicht nur 30% 
der Sprache zu kennen, denn dann weißt du nicht, welcher Möglichkeiten 
du eigentlich hast, was du überhaupt zur Verfügung hast um es 
einzusetzen. Alles hängt irgendwie mit allem anderen zusammen und erst 
in Summe ergibt sich dann das mächtige Werkzeug, das eine 
Programmiersprache darstellt. Das ist wie Schach: die Grundlage sind die 
Möglichkeiten wie die Figuren ziehen können. Aber die Komplexität eines 
Schachspiels und die Möglichkeiten ergeben sich daraus. Das ist nichts, 
was in die Figuren eingebaut wäre. Erst alle Figuren zusammen, ihre 
Schlagmöglichkeiten, ihre Zugmöglichkeiten machen das aus, was ein 
Schachspiel ausmacht. Nur weil man von ein paar Figuren weiß, wie sie 
ziehen können, ist man noch lang kein Schachspieler. Man ist auch dann 
noch kein Schachspieler, wenn man das von allen Figuren kennt. Aber in 
der Umkehrung kann man nie ein Schachspieler werden, wenn man nicht alle 
Figuren mit allen Zugmöglichkeiten kennt.
Und deswegen predige ich unermüdlich hier im Forum: Lernt eure Sprache 
und lernt sie gut! Sie sind die Schachfiguren, mit denen man arbeitet. 
Alles weitere ist dann ein Kombinieren der Möglichkeiten die man hat. 
Und daran lernt man ein Leben lang.
Aber die wenigsten wollen das hören.

: Bearbeitet durch User
von Achim S. (achims)


Lesenswert?

Danke Karl Heinz
Sehe jetzt deutlich, das ich es nicht zuende gedacht habe, war aber auf 
dem richtigen weg. Damit habe ich alle Möglichkeite, Anzeige und 
Programm anzupassen. Wunderbar. Danke.

Hallo Spess53
Danke für die Info, hatte es übersehen. Der Preis ist unschlagbar. Habe 
mich gerade von einen Graphik zu einem Textdisplay bewegt und es soweit 
in den griff bekommen. Bei diesem Typ ist der SED 1520 angegeben, ist 
der identisch? Sorry muss mir erst die Daten holen. Was ich jetz auf die 
schnelle nicht weiss, wie ist die Ansteuerung und die Ausgabe in Bezug 
auf die lcd-put usw, ist die gleich oder was ist der Unterschied? Meine 
damit z.B. das zeichnen von strichen oder box
achim

von Digitalzwerg (Gast)


Lesenswert?

Grummel.

von Achim S. (achims)


Lesenswert?

Hallo Karl Heinz
sehe jetzt erst wie du das gemacht hast. Ist noch anders als gedacht, 
aber sehr einfach und gut. Danke für deine Tips
achim

von Grummel (Gast)


Lesenswert?

@  Karl Heinz

Ich scheine überhaupt nicht begriffen zu haben, was das Problem des TO 
war.
Magst Du Dir mal kurz meine Antworten anschauen und einen kurzen 
Kommentar geben? Das wäre nett.

von spess53 (Gast)


Lesenswert?

Hi

>Bei diesem Typ ist der SED 1520 angegeben, ist der identisch?

Wenn du identisch mit dem HD44780 meinst, dann nein. Aber der SED1520 
ist ein Grafikcontroller mit einem recht übersichtlichen Befehlssatz. 
Aber ist er recht alt, so das sich recht viel im Internet finden lässt.

MfG Spess

von Digitalzwerg (Gast)


Lesenswert?

Oh. Falscher Name. Sorry.

@  Karl Heinz

Ich scheine überhaupt nicht begriffen zu haben, was das Problem des TO
war.
Magst Du Dir mal kurz meine Antworten anschauen und einen kurzen
Kommentar geben? Das wäre nett.

von Karl H. (kbuchegg)


Lesenswert?

Grummel schrieb:
> @  Karl Heinz
>
> Ich scheine überhaupt nicht begriffen zu haben, was das Problem des TO
> war.
> Magst Du Dir mal kurz meine Antworten anschauen und einen kurzen
> Kommentar geben? Das wäre nett.

Ich kann jetzt nicht ganz nachvollziehen, welche Antwort von dir war.
Wenn ich aber so alle Antworten durchsehe, dann würde ich von keiner 
sagen, dass sie am Thema vorbei geht. Alle beantworten die etwas 
unpräzise gestellte Frage auf ihre eigene Art und Weise, wobei der Fokus 
der einzelnen Antworten auf anderen Teilaspekten liegt, je nachdem was 
der Beantworter meint, aus der Frage herausgelesen zu haben.
Ich persönlich konzentriere mich als erstes meistens auf Sprachprobleme, 
Funktionsaufrufe etc. und liege damit meistens nicht so schlecht, wenn 
es darum geht zu erraten, was das eigentliche Problem des Fragestellers 
ist.
Obwohl ich mitlerweile denke, dass der Knackpunkt an dieser Stelle die 
TO-Annahme war, dass man den Zeichensatz nur einmal laden kann und dass 
dies unbedingt am Programmanfang passieren muss.

von Digitalzwerg (Gast)


Lesenswert?

>Ich kann jetzt nicht ganz nachvollziehen, welche Antwort von dir war.

Tschuldigung. Mein Fehler.

Jedenfalls Danke für den Kommentar.

> ... die TO-Annahme war ...

Ein Problem, das ich eigentlich immer versuche zu klären in dem ich nach 
den Gründen für die diversen Annahmen frage. Man bekommt aber fast nie 
eine Antwort darauf. (Siehe in diesem Thread die Frage nach der 
Bedeutung der "Namen" oder die Frage nach der "Verschachtelung").

Ich will da jetzt keine Diskussion anfangen. Dankeschön, jedenfalls.

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.