Kleines Problem beim T6963C (Grafik Modus)

Gast #1969236
Lesenswert?

Hallo zusammen,

ich habe ein Problem mit der Ansteuerung meines Grafik Displays. Ich 
habe mir ein Display mit 240*128 Pixeln und dem T6963C Controller drauf 
gekauft. Den Textmodus habe ich bereits im Griff und nun wollte ich mich 
am Grafikmodus versuchen allerdings scheint es nicht ganz zu klappen.

Wie gesagt der Textmodus läuft ohne Probleme. Und mein Problem beim 
Grafikmodus ist folgendes: Ich möchte lediglich zum Verständnis des 
Controllers ein einziges Bit/Pixel auf dem Display an einer gewählten 
Stelle setzten. Aus dem Datenblatt habe ich erlesen, dass man wie folgt 
vorgehen soll:

*1. Die Adresse setzten*
(Das mache ich mit der selben Funktion mit der ich auch im Textmodus die 
Zeilen und Spalten angesteuert habe)

*2. Die Statusbits überprüfen*

*3. Den Befehl für Bit Set senden*

Hier ist meine Initialisierung mit den entsprechenden Speicherbereichen 
für die beiden Modi (hoffentlich richtig berechnet --> Text braucht min. 
480 Bytes und Grafik braucht min. 3840 Bytes):
1
void GLCD_Initialisierung(void)
2
{
3
  LCD_RST = 0;
4
  Delay10TCYx(10);
5
  LCD_RST = 1;
6

7
  LCD_CE = 1;  
8

9
// Grafikbereich im Speicher 768 - 8192
10
  GLCD_Daten  (0x00);    // Grapic home address (low)
11
  GLCD_Daten  (0x03);    // ...(high)
12
  GLCD_Befehl (0x42);    // ...
13

14
  GLCD_Daten  (0x00);    // Graphic area set (low)
15
  GLCD_Daten  (0x12);    // ...(high)
16
  GLCD_Befehl (0x43);    // ...
17

18
// Text Bereich im Speicher 0-512
19
  GLCD_Daten  (0x00);    // Text home adress (low)
20
  GLCD_Daten  (0x00);    // ...(high)
21
  GLCD_Befehl (0x40);    // ...
22

23
  GLCD_Daten  (0x00);    // Text area set (low)
24
  GLCD_Daten  (0x02);    // ...(high)
25
  GLCD_Befehl (0x41);    // ...
26

27
// Weiteres
28
  GLCD_Befehl (0x80);    // Mode set (OR)
29
  GLCD_Befehl (0x9C);    // Display mode (Grafik und Text)
30

31
  Display_Loeschen();

Die Routine Display_Löschen ist ebenfalls die selbe wie vom Textmodus:
1
void Display_Loeschen(void)
2
{
3
  unsigned char i;
4

5
  GLCD_Position(1,1);
6

7
  for(i=0; i<(GLCD_Cols * GLCD_Height/64); i++)
8
  {
9
       GLCD_Schreiben(' '); GLCD_Schreiben(' ');
10
       GLCD_Schreiben(' '); GLCD_Schreiben(' ');
11
       GLCD_Schreiben(' '); GLCD_Schreiben(' ');
12
       GLCD_Schreiben(' '); GLCD_Schreiben(' ');
13
    } 
14
  GLCD_Position(1,1);
15
}

Die Routine zum Bit Set habe ich in den Anhang geladen, da sonst wegen 
der Kommentare hier in der Browseransicht alles verschoben wäre.

Ich freue mich auf Rückmeldungen =)
Gruß Hans
Angehängte Dateien:
Gast #1969245
Lesenswert?

Das wichtigste habe ich vergessen: Das Display möchte ich halt in beiden 
Modi gleichzeitig betreiben. Ich habe ganz oben in der ersten Zeile 
(1,1)  einen Text ausgegeben. Und in der Zeile 5 Spalte 5 möchte ich das 
Bit 5 setzten:
1
  GLCD_Zeichenkette("Multimedia Modul");
2
  Pixel_setzten(5,5,5);

Und das Display sieht folgendermaßen aus: Es ziehen sich von oben nach 
unten Streifen übers ganze Display. Und man kann den Text erahnen, 
welcher ebenfalls wie die Striche nach unten wiederholt wirkt.
Gast #1969332
Lesenswert?

Hi

Was mir erstmal auffällt sind deine Werte für Text- und Grafikarea. Bei 
einem 240 Pixel breiten Display und einem 8x8 Font sollten beide Werte 
$1E (30) sein. Das sind die dargestellten Byte in einer Zeile.

MfG Spess
Gast #1969350
Lesenswert?

Achso. Ich dachte das wäre quasi ein Bereich indem Platz wäre um das 
Display einmal zu füllen.. Aber wie wählt man dann die Home Adressen 
aus? Einfach nur, dass sie sich nicht überlagern?

(Jetzt bekomme ich einfach nur wilde Punkte überall.)

Also sehe es so aus:
1
// Grafikbereich im Speicher 768 - 8192
2
  GLCD_Daten  (0x00);    // Grapic home address (low)
3
  GLCD_Daten  (0x03);    // ...(high)
4
  GLCD_Befehl (0x42);    // ...
5

6
  GLCD_Daten  (0x1E);    // Graphic area set (low)
7
  GLCD_Daten  (0x00);    // ...(high)
8
  GLCD_Befehl (0x43);    // ...
9

10
// Text Bereich im Speicher 0-512
11
  GLCD_Daten  (0x00);    // Text home adress (low)
12
  GLCD_Daten  (0x00);    // ...(high)
13
  GLCD_Befehl (0x40);    // ...
14

15
  GLCD_Daten  (0x1E);    // Text area set (low)
16
  GLCD_Daten  (0x00);    // ...(high)
17
  GLCD_Befehl (0x41);    // ...
Gast #1969379
Lesenswert?

Hi

Mit folgenden Werten funktioniert es bei mir:

    .equ grahome   = $0000                ;Gafic Home Adress
    .equ txthome   = $1700                ;Text Home Adress(4kByte)

    .equ graarea   = $1e                  ;Grafic Area
    .equ txtarea   = $1e                  ;Text Area

MfG Spess
Gast #1969409
Lesenswert?

Aber es ist doch egal ob ich den Textspeicher vor oder hinter dem 
Grafikspeicher habe oder etwa nicht?

Danke für deine Hilfe btw. =)

Also ich habe jetzt folgende Werte (Wenn ich deine Werte übernehme 
funktioniert meine Textausgabe nicht mehr):
1
GLCD_Daten  (0x00);    // Grapic home address (low)
2
GLCD_Daten  (0x03);    // ...(high)
3
..
4

5
GLCD_Daten  (0x1E);    // Graphic area set (low)
6
GLCD_Daten  (0x00);    // ...(high)
7
..
8

9
GLCD_Daten  (0x00);    // Text home adress (low)
10
GLCD_Daten  (0x00);    // ...(high)
11
..
12

13
GLCD_Daten  (0x1E);    // Text area set (low)
14
GLCD_Daten  (0x00);    // ...(high)
15
..

Und ich habe jetzt mal wie folgt versucht das Display zu löschen indem 
ich den ganzen Speicher mit 0en fülle:
1
void Speicher_Loeschen(void)
2
{
3
  unsigned int i;
4

5
  Speicher_Adresse(0x0000);
6

7
  for(i=0; i<(0xFFFF); i++)
8
  {
9
       GLCD_Daten(0);
10
    } 
11
  GLCD_Position(1,1);
12
}
13

14
void Speicher_Adresse (unsigned int Adresse)
15
{
16
  GLCD_Daten(Adresse%256);
17
  GLCD_Daten(Adresse>>8);
18
  GLCD_Befehl(0x24);
19
}

Wenn ich jetzt schreibe scheint es fast zu klappen bis auf eine 
Kleinigkeit. Anstatt dass nur 1 Pixel gesetzt wird erscheint ein Zeichen 
könnte ein @ sein (siehe Anhang).
Angehängte Dateien:
Gast #1969420
Lesenswert?

Hi

>Wenn ich jetzt schreibe scheint es fast zu klappen bis auf eine
>Kleinigkeit. Anstatt dass nur 1 Pixel gesetzt wird erscheint ein Zeichen
>könnte ein @ sein (siehe Anhang).

Dann schreibst du in den Textspeicher.

>  GLCD_Daten(Adresse%256);
>  GLCD_Daten(Adresse>>8);
>  GLCD_Befehl(0x24);

Hast du den Anfang des Grafikspeichers berücksichtigt. Das Byte links 
oben ist Grafik Home.

MfG Spess
Gast #1969462
Lesenswert?

Ich orientiere mich i.M. an dem hier:
http://www.mikrocontroller.net/attachment/highlight/16188

Und stecke grad in der Funktion "glcd_setpixel" fest in folgender Zeile:
1
addr =  glcd_G_BASE + (row*glcd_BYTES_PER_ROW)  + (column/8);

Hier wird doch nun die Adresse zusammen geschustert an der im RAM dann 
das Pixel gesetzt werden soll, richtig? Warum addiert er hinten 
(colums/8)? Wird somit nicht bei einem 16 Zeilen (128 Pixel) Display 
nicht immer das 2 Pixel gesetzt also Bit 1? Oder verstehe ich das gerade 
falsch..

Ich bin mal zum Zahnarzt hehe bis später und nochmal Danke ;-)
Gast #1969895
Lesenswert?

Ich bin ehrlich gesagt gerade ein bisschen am Verzweifeln. Ich habe 
meine Routinen jetzt folgendermaßen:

Ich habe jetzt die Werte von Spess übernommen für die Homeadressen.
1
// 0x0000 = 0
2
  GLCD_Daten  (0x00);    // Grapic home address (low)
3
  GLCD_Daten  (0x00);    // ...(high)
4
  GLCD_Befehl (0x42);    // ...
5

6
  GLCD_Daten  (0x1E);    // Graphic area set (low)
7
  GLCD_Daten  (0x00);    // ...(high)
8
  GLCD_Befehl (0x43);    // ...
9

10
// 0x1700 = 5888
11
  GLCD_Daten  (0x00);    // Text home adress (low)
12
  GLCD_Daten  (0x17);    // ...(high)
13
  GLCD_Befehl (0x40);    // ...
14

15
  GLCD_Daten  (0x1E);    // Text area set (low)
16
  GLCD_Daten  (0x00);    // ...(high)
17
  GLCD_Befehl (0x41);    // ...
18

19
// Weiteres
20
  GLCD_Befehl (0x80);    // Mode set (OR)
21
  GLCD_Befehl (0x9C);    // Display mode (Grafik und Text)
22

23

24
  Speicher_Loeschen();  // Den gesamten Speicher löschen

Speicher löschen ruft nacheinander diese beiden Funktionen auf, welche 
den gesamten Inhalt des RAMs löschen sollen indem sie 0en hinein 
schreiben:
1
void Grafik_Speicher_Loeschen(void)
2
{
3
  unsigned int i;
4

5
  Speicher_Adresse(0x0000);
6

7
  for(i=0; i<(0x16FF); i++)
8
  {
9
       GLCD_Daten(0);
10
    } 
11
  GLCD_Position(1,1);
12
}
1
void Text_Speicher_Loeschen(void)
2
{
3
  unsigned int i;
4

5
  Speicher_Adresse(0x1700);
6

7
  for(i=0x1700; i<(0xFFFF); i++)
8
  {
9
       GLCD_Daten(0);
10
    } 
11
  GLCD_Position(1,1);
12
}

Eigentlich habe ich mir vorgestellt, dass nun das Display leer ist. Aber 
Pustekuchen =( es ist voller Müll.

So sieht meine Routine aus um zu einer bestimmten Speicheradresse zu 
springen. Im Prinzip ist es die selbe wie hier:
http://www.mikrocontroller.net/attachment/highlight/16188

Nur leicht geändert, da meine Ausgabe-Funktionen mit 8 Bit arbeiten. 
Also habe ich die 16 Bit Adresse in zwei 8 Bit Variablen gewandelt und 
übertrage diese einzeln. Erst Low, dann High.
1
void Speicher_Adresse (unsigned int Adresse)
2
{
3
  unsigned char Low;
4
  unsigned char High;
5

6
  Low = Adresse&255;
7
  Adresse=Adresse>>8;
8
  High = Adresse&255;
9
  
10
  GLCD_Daten(Low);
11
  GLCD_Daten(High);
12
  GLCD_Befehl(0x24);
13
}

>Hast du den Anfang des Grafikspeichers berücksichtigt. Das Byte links
>oben ist Grafik Home.

Das verstehe ich nicht, was meinst du damit?

Nabend
Gast #1969912
Lesenswert?

Okay ein Fehler ist gefunden! Bei den Routinen:
- void Grafik_Speicher_Loeschen(void)
- void Text_Speicher_Loeschen(void)
fehlte jeweils der Befehl: GLCD_Befehl  (0xC0); in der for Schleife.

So ich versuche mich weiter... pfff
Gast #1971004
Lesenswert?

Kann es sein, dass der C18 hier wieder irgendwas krankes optimiert?
1
ADR = ((X-1)*30)+((Y-1)/8);

Diese Rechnung ergibt bei X=64 und Y=120 nämlich nicht 1904.. Warum??
Wenn ich folgendes schreibe wird auch 1904 in die Variable ADR (unsigned 
int) geschrieben:
1
ADR=1904;
Gast #1971041
Lesenswert?

Fakt ist, ich möchte die Rechnung durchführen aber es funktioniert 
komischerweise nicht.

Also das hier funktioniert nicht:
1
Pixel_setzten(64,120);
2

3
void Pixel_setzten(unsigned char X, unsigned char Y)
4
{
5
unsigned int ADR;    // Zur Berechnung der RAM Adresse
6
ADR = 0;      // Die Grafik Home Adresse
7

8
if ( (X>128) | (Y>240) )   // Wenn der adressierte Bereich
9
{        // außerhalb des Displays liegt,
10
  return;      // dann springe sofort zurück!
11
}  
12

13
ADR = ((X-1)*30)+((Y-1)/8);  
14
ADR = 1904;
15

16
Speicher_Adresse(ADR);
17
Busy_Abfrage();      // Nachfragen ob das Display fertig ist
18

19
GLCD_Befehl (0xF8+1);            
20
}

Das dann schon:
1
Pixel_setzten(64,120);
2

3
void Pixel_setzten(unsigned char X, unsigned char Y)
4
{
5
unsigned int ADR;    // Zur Berechnung der RAM Adresse
6
ADR = 0;      // Die Grafik Home Adresse
7

8
if ( (X>128) | (Y>240) )   // Wenn der adressierte Bereich
9
{        // außerhalb des Displays liegt,
10
  return;      // dann springe sofort zurück!
11
}  
12

13
ADR = ((X-1)*30)+((Y-1)/8);  
14
ADR = 1904;  <--------------------------------------
15

16
Speicher_Adresse(ADR);
17
Busy_Abfrage();      // Nachfragen ob das Display fertig ist
18

19
GLCD_Befehl (0xF8+1);            
20
}

Aber warum denn?
Gast #1971055
Lesenswert?

Hab den Fehler gefunden!

Im Programkopf muss unsigned int X und Y stehen. Ich verstehe allerdings 
nicht ganz wieso. Kann mir das jemand erklären?

Also ist es so, dass zunächst (bei der Rechnung) X-1 und dann *30 UND 
DAS wird dann erst in X geschrieben bevor es in ADR kommt?
Gast #1971071
Lesenswert?

Jemand schrieb:
> Also ist es so, dass zunächst (bei der Rechnung) X-1 und dann *30 UND
> DAS wird dann erst in X geschrieben bevor es in ADR kommt?

Korrekt - wie sollte es denn sonst laufen. Wenn du es die als Listing 
anzeigen lässt, sollte auch klar werden warum. Das Ganze läuft ja 
sequentiell ab. Das es hier in C so schön in eine Zeile passt heisst ja 
nicht, dass es so durch Comiler auch in einem Befehl bearbeitet werden 
kann (wie auch - sind ja schon alleine vier Rechenbefehle).

- gerd
Gast #1971256
Lesenswert?

Hi

>So nun habe ich das Display im Griff.

Na, geht doch. Aber eine Frage: Warum fängst du mit der Spalten- und 
Zeilenzählung nicht bei 0 an? Deine Berechnungen vereinfachen sich und 
werden dadurch auch schneller.

MfG Spess
Gast #1971308
Lesenswert?

Hi

>Ich meine ist nur hier und da eine Subtraktion um 1.

Kommt darauf an, was dein Compiler daraus macht. Und es ist nicht nur 
die -1

Was passiert hier:

>if ( (X>128) | (Y>240) )  ....

 bei X oder Y =0?

MfG Spess

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