mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Grafik-Display mit T6963C Darstellungsfehler


Autor: Anubis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe bereits einige Zeit investiert, um auf meinem Grafik-Display 
VARITRONIX MGLS-12864T etwas vernüftig darzustellen.
Das Problem ist, dass nur in einer Zeile (etwas unterhalb der Mitte) 
etwas vernüftig angezeigt wird. Siehe hierzu Dateianhang!

Angeschlossen ist das Display an einem PIC16F877. Die Kontrastspannung 
beträgt -5V.
Mein Programm-Code sieht folgendermaßen aus:
/*******************************************************************************
********************                    ********************
********************         M O D U L K O P F    ********************
********************                    ********************
********************            (C)          ********************
********************                    ********************
********************************************************************************
------------------------------- Organisatorisches ------------------------------
                
    Modulname  :  LCD_T69693
    Projekt    :  LCD-Ansteuerung
    Compiler  :  CC5X (Freeware)
    Autor    :    
    Version    :  1.1
    Datum    :  29.03.20008
    
--------------------------------- Funktionales ---------------------------------
    Zweck
                    
    End_Zweck 
*******************************************************************************/

//Header-Datei für PIC 16F876 einbinden
#include <16f877.h>  

#define NotWR  PORTD.0        //Write LOW aktiv
#define NotRD  PORTD.1        //Read LOW aktiv
#define NotCE  PORTD.2        //Chip Enable LOW aktiv
#define NotCD  PORTD.3        //LOW = Data   HIGH = Command
#define NotRST  PORTD.4        //Reset LOW aktiv
#define FontSel  PORTD.5        //Font Select HIGH = 6x8  LOW = 8x8

void Delay_ms(uns8);
void Delay_us(uns16);
void InitLCD(void);
void CheckBusy(void);
void WriteCommand(uns8);
void WriteData(uns8);
void ClearLCD(void);
void Anzeigen_Test(void);

/*******************************************************************************
********************       Hauptprogramm          ***********************
********************************************************************************
    ProcName       :   main
    Autor        :    
    Datum        :  27.03.2008
    Sichtbarkeit  :  
    Funktion       :  Hauptprogramm
    
    Parameter       :  keine  
    Rückgabe       :  keine
*******************************************************************************/

void main()
{
 TRISD = 0;              //Port D als Ausgang
 PORTD = 255;
 T1CON = 0;              //Timer 1 Vorteiler 1:1
 NotRST = 0;
 Delay_ms(2);
 NotRST = 1;
 FontSel = 0;
 InitLCD();              //Display initialisieren
 Anzeigen_Test();
 while(1);
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   InitLCD
    Autor        :    
    Datum        :  28.03.2008
    Sichtbarkeit  :  
    Funktion       :  Initialisierung des Displays
    
    Parameter       :  keine  
    Rückgabe       :  keine
*******************************************************************************/

void InitLCD(void)
{
 TRISC = 0xFF;            //Port C als Eingang (D0 bis D7)
 
 /*Text Home Set*/
 WriteData(0x00);
 WriteData(0x00);
 WriteCommand(0x40);
 
 /*Text Area Set*/
 WriteData(0x10);          //16 Zeichen pro Zeile
 WriteData(0x00);
 WriteCommand(0x41);
 
 /*Grafik Home Adresse*/
 WriteData(0x00);
 WriteData(0x20);          //Adresse = 0x2000h
 WriteCommand(0x42);
 
 /*Grafik Area Set*/
 WriteData(0x10);
 WriteData(0x00);
 WriteCommand(0x43);
 
 /*Display im OR-Mode*/
 WriteCommand(0x80);
 
 /*Text an, Grafik an, Cursor aus*/
 WriteCommand(0x94);
 
 /*Adress-Pointer auf 0x0000h setzen*/
 WriteData(0x00);
 WriteData(0x00);
 WriteCommand(0x24);
 
 
 /*Offset Register setzen*/
 /*WriteData(0x00);
 WriteData(0x20);
 WriteCommand(0x22);*/
 
 /*Display löschen*/
 ClearLCD();
 
 /*Adress-Pointer auf 0x0000h setzen*/
 WriteData(0x40);
 WriteData(0x00);
 WriteCommand(0x24);
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   ClearLCD
    Autor        :    
    Datum        :  28.03.2008
    Sichtbarkeit  :  
    Funktion       :  Displays löschen
    
    Parameter       :  keine  
    Rückgabe       :  keine
*******************************************************************************/

void ClearLCD(void)
{
 uns16 Counter;
 
 /*Adress-Pointer auf 0x0000h setzen*/
 WriteData(0x00);
 WriteData(0x00);
 WriteCommand(0x24);
 
 /*Auto-Write aktivieren*/
 WriteCommand(0xB0);
 
 /*es müssen 8 Zeilen mit je 30 Zeichen gelöscht werden --> 8*16=240)*/
 for(Counter = 0; Counter < 240; Counter++)
 {
  WriteData(0x10);          //0x00 == kein Zeichen
 }

 /*Auto-Write deaktivieren*/
 WriteCommand(0xB2);
 
 
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   Delay_ms
    Autor        :    
    Datum        :  27.03.2008
    Sichtbarkeit  :  
    Funktion       :  Wartezeit in Millisekunden
    
    Parameter       :  Anzahl Millisekunden (uns8)  
    Rückgabe       :  keine
*******************************************************************************/

void Delay_ms(uns8 Milli)
{
 uns8 Durchgang;
 
 TMR1ON = 0;
 for(Durchgang = 0; Durchgang < Milli; Durchgang++)
 {
  TMR1H = 0xFC;
  TMR1L = 0x18;          //Timer 1 mit 64536 vorladen (1000 Durchgänge)
  TMR1IF = 0;
  TMR1ON = 1;
  while(!TMR1IF);
  TMR1ON = 0;
 }
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   Delay_us
    Autor        :    
    Datum        :  27.03.2008
    Sichtbarkeit  :  
    Funktion       :  Wartezeit in Mykrosekunden
    
    Parameter       :  Anzahl Mykrosekunden (uns8)  
    Rückgabe       :  keine
*******************************************************************************/

void Delay_us(uns16 Mykro)
{
 uns8 Wert1, Wert2, Counter;
 uns16 Temp, Zeit;
 
 TMR1ON = 0;
 Zeit = 65536 - Mykro;
 Temp = Zeit & 0xFF00;      //oberes Nibble isolieren
 Wert1 = Temp >> 4;        //Rechtsverschiebung um 4 Bit
 Temp = Zeit & 0x00FF;      //unteres Nibble isolieren
 Wert2 = Temp;
 
 for(Counter = 0; Counter < Mykro; Counter++)
 {
  TMR1H = Wert1;
  TMR1L = Wert2;
  TMR1IF = 0;
  TMR1ON = 1;
  while(!TMR1IF);
  TMR1ON = 0;
 }
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   CheckBusy
    Autor        :    
    Datum        :  28.03.2008
    Sichtbarkeit  :  
    Funktion       :  Statusabfrage des Displays
              Warten solange Stauts = Busy ist
    
    Parameter       :  keine  
    Rückgabe       :  keine
*******************************************************************************/

void CheckBusy(void)
{
 uns8 Status;
 
 TRISC = 255;
 do
 {
  NotCD = 1;
  NotCE = 1;
  NotRD = 1;
  NotWR = 1; 
  NotCE = 0;
  NotRD = 0;
  Delay_us(3);
  Status = PORTC;
  Status &= 0x03;
 }while(Status != 0x03);
 NotRD = 1;
 NotCE = 1;
 TRISC = 0;
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   WriteCommand
    Autor        :    
    Datum        :  28.03.2008
    Sichtbarkeit  :  
    Funktion       :  Kommando ins Display schreiben
    
    Parameter       :  Kommando (uns8)
    Rückgabe       :  keine
*******************************************************************************/

void WriteCommand(uns8 Command)
{
 TRISC = 0;
 CheckBusy();
 PORTC = Command;
 NotCD = 1;
 NotRD = 1;
 NotWR = 0;
 NotCE = 0;
 Delay_us(2);
 NotWR = 1;
 NotCE = 1;
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   WriteData
    Autor        :    
    Datum        :  28.03.2008
    Sichtbarkeit  :  
    Funktion       :  Daten ins Display schreiben
    
    Parameter       :  Daten (uns8)
    Rückgabe       :  keine
*******************************************************************************/

void WriteData(uns8 Data)
{
 TRISC = 0;
 CheckBusy();
 PORTC = Data;
 NotCD = 0;
 NotRD = 1;
 NotWR = 0;
 NotCE = 0;
 Delay_us(2);
 NotWR = 1;
 NotCE = 1;
}

/*******************************************************************************
********************       Unterprogramm          ***********************
********************************************************************************
    ProcName       :   Anzeigen_Test
    Autor        :    
    Datum        :  29.03.2008
    Sichtbarkeit  :  
    Funktion       :  Test der Ausgabe 
              gesammtes display mit 'A' füllen
              
    Parameter       :  keine
    Rückgabe       :  keine
*******************************************************************************/

void Anzeigen_Test(void)
{
 uns16 Counter;
 
 /*Adress-Pointer auf 0x0000h setzen*/
 WriteData(0x00);
 WriteData(0x00);
 WriteCommand(0x24);
 
 /*Auto-Write aktivieren*/
 WriteCommand(0xB0);
 
 /*es müssen 8 Zeilen mit je 30 Zeichen gelöscht werden --> 8*16=240)*/
 for(Counter = 0; Counter < 240; Counter++)
 {
  WriteData(0x21);          //Zeichen = 'A'
 }

 /*Auto-Write deaktivieren*/
 WriteCommand(0xB2);
 
}

Eigentlich müsste das Display komplett mit 'A' gefüllt sein, aber leider 
ist das Ergebnis wie auf dem Foto zu sehen.

Ist mein Code fehlerhaft, bzw. die Initialisierung des Displays? Oder 
ist das Display einfach nur defekt?

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Bild???
Nur kurz reingeschaut:

Wieviel Ram hat das TEil denn? Du setzt die Grafikarea aud 0x2000, das 
ist 8k. Die kleinen haben doch meist nur 8k Ram drauf, damit würde die 
Grafikarea bei 0x0000 landen und da hast Du ihm schon Text gesagt?

Gruß aus Berlin
Michael

Autor: Anubis (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

okay 2.Versuch mit dem Dateianhang.

Das Ding hat ein 8k-RAM.

Der Text-Modus ist eingestellt.

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sieht aber schwer nach Grafikmodus aus.

Autor: die ??? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Edit: Will sagen, die Daten scheinen im Grafikbereich zu liegen. 
Allerdings wundert mich die Regelmäßigkeit. Hab deinen Code jedoch nicht 
beaugapfelt.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

mich stört immernoch etwas der Start Grafik auf 0x2000. Bei 8k Ram liegt 
dann Grafik. und Text Ram auf den gleichen Adressen. Keine Ahnung, was 
der T6963C da macht.
Setz doch mal Grafikram auf einen sinnvollen Wert, 0x0400 oder so, Du 
brauchst doch erstmal nur 16x8 Byte für den Textram.
Einfach, um das mal auszuschließen.

Gruß aus Berlin
Michael

Autor: Anubis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so, ich habe mal den Adressbereich für die Grafik verändert (0x0400). 
Ohne Erfolg - Display zeigt immer noch den selben Murks.

Hat noch jemand eine Ideee? Oder kann ich davon ausgehen, dass das 
Display hin ist?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du löschst nur den Textbereich. Im Grafikbereich bleibt dann noch 
irgendwas zufälliges drin, was vorher schon drin stand. Lösch doch mal 
alle 8192 Bytes in der Initialisierungsroutine.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Hat noch jemand eine Ideee? Oder kann ich davon ausgehen, dass das
>Display hin ist?

Sieht so aus als wären die Zeilentreiber hin. Was man
sieht sind ja alles Reste von den 'A'.

Autor: Anubis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe gerade gesehn, dass in Code in kleiner Fehler drinsteckt.
/*Text an, Grafik an, Cursor aus*/
 WriteCommand(0x94);

Bei 0x94 ist nur der Text-Modus aktiv!

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:

> Sieht so aus als wären die Zeilentreiber hin. Was man
> sieht sind ja alles Reste von den 'A'.

Stimmt. Er verwendet den OR Modus, von daher würden Daten im 
Grafikbereich zusätzliche Pixel ergeben. Es fehlen aber welche.

Wobei ich nicht auf die Zeilentreiber tippe, sondern auf die Leitgummis 
die das LCD mit der Platine verbinden.

Autor: Anubis (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

so, ich habe gestern noch ein wenig experiemntiert. Der Fehler wird 
durch das Flachbandkabel (das LCD mit der Platine verbindet), das für 
die Zeilenansteuerung da ist.

Autor: Rick Dangerus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum macht Ihr den Code nicht lesbarer?
Hier mal ein Beispiel (Auszug):

#define T6963_SET_CURSOR_POINTER        0x21
#define T6963_SET_OFFSET_REGISTER       0x22
#define T6963_SET_ADDRESS_POINTER       0x24

#define T6963_SET_TEXT_HOME_ADDR        0x40
#define T6963_SET_TEXT_AREA             0x41
#define T6963_SET_GRAPHIC_HOME_ADDR     0x42
#define T6963_SET_GRAPHIC_AREA          0x43

#define T6963_MODE_SET          0x80
#define MS_OR                   0
#define MS_EXOR                 1
#define MS_AND                  3
#define MS_TEXT_ATTR            4
#define MS_INTERNAL_CG          0       // char 128..255 userdefined
#define MS_EXTERNAL_CG          8       // all char userdefined

#define T6963_DISPLAY_MODE      0x90
#define DM_OFF                  0
#define DM_CURSOR_BLINK         1
#define DM_CURSOR_ON            2
#define DM_TEXT_ON              4
#define DM_GRAPH_ON             8

#define T6963_SET_CURSOR_PATTERN        0xA0

#define T6963_DATA_AUTO_WRITE           0xB0
#define T6963_DATA_AUTO_READ            0xB1
#define T6963_AUTO_MODE_RESET           0xB3

#define T6963_DATA_WRITE_INCREMENT      0xC0
#define T6963_DATA_READ_INCREMENT       0xC1
#define T6963_DATA_WRITE_DECREMENT      0xC2
#define T6963_DATA_READ_DECREMENT       0xC3
#define T6963_DATA_WRITE                0xC4
#define T6963_DATA_READ                 0xC5

#define T6963_BIT_RESET         0xF0
#define T6963_BIT_SET           0xF8


...

void T6963_InitDisplay (void)
{
  INIT_CONTROL_PINS ();         //WR,CE,RD,C/D auf Ausgang

  CE_ON();
  WR_ON();
  RD_ON();

  T6963_WriteData2( TEXT_AREA, T6963_SET_TEXT_HOME_ADDR);
  T6963_WriteData2( BYTES_PER_ROW, T6963_SET_TEXT_AREA);

  T6963_WriteData2( GRAPH_AREA, T6963_SET_GRAPHIC_HOME_ADDR);
  T6963_WriteData2( BYTES_PER_ROW, T6963_SET_GRAPHIC_AREA);

  T6963_WriteData2( (CHARGEN_AREA >> 11), T6963_SET_OFFSET_REGISTER);

  T6963_ClearScreen ();
  T6963_ClearTextScreen();

  T6963_WriteCommand (T6963_MODE_SET + MS_INTERNAL_CG + MS_EXOR);
  T6963_WriteCommand (T6963_DISPLAY_MODE + DM_GRAPH_ON + DM_TEXT_ON);

}

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@ Rick Dangerus: kann Dir nur zustimmen, mache ich auch so ähnlich.
Wenn man den Code wiederbenutzt, ist man sich spätestens nach ein paar 
Monaten selbst dankbar dafür, weil man es so noch versteht und viel Zeit 
spart. :-)

Gruß aus Berlin
Michael

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.