PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : KS0108 / Pollin 128x64 LCD: Probleme [gelöst]



Jaecko
30.08.2008, 20:29
Moin.

Bin gerade dabei, einige Routinen in Eigenarbeit für ein LCD (128x64, Klassiker von Pollin mit KS0108-kompatiblem Controller) zu erstellen.
Es gibt zwar schon ein paar fertige Routinen, nur möcht ich das ganze selbst von Grund auf erstellen, um genau zu wissen, was ich da eigentlich mach.

Im Anhang ist der bisherige Stand.
Das Testprogramm in der main.c soll vom Prinzip her das gleiche machen, wie die Funktion TG12864B_Fill(), nur dass eben jedes Pixel gezielt angesprochen werden kann.
Problem ist nun hier, dass die Fläche nach dem Test nicht durchgehend weiss ist, sondern am linken Rand jedes "Treibers" dieses Muster hier aufweist:

http://cihome.kilu.de/_forendaten/lcd01.jpg

Wobei dieses "Muster" erst während des Aufbaus entsteht; d.h. die erste Zeile wird durchgehend gesetzt. Sobald die 2. Zeile beginnt, wird das erste Pixel wieder gelöscht. Beginnt die 3. Zeile, rutscht das gelöschte Pixel aus der ersten Zeile eins weiter ... usw, bis am Ende eben dieses Muster entsteht.
Der Fehler müsste entweder irgendwo in ~_SetPixel() oder ~_Goto() sein. Nur seh ich ihn nicht. Evtl jemand von euch?

Hier die Codes:
main.c


int main (void)
{
ui8_t x=0;
ui8_t y=0;

TG12864B_Init();
for (y = 0; y < 64 ; y++)
for (x = 0; x < 128 ; x++)
{
{
TG12864B_SetPixel(x,y,1);
// _delay_ms(100);
}
}
while(1)
{

}
return(0);
}


tg12864b.c


#include "tg12864b.h"

stc_DisplayPosition DPos;
volatile ui8_t readdata = 0;


static inline void _delay4Cycles(ui16_t __count)
{
if (__count == 0)
{
__asm__ __volatile__("rjmp 1f\n 1:");
}
else
{
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__count)
: "0" (__count)
);
}
}

#define delay(us) _delay4Cycles(((F_CPU / 4000)*us)/1000)

void TG12864B_Init(void)
{
// Prepare Timer 0, PWM Channel B
//TCCR0A = (1 << WGM00) | (1 << COM0B1);
//TCCR0B = (1 << CS00) | (1 << CS01);
//OCR0B = 0;

// Set Ports & Pins as Output
TG12864B_DATA_PORT = 0x00;
TG12864B_DATA_DDR = 0xFF;
// TG12864B_LIGHT_DDR |= (1 << TG12864B_LIGHT_PIN);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
TG12864B_EN_DDR |= (1 << TG12864B_EN_PIN);
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN);
TG12864B_RW_DDR |= (1 << TG12864B_RW_PIN);
TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN);
TG12864B_DI_DDR |= (1 << TG12864B_DI_PIN);
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);
TG12864B_CS1_DDR |= (1 << TG12864B_CS1_PIN);
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);
TG12864B_CS2_DDR |= (1 << TG12864B_CS2_PIN);
TG12864B_RST_PORT &=~ (1 << TG12864B_RST_PIN);
TG12864B_RST_DDR |= (1 << TG12864B_RST_PIN);

_delay_ms(10);
TG12864B_RST_PORT |= (1 << TG12864B_RST_PIN);
_delay_ms(10);


// Send commands for init
DPos.x = 0;
DPos.y = 0;
DPos.page = 0;
DPos.addr = 0;
DPos.driver = 0;
DPos.rel_y = 0;
TG12864B_SendCmd(TG12864B_ON, 1); // Power on both drivers
TG12864B_SendCmd(TG12864B_ON, 2); // Power on both drivers
TG12864B_SendCmd(TG12864B_DISP_START, 1); // Display start line = 0
TG12864B_SendCmd(TG12864B_DISP_START, 2); // Display start line = 0
TG12864B_Fill(0x00);
}

void TG12864B_SendCmd(ui8_t cmd, ui8_t driver)
{
switch(driver)
{
case 1:
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
break;
case 2:
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
break;
case 3:
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
break;
default:
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
break;
}
TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN); // D/I = 0 = Instruction
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Port = Output
TG12864B_DATA_PORT = cmd; // Set data
TG12864B_EN_Pulse(); // Enable Clock
TG12864B_DATA_PORT = 0x00; // Reset data port
}

void TG12864B_EN_Pulse(void)
{
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
delay(4);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
delay(4);
}

void TG12864B_Fill(ui8_t pattern)
{
ui8_t add;
ui8_t page;
for (page = 0; page < 8 ; page++)
{
for (add = 0 ; add < 64 ; add++)
{
TG12864B_SendCmd(TG12864B_SET_ADD | add, 3);
TG12864B_SendCmd(TG12864B_SET_PAGE | page, 3);
TG12864B_SendDataRaw(pattern,3);
}
}
}

void TG12864B_SendDataRaw(ui8_t data, ui8_t driver)
{
switch(driver)
{
case 1:
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
break;
case 2:
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
break;
case 3:
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
break;
default:
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
break;
}
TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Port = Output
TG12864B_DATA_PORT = data; // Set data
TG12864B_EN_Pulse(); // Enable Clock
TG12864B_DATA_PORT = 0x00; // Reset data port

}

void TG12864B_Goto(ui8_t x, ui8_t y)
{
DPos.x = x;
DPos.y = y;

// Check: coordinates are valid
if (x > 127) { x = 127; }
if (y > 63) { y = 63; }

// Calculate Coordinates:
// Get driver nr. & relative x coordinate (= address)
if ( x >= 128)
{
return;
}

if ( x < 64 )
{
DPos.driver = 1;
DPos.addr = x;
}

if (( x >= 64 ) && ( x < 128 ))
{
DPos.driver = 2;
DPos.addr = x - 64;
}

// Get Page:
/*
if (y < 8) {DPos.page = 0;}
if ((y >= 8) && (y < 16)) {DPos.page = 1;}
if ((y >= 16) && (y < 24)) {DPos.page = 2;}
if ((y >= 24) && (y < 32)) {DPos.page = 3;}
if ((y >= 32) && (y < 40)) {DPos.page = 4;}
if ((y >= 40) && (y < 48)) {DPos.page = 5;}
if ((y >= 48) && (y < 56)) {DPos.page = 6;}
if ((y >= 56) && (y < 64)) {DPos.page = 7;}
*/
DPos.page = floor(y / 8);
DPos.rel_y = (y-DPos.page*8);
//DPos.rel_y = y & 8;
}

ui8_t TG12864B_ReadData(void)
{
ui8_t data;
TG12864B_DATA_PORT = 0x00; // Data = 0
TG12864B_DATA_DDR = 0x00; // Data = Input

if (DPos.driver == 1)
{
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
}
if (DPos.driver == 2)
{
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
}

TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT |= (1 << TG12864B_RW_PIN); // R/W = 1 = Read

TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
delay(10);
data = TG12864B_DATA_INPUT;
delay(10);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
delay(10);
TG12864B_DATA_DDR = 0xFF; // Data = Output
return (data);
}

void TG12864B_SetPixel(ui8_t x, ui8_t y, ui8_t value)
{
TG12864B_Goto(x, y);
TG12864B_SendCmd(TG12864B_SET_ADD | DPos.addr, DPos.driver);
TG12864B_SendCmd(TG12864B_SET_PAGE | DPos.page, DPos.driver);
readdata = TG12864B_ReadData();
if (value == 0)
{
readdata &=~ (1 << DPos.rel_y);
}
else
{
readdata |= (1 << DPos.rel_y);
}
TG12864B_SendCmd(TG12864B_SET_ADD | DPos.addr, DPos.driver);
TG12864B_SendCmd(TG12864B_SET_PAGE | DPos.page, DPos.driver);
TG12864B_SendDataRaw(readdata, DPos.driver) ;

}


tg12864b.h


#ifndef _TG12864B_H_
#define _TG12864B_H_

#include <math.h>
#include <avr/io.h>
#include <util/delay.h>
#include "glob_defs.h"
#include "glob_type.h"

#define TG12864B_DATA_PORT PORTA
#define TG12864B_DATA_DDR DDRA
#define TG12864B_DATA_INPUT PINA

#define TG12864B_EN_PORT PORTD
#define TG12864B_EN_DDR DDRD
#define TG12864B_EN_PIN 4

#define TG12864B_RW_PORT PORTD
#define TG12864B_RW_DDR DDRD
#define TG12864B_RW_PIN 5

#define TG12864B_DI_PORT PORTD
#define TG12864B_DI_DDR DDRD
#define TG12864B_DI_PIN 6

#define TG12864B_CS1_PORT PORTB
#define TG12864B_CS1_DDR DDRB
#define TG12864B_CS1_PIN 2

#define TG12864B_CS2_PORT PORTB
#define TG12864B_CS2_DDR DDRB
#define TG12864B_CS2_PIN 3

#define TG12864B_RST_PORT PORTD
#define TG12864B_RST_DDR DDRD
#define TG12864B_RST_PIN 3

// Commands
#define TG12864B_ON 0x3F
#define TG12864B_OFF 0x3E
#define TG12864B_SET_ADD 0x40
#define TG12864B_SET_PAGE 0xB8
#define TG12864B_DISP_START 0xC0
#define INCREMENT_X 0
#define NO_INCREMENT_X 1



void TG12864B_Init(void);
void TG12864B_SendCmd(ui8_t cmd, ui8_t driver);
void TG12864B_SendDataRaw(ui8_t data, ui8_t driver);
void TG12864B_EN_Pulse(void);
void TG12864B_Fill(ui8_t pattern);
void TG12864B_Goto(ui8_t x, ui8_t y);
ui8_t TG12864B_ReadData(void);
void TG12864B_SetPixel(ui8_t x, ui8_t y, ui8_t value);


typedef struct {
ui8_t x;
ui8_t y;
ui8_t driver;
ui8_t addr;
ui8_t page;
ui8_t rel_y;
} stc_DisplayPosition;


#endif


mfG

linux_80
31.08.2008, 11:22
Hallo,

evtl. passt die Berechnung bei TG12864B_Goto nicht ganz, probier einfach mal einzelne Pixel zu setzen, und zähl dann aus ob die an der richtigen Stelle gelandet sind.
Evtl. macht floor nicht ganz das was es soll, das sollte man aber auch ganz weglassen können, da nur Integers verwendet werden.

Jaecko
31.08.2008, 12:46
Also wenn einzelne Pixel gesetzt werden sollen, dann gehts schon so halb; nur wenn dann Pixel gesetzt werden, die in der gleichen "Page", aber untereinander liegen, dann verschwinden die darüber bzw. "togglen".

Hab von diesem Phänomen jetzt auch mal ein Video, die Pixel werden langsam zeilenweise gezeichnet, entsprechend der beiden for-Schleifen in der main.c; dort sieht man deutlich, wie dieses Muster entsteht.

http://cihome.kilu.de/_forendaten/lcd01.avi
(DivX 6.8, ca. 1,7MB, 22 sec, no Audio)

Das mit dem floor war so geplant, dass z.B. auch 7/8 (=0,875) noch 0 ergibt und nicht auf 1 aufgerundet wird, wo ich mir nicht sicher bin, ob "7/8" allein das auch ergibt. In der Sache bin ich immer etwas vorsichtiger, da dort jedes Programm was anderes macht. Die einen runden, die andern schneidens einfach ab.


EDIT: Nachtrag:
Habs gerade so versucht, dass ich den Displayinhalt im RAM des Controllers zwischenspeichere und dort lese, was bereits am Display steht.
Dort verschwindet der Effekt nun. Bringt zwar noch den weiteren Vorteil, dass das Pixel setzen nochmal ne Stufe schneller wurde, aber der erhebliche Nachteil ist, dass z.B. beim ATMega32 jetzt etwa 63% vom RAM nur für das Display draufgehen... schon etwas viel, naja aber bis es anders geht, lass ichs mal so.

Jaecko
15.09.2008, 18:10
So ich nochmal...
nachdem mir nun langsam der RAM ausgeht und diese Methode nun doch einige Probleme aufwirft, möcht ich doch nochmal die anderen Routinen verwenden.

Hab diese dann nochmal komplett neu aufgebaut, in der Hoffnung, dass der Fehler verschwindet. Aber wie damals auch: das Problem bleibt.

Wo der Fehler herkommt, weiss ich immer noch nicht. Nach bisherigen Erkenntnissen gibt es beim Auslesen des Displayinhalts Probleme, d.h. es wird beim Zeilenwechsel ein falscher Wert ausgelesen.

Evtl ist hier ja jemand, der so ein Display hat und den Code mal testen kann...

Hier mal die neuesten Codes:

tg12864b.c


#include "tg12864b.h"

// This file contains routines for the Pollin 128x64 GLCD.
// All GLCD-Functions transfer data directly to the display RAM after
// reading back the current display contents.


// Enable this for display color inversion (to be done)
// #define INVERTED

volatile stc_DisplayPosition DPos;

ui8_t state_rw;
ui8_t state_di;
ui8_t state_cs1;
ui8_t state_cs2;

static inline void _delay4Cycles(ui16_t __count)
{
if (__count == 0)
{
__asm__ __volatile__("rjmp 1f\n 1:");
}
else
{
__asm__ __volatile__ (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (__count)
: "0" (__count)
);
}
}

#define delay(us) _delay4Cycles(((F_CPU / 4000)*us)/1000)

void GLCD_Init(void)
{
// Set Ports & Pins as Output
TG12864B_DATA_PORT = 0x00;
TG12864B_DATA_DDR = 0xFF;

TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
TG12864B_EN_DDR |= (1 << TG12864B_EN_PIN);
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN);
TG12864B_RW_DDR |= (1 << TG12864B_RW_PIN);
TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN);
TG12864B_DI_DDR |= (1 << TG12864B_DI_PIN);
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN);
TG12864B_CS1_DDR |= (1 << TG12864B_CS1_PIN);
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN);
TG12864B_CS2_DDR |= (1 << TG12864B_CS2_PIN);
TG12864B_RST_PORT &=~ (1 << TG12864B_RST_PIN);
TG12864B_RST_DDR |= (1 << TG12864B_RST_PIN);
_delay_ms(10);
TG12864B_RST_PORT |= (1 << TG12864B_RST_PIN);
_delay_ms(10);

// Send commands for init
GLCD_WriteCommand(TG12864B_ON, DRIVER1); // Power on both drivers
GLCD_WriteCommand(TG12864B_ON, DRIVER2); // Power on both drivers
GLCD_WriteCommand(TG12864B_DISP_START, DRIVER1); // Display start line = 0
GLCD_WriteCommand(TG12864B_DISP_START, DRIVER2); // Display start line = 0
}

ui8_t GLCD_ReadCell(ui8_t x, ui8_t page)
{
volatile ui8_t driver;
volatile ui8_t address;
volatile ui8_t data = 0;
volatile ui8_t i;

// select driver
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}

// set position
GLCD_WriteCommand(TG12864B_SET_PAGE | page, driver);
GLCD_WriteCommand(TG12864B_SET_ADD | address, driver); // set x address on active chip

if (driver == DRIVER1)
{
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
}
else
{
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
}


// read cell
TG12864B_DATA_DDR = 0x00; // Data port = Input
TG12864B_DATA_PORT = 0x00; // Reset data port
TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT |= (1 << TG12864B_RW_PIN); // R/W = 1 = Read

TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile("nop\n\t""nop\n\t""nop\n\t"::);
data = TG12864B_DATA_INPUT;

TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
for(i = 0 ; i < 5 ; i++);

TG12864B_DATA_DDR = 0xFF; // Data port = output

return (data);
}

void GLCD_WriteCell(ui8_t x, ui8_t page, ui8_t data)
{
ui8_t driver;
ui8_t address;

// calc coordinates
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}

// set position
GLCD_WriteCommand(TG12864B_SET_ADD | address, driver); // set x address on active driver
GLCD_WriteCommand(TG12864B_SET_PAGE | page, driver); // set page on active driver

if (driver == DRIVER1)
{
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
}
else
{
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
}

// write cell
TG12864B_DI_PORT |= (1 << TG12864B_DI_PIN); // D/I = 1 = Data
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Data port = Output
TG12864B_DATA_PORT = data;
GLCD_Enable();

}


void GLCD_WriteCommand(ui8_t cmd, ui8_t driver)
{
switch(driver)
{
case DRIVER1:
TG12864B_CS2_PORT &=~ (1 << TG12864B_CS2_PIN); // Driver 2 Off
TG12864B_CS1_PORT |= (1 << TG12864B_CS1_PIN); // Driver 1 On
break;
case DRIVER2:
TG12864B_CS1_PORT &=~ (1 << TG12864B_CS1_PIN); // Driver 1 Off
TG12864B_CS2_PORT |= (1 << TG12864B_CS2_PIN); // Driver 2 On
break;
}

TG12864B_DI_PORT &=~ (1 << TG12864B_DI_PIN); // D/I = 0 = Instruction
TG12864B_RW_PORT &=~ (1 << TG12864B_RW_PIN); // R/W = 0 = Write
TG12864B_DATA_DDR = 0xFF; // Data port = Output
TG12864B_DATA_PORT = cmd;
GLCD_Enable();
}

void GLCD_Enable(void)
{
volatile ui8_t i;
TG12864B_EN_PORT |= (1 << TG12864B_EN_PIN);
asm volatile(
"nop\n\t"
"nop\n\t"
"nop\n\t"
::);
TG12864B_EN_PORT &=~ (1 << TG12864B_EN_PIN);
for(i = 0 ; i < 8 ; i++);
}

void GLCD_SetPixel(ui8_t x, ui8_t y, ui8_t color)
{
ui8_t driver; // which driver controls the selected Pixel?
ui8_t address; // address on the selected driver
ui8_t page; // page, which contains the pixel
ui8_t rel_y; // relative y coordinate in page
ui8_t celldata;

ui8_t dbgbefore;
ui8_t dbgafter;
ui8_t dbgchange;

// calculate address + driver
if (x < 64)
{
address = x;
driver = DRIVER1;
}
else
{
address = x - 64;
driver = DRIVER2;
}

// calculate page:
//page = floor(y / 8);
page = y / 8;
rel_y = (y - (page * 8));

// Read current cell
celldata = GLCD_ReadCell(x, page);
dbgbefore = celldata;

// set or clear pixel
if (color == 0)
{
celldata &=~ (1 << rel_y);
}
else
{
celldata |= (1 << rel_y);
}
dbgchange = (1 << rel_y);

dbgafter = celldata;

// Write cell back
GLCD_WriteCell(x, page, celldata);

/*
if (1==0)//x < 8)
{
sprintf(dbgtext, "Before: 0x%02X Change: 0x%02X After: 0x%02X", dbgbefore, dbgchange, dbgafter);
DBG_Print(dbgtext);
_delay_ms(1000);
}
*/

}



tg12864b.h


#ifndef _TG12864B_H_
#define _TG12864B_H_

#include <math.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <string.h>
#include <stdio.h>
#include "glob_defs.h"
#include "glob_type.h"

#define ELEM_BRIGHTNESS 1
#define ELEM_AUTOOFF 2
#define ELEM_AUTOOFFACT 3

#define TG12864B_DATA_PORT PORTK
#define TG12864B_DATA_DDR DDRK
#define TG12864B_DATA_INPUT PINK

#define TG12864B_EN_PORT PORTF
#define TG12864B_EN_DDR DDRF
#define TG12864B_EN_PIN 7

#define TG12864B_RW_PORT PORTF
#define TG12864B_RW_DDR DDRF
#define TG12864B_RW_PIN 6

#define TG12864B_DI_PORT PORTF
#define TG12864B_DI_DDR DDRF
#define TG12864B_DI_PIN 5

#define TG12864B_CS1_PORT PORTJ
#define TG12864B_CS1_DDR DDRJ
#define TG12864B_CS1_PIN 7

#define TG12864B_CS2_PORT PORTA
#define TG12864B_CS2_DDR DDRA
#define TG12864B_CS2_PIN 0

#define TG12864B_RST_PORT PORTA
#define TG12864B_RST_DDR DDRA
#define TG12864B_RST_PIN 1

// Commands
#define TG12864B_ON 0x3F
#define TG12864B_OFF 0x3E
#define TG12864B_SET_ADD 0x40
#define TG12864B_SET_PAGE 0xB8
#define TG12864B_DISP_START 0xC0
#define INCREMENT_X 0
#define NO_INCREMENT_X 1
#define DRIVER1 0
#define DRIVER2 1

#define ICON_ARROWLEFT 130

// New functions:
void GLCD_Init(void);
void GLCD_WriteCommand(ui8_t cmd, ui8_t driver);
ui8_t GLCD_ReadCell(ui8_t x, ui8_t page);
void GLCD_WriteCell(ui8_t x, ui8_t page, ui8_t data);
void GLCD_Enable(void);
void GLCD_SetPixel(ui8_t x, ui8_t y, ui8_t color);

typedef struct {
ui8_t x;
ui8_t y;
ui8_t driver;
ui8_t addr;
ui8_t page;
ui8_t rel_y;
} stc_DisplayPosition;

typedef struct{
ui8_t data[7];
} stc_font5x7;

#endif



Testprorgamm in der main.c:


int main (void)
{
ui8_t x;
ui8_t y;

while(1)
{
// Test area for GLCD-Commands [START]

GLCD_Init();

for (y = 0 ; y < 8 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Clears whole display
GLCD_WriteCell(x,y , 0x00);
}
}


while(1)
{

for (y = 0 ; y < 64 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Set Display white
GLCD_SetPixel(x, y, 1);
}
}
for (y = 0 ; y < 64 ; y++)
{
for (x = 0 ; x < 128 ; x++)
{
// Set Display blue
GLCD_SetPixel(x, y, 0);
}
}
}
while(1);
// Test area for GLCD-Commands [END]
}

Jaecko
17.09.2008, 22:07
Und zum dritten:
Habs mittlerweile geschafft, den Fehler auszubügeln bzw. zu umgehen.
Der "Trick" an der Sache ist einfach der, das Display 2x auszulesen und den ersten (falschen) Wert zu verwerfen; Sprich, dem eigentlichen Read ein Dummy Read voranstellen. Dann gehts.