Forum: Mikrocontroller und Digitale Elektronik t6963c Falsche Zeichen auf dem Display


von Ramon (Gast)


Lesenswert?

Hallo,

ich habe ein EADIP240-7 und versuche mit einem Arduino Uno, das Teil zum 
Laufen zu bringen. Die Initialisierung klappt soweit, nur wenn ich jetzt 
Text auf dem Display anzeigen möchte, dann sind die Buchstaben irgendwie 
falsch. Aus einem "A" macht er ein "B" und umgekehrt, ebenso aus einem 
"E" ein "F" und umgekehrt und so weiter.

Ich habe meinen Code unten angefügt, er stammt größtenteils von 
http://en.radzio.dxp.pl/t6963/, ich habe den Code lediglich an den 
Arduino angepasst. Programmieren tue ich mit der 
Arduino-Entwicklungsumgebung. Ich wäre froh, wenn mir jemand 
weiterhelfen könnte.

Vielen Dank im Voraus,

Ramon

-------------------------------------------------

#define READ_PIN   8 //  Wenn dieser Pin LOW ist, dann wird gelesen
#define WRITE_PIN  9 //  Wenn dieser Pin LOW ist, dann wird geschrieben
#define CD_PIN    10 //  Data/Command-Pin; wenn dieser Pin LOW ist, dann 
werden werden Daten geschrieben
                     //  Wenn HIGH, dann wird ein Befehl gesendet

#define CE_PIN    11 //  Chip Enable; wenn dieser Pin LOW ist, dann ist 
der Controller aktiv. Bei HIGH ist der
                     //  Controller inaktiv

#define RESET_PIN 12 //  Wenn dieser Pin LOW ist, dann erfolgt ein Reset

#define GLCD_TEXT_HOME                  0    // Text Home ist 0x00
#define GLCD_PIXELS_PER_LINE          240  // Anzahl der Pixel = 240 bei 
dem EADIP240-7
#define GLCD_FONT_WIDTH            8    // Fontbreite
#define GLCD_NUMBER_OF_LINES            128  // Anzahl der Zeilen = 128 
bei dem EADIP240-7
#define GLCD_OFFSET_REGISTER    2
#define GLCD_EXTERNAL_CG_HOME    (GLCD_OFFSET_REGISTER << 11)

#define GLCD_TEXT_AREA            (GLCD_PIXELS_PER_LINE / 
GLCD_FONT_WIDTH)    //240 / 8 = 30 = 1EH
#define GLCD_TEXT_SIZE      (GLCD_TEXT_AREA * (GLCD_NUMBER_OF_LINES/8)) 
//30 * (128/8) = 480 = 1E0H

#define GLCD_GRAPHIC_HOME          (GLCD_TEXT_HOME + GLCD_TEXT_SIZE) 
//0 + 480 = 480
#define GLCD_GRAPHIC_AREA    (GLCD_PIXELS_PER_LINE / GLCD_FONT_WIDTH) 
//240/8 = 30
#define GLCD_GRAPHIC_SIZE          (GLCD_GRAPHIC_AREA * 
GLCD_NUMBER_OF_LINES)  //30 * 128 = 3840

// Die folgenden Befehle und Bytes stammen aus dem Datenblatt des T6963C
#define T6963_SET_ADDRESS_POINTER  0x24
#define T6963_SET_CURSOR_POINTER        0x21
#define T6963_SET_OFFSET_REGISTER  0x22
#define T6963_SET_ADDRESS_POINTER  0x24

#define T6963_SET_TEXT_HOME_ADDRESS  0x40
#define T6963_SET_TEXT_AREA    0x41
#define T6963_SET_GRAPHIC_HOME_ADDRESS  0x42
#define T6963_SET_GRAPHIC_AREA    0x43

#define T6963_MODE_SET      0x80

#define T6963_SET_DATA_AUTO_WRITE  0xB0
#define T6963_SET_DATA_AUTO_READ  0xB1
#define T6963_AUTO_RESET    0xB2

#define T6963_DATA_WRITE_AND_INCREMENT  0xC0
#define T6963_DATA_READ_AND_INCREMENT  0xC1
#define T6963_DATA_WRITE_AND_DECREMENT  0xC2
#define T6963_DATA_READ_AND_DECREMENT  0xC3
#define T6963_DATA_WRITE_AND_NONVARIALBE  0xC4
#define T6963_DATA_READ_AND_NONVARIABLE  0xC5

#define T6963_SET_DATA_AUTO_WRITE    0xB0
#define T6963_SET_DATA_AUTO_READ    0xB1
#define T6963_AUTO_RESET      0xB2

#define T6963_DATA_WRITE_AND_INCREMENT    0xC0
#define T6963_DATA_READ_AND_INCREMENT    0xC1
#define T6963_DATA_WRITE_AND_DECREMENT    0xC2
#define T6963_DATA_READ_AND_DECREMENT    0xC3
#define T6963_DATA_WRITE_AND_NONVARIALBE  0xC4
#define T6963_DATA_READ_AND_NONVARIABLE    0xC5

#define T6963_SCREEN_PEEK      0xE0
#define T6963_SCREEN_COPY      0xE8
#define T6963_DISPLAY_MODE      0x90
#define T6963_CURSOR_BLINK_ON      0x01
#define T6963_CURSOR_DISPLAY_ON      0x02
#define T6963_TEXT_DISPLAY_ON      0x04
#define T6963_GRAPHIC_DISPLAY_ON    0x08

int flg = 0; //Wird in der Loop-Schleife bentigt

/**************************
//
//  Controller zuruecksetzen
//
***************************/
void GLCD_Reset() {
  digitalWrite(RESET_PIN, LOW); //Reset-Pin auf LOW
  delay(10);                    //10 ms warten
  digitalWrite(RESET_PIN, HIGH);//Reset-Pin auf HIGH
  delay(10);                    //10 ms warten
}


/****************************
//
// Delay-Routine
//
*****************************/
void soft_delay(void) {
  unsigned char i;

  for (i = 0; i < F_CPU/1000000; i++) {
    asm("nop");
  }
}

/******************************
//
// Liest den Status des Displays aus
//
*******************************/
unsigned char GLCD_CheckStatus(void)
{
  uint8_t tmp;
  DDRD = 0x00; //Datenrichtung: Port D als Eingang

  digitalWrite(CE_PIN, LOW);    // Chip-Enable-Pin auf LOW
  digitalWrite(READ_PIN, LOW);  // Read--Pin auf LOW
  digitalWrite(WRITE_PIN, HIGH);// Write-Pin auf HIGH

  soft_delay();  //Delay
  tmp = PIND;    // Port D einlesen

  DDRD = 0xFF;   //Datenrichtung von Port D auf Ausgang

  digitalWrite(READ_PIN, HIGH);  // Read-Pin auf HIGH
  digitalWrite(CE_PIN, HIGH);    // Chip-Enable auf HIGH
  return tmp;
}

/*****************************
//
// Daten ueber Port D einlesen
//
******************************/
unsigned char GLCD_ReadData(void)
{
  uint8_t tmp;
  while(!(GLCD_CheckStatus()&0x03)); // Warten, bis Display bereit

  DDRD = 0x00;  // Datenrichtung Port D auf Eingang

  digitalWrite(CE_PIN, LOW);    // Chip-Enable-Pin auf LOW
  digitalWrite(READ_PIN, LOW);  // Read-Pin auf LOW

  soft_delay();                 // Warten...
  tmp = PIND;                   // Port D einlesen

  digitalWrite(READ_PIN, HIGH); // Read-Pin auf HIGH
  digitalWrite(CE_PIN, HIGH);   // Chip-Enable-Pin auf HIGH

  DDRD = 0xFF;                  // Port D wieder auf Ausgang
  return tmp;
}

/************************
//
// Schreibt einen Befehl ueber Port D in das Display
//
*************************/
void GLCD_WriteCommand(unsigned char command)
{
  while(!(GLCD_CheckStatus()&0x03));  // Warten bis Display bereit
  PORTD = command;                    // Befehl auf Port D schreiben

  digitalWrite(CE_PIN, LOW);          // Chip-Enable-Pin auf LOW
  digitalWrite(CD_PIN, HIGH);         // CD-Pin auf HIGH, es wird ein 
Befehl geschrieben
  digitalWrite(WRITE_PIN, LOW);       // Write-Pin auf LOW

  soft_delay();                       // Warten

  digitalWrite(WRITE_PIN, HIGH);      // Write-Pin wieder auf HIGH
  digitalWrite(CE_PIN, HIGH);         // Chip-Enable auf HIGH
}


/*****************************
//
// Schreibt ein Datenbyte auf den Port D
//
******************************/
void GLCD_WriteData(uint8_t data)
{
  while(!(GLCD_CheckStatus()&0x03));  // Warten bis Display bereit
  PORTD = data;                       // Datenbyte auf Port D schreiben

  digitalWrite(CE_PIN, LOW);          // Chip-Enable auf LOW
  digitalWrite(CD_PIN, LOW);          // CD-Pin auf LOW, es werden Daten 
geschrieben
  digitalWrite(WRITE_PIN, LOW);       // Write-Pin auf LOW

  soft_delay();                       // Warten

  digitalWrite(WRITE_PIN, HIGH);      // Schreibpin auf HIGH
  digitalWrite(CE_PIN, HIGH);         // Chip-Enable-Pin auf HIGH
}


/****************************************************
//
// Schreibt ein Datenbyte auf Port D und inkrementiert den Adresszeiger
//
*****************************************************/
void GLCD_WriteDisplayData(uint8_t x)
{
  GLCD_WriteData(x);       // Schreibe ein Datenbyte auf Port D
  GLCD_WriteCommand(T6963_DATA_WRITE_AND_INCREMENT); // Befehl "Daten 
schreiben und Adresspointer erhoehen"
}


/***************************************************
//
// Schreibt einen Buchstaben (ASCII code) in den Displayspeicher
//
****************************************************/
void GLCD_WriteChar(uint8_t charCode)
{
  GLCD_WriteDisplayData(charCode - 32);
}

/****************************************************
//
// Schreibt einen String in den Displayspeicher
//
*****************************************************/
void GLCD_WriteString(char * string)
{
  while(*string) // Solange *string ungleich null
    {
      GLCD_WriteChar(*string++); // Character schreiben und gleichzeitig 
Zeiger erhoehen
    }
}

/************************************************
//
// Setzte den Adresszeiger im Displayspeicher
//
*************************************************/
void GLCD_SetAddressPointer(unsigned int address)
{
  GLCD_WriteData(address & 0xFF);  // Schreibe LSB
  GLCD_WriteData(address >> 8);    // Schreibe MSB
  GLCD_WriteCommand(T6963_SET_ADDRESS_POINTER); // Schreibe Befehl zum 
Setzen des Adresszeigers im Display-Speicher
}

/************************************************
//
// Setze Koordinaten fuer die Textausgabe
//
*************************************************/
void GLCD_TextGoTo(uint8_t x, uint8_t y)
{
  unsigned int address;
  address = GLCD_TEXT_HOME +  x + (GLCD_TEXT_AREA * y);  // Errechne die 
Adresse im Textspeicher
  GLCD_SetAddressPointer(address);                       // Setze 
Adresszeiger
}

/*****************************************
//
// Loesche Textspeicher
//
*****************************************/
void GLCD_ClearText(void)
{
  int i;
  GLCD_SetAddressPointer(GLCD_TEXT_HOME); // Setze Adresszeiger auf den 
Anfang des Textspeichers

//  for(i = 0; i < GLCD_TEXT_SIZE; i++)
  for(i = 0; i < 5120; i++) //5120 manuell ausprobiert
  {
    GLCD_WriteDisplayData(0x00); // Schreibe eine 00H mit Autoincrement
  }
}

/*********************************************************
//
// Loeschen des Character Generator Bereiches im Displayspeicher
//
**********************************************************/
void GLCD_ClearCG()
{
  unsigned int i;
  GLCD_SetAddressPointer(GLCD_EXTERNAL_CG_HOME);

  for(i = 0; i < 256 * 8; i++)
  {
    GLCD_WriteDisplayData(0x00);
  }
}

/*************************************************
//
// Grafikbereich des Displayspeichers loeschen
//
**************************************************/
void GLCD_ClearGraphic(void)
{
  unsigned int i;
  GLCD_SetAddressPointer(GLCD_GRAPHIC_HOME); // Adresszeiger auf den 
Anfangsbereich des Grafikbreiches setzen
  for(i = 0; i < GLCD_GRAPHIC_SIZE; i++)
  {
    GLCD_WriteDisplayData(0x00);
  }
}


/***********************************************************
//
// Setze Pixel an der Stelle x/y; Wenn color = 1 dann setzen, wenn Color 
= 0 dann loeschen
//
************************************************************/
void GLCD_SetPixel(uint8_t x, uint8_t y, uint8_t color)
{
  uint8_t tmp;
  unsigned int address;

  address = GLCD_GRAPHIC_HOME + (x / GLCD_FONT_WIDTH) + 
(GLCD_GRAPHIC_AREA * y);
  //        Beispiel x = 10, y = 20:
  //        address = 480 + (10/8) + (30 * 20) = 1081
  GLCD_SetAddressPointer(address);  // Setze Adresszeiger

  GLCD_WriteCommand(T6963_DATA_READ_AND_NONVARIABLE); // ???
  tmp = GLCD_ReadData();

  if(color)
    tmp |=  (1 <<  (GLCD_FONT_WIDTH - 1 - (x % GLCD_FONT_WIDTH)));
  else
    tmp &= ~(1 <<  (GLCD_FONT_WIDTH - 1 - (x % GLCD_FONT_WIDTH)));

  GLCD_WriteDisplayData(tmp);
}


/******************************
//
// Initialisierung
//
*******************************/
void GLCD_Initalize(void)
{
  GLCD_Reset();

  // Reihenfolge entnommen aus Datenblatt T6963C, S. 25
  GLCD_WriteCommand(T6963_MODE_SET | 0);

  GLCD_WriteData(GLCD_GRAPHIC_HOME & 0xFF);
  GLCD_WriteData(GLCD_GRAPHIC_HOME >> 8);
  GLCD_WriteCommand(T6963_SET_GRAPHIC_HOME_ADDRESS);

  GLCD_WriteData(GLCD_GRAPHIC_AREA);
  GLCD_WriteData(0x00);
  GLCD_WriteCommand(T6963_SET_GRAPHIC_AREA);

  GLCD_WriteData(GLCD_TEXT_HOME);
  GLCD_WriteData(GLCD_TEXT_HOME >> 8);
  GLCD_WriteCommand(T6963_SET_TEXT_HOME_ADDRESS);

  GLCD_WriteData(GLCD_TEXT_AREA);
  GLCD_WriteData(0x00);
  GLCD_WriteCommand(T6963_SET_TEXT_AREA);

  GLCD_WriteData(GLCD_OFFSET_REGISTER);
  GLCD_WriteData(0x00);
  GLCD_WriteCommand(T6963_SET_OFFSET_REGISTER);

  GLCD_WriteCommand(T6963_DISPLAY_MODE  | T6963_GRAPHIC_DISPLAY_ON   | 
T6963_TEXT_DISPLAY_ON );

}

void setup() {
  pinMode (13,OUTPUT);          // Einfache Blink-LED auf dem 
Arduino-Board
  pinMode (READ_PIN, OUTPUT);   // Lese-Pin RD, Aktiv-Low
  pinMode (WRITE_PIN, OUTPUT);  // Schreib-Pin, Aktiv-Low
  pinMode (CD_PIN, OUTPUT);     // Command/Data-Pin; wenn LOW, dann 
werden Daten gehandelt, bei HIGH Commands
  pinMode (RESET_PIN, OUTPUT);  // Reset-Pin, Aktiv-Low
  pinMode (CE_PIN, OUTPUT);     // Chip-Enable-Pin, Aktiv-Low

  DDRD = 0xff; //Port D als Ausgang
  GLCD_Initalize();  // Initialisiere das Display
}

void loop() {
  // Blink-LED auf Arduino-Board
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);

  if (flg == 0) {
    GLCD_ClearText();  // Textbereich loeschen
    GLCD_ClearCG();    // Character Generator Bereich loeschen
    GLCD_ClearGraphic(); // Grafikbereich loeschen
    GLCD_TextGoTo(4,0);  // Koordinaten fuer Textausgabe setzen
    GLCD_WriteString("Gvtfm Tbg"); // Schreibe Text auf Display; 
Reihenfolge ist kurios! Es sollte "Guten Tag" erscheinen;
                                   // Mit dieser Buchstabenkombination 
erscheint auch "Guten Tag"
//    for (int i = 10; i < 100; i++) GLCD_SetPixel(i,20,1);
    flg = 1;
  }
}

von holger (Gast)


Lesenswert?

Die Datenleitung D0 und D1 deines Displays haben einen
Kurzschluss zueinander.

von kubi (Gast)


Lesenswert?

Ich glaube eher Du hast D0 und D1 vertauscht.

von holger (Gast)


Lesenswert?

>Ich glaube eher Du hast D0 und D1 vertauscht.

Ja, ich denke DU hast recht;)

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.