I'm not sure if I have already posted this somewhere but anyway this is what I've used:
The WriteData and WriteCommand functions should show what is needed to write data and commands to the display.
Code:
#define DISPLAY_ON 0x3f //0011 1111
#define DISPLAY_OFF 0x3e //0011 1110
#define DISPLAY_STARTLINE 0xc0 //1100 0000
#define DISPLAY_PAGE_SET 0xb8 //1011 1000
#define DISPLAY_COLUMN_SET 0x40 //0100 0000
void cKS0108::WriteCommand(unsigned char Command, unsigned char CS)
{
Delay(delay);
SetPortVal(CONTROL, ENABLE_LO | CS | RS_LO, 1);
SetPortVal(DATA, Command, 1);
SetPortVal(CONTROL, ENABLE_HI | CS | RS_LO, 1);
Delay(delay);
SetPortVal(CONTROL, ENABLE_LO | CS | RS_LO, 1);
//SetPortVal(DATA, 0, 1);
}
void cKS0108::WriteData(const unsigned char Data[], unsigned int amount)
{
unsigned char cs;
unsigned int counter;
for (counter=0; counter < amount;counter++)
{
cs = CurrentColumn>63?CS2:CS1;
Delay(delay);
SetPortVal(CONTROL, ENABLE_LO | cs | RS_HI, 1);
SetPortVal(DATA, Data[counter], 1);
SetPortVal(CONTROL, ENABLE_HI | cs | RS_HI, 1);
Delay(delay);
SetPortVal(CONTROL, ENABLE_LO | cs | RS_HI, 1);
CurrentColumn++;
if (CurrentColumn > 127)
return;
}
}
void cKS0108::SetColumn(unsigned char y)
{
CurrentColumn = y;
if (y < 64)
{
WriteCommand(DISPLAY_COLUMN_SET | (y&63), CS1);
WriteCommand(DISPLAY_COLUMN_SET | 0, CS2);
} else
{
WriteCommand(DISPLAY_COLUMN_SET | 63, CS1);
WriteCommand(DISPLAY_COLUMN_SET | ((y-64)&63), CS2);
}
}
void cKS0108::SetPage(unsigned char x)
{
Delay(delay);
WriteCommand(DISPLAY_PAGE_SET | x, CS1);
WriteCommand(DISPLAY_PAGE_SET | x, CS2);
}
void cKS0108::SetStartLine(unsigned char line)
{
WriteCommand(DISPLAY_STARTLINE | (line & 63), CS1);
WriteCommand(DISPLAY_STARTLINE | (line & 63), CS2);
}
void cKS0108::InitLCD()
{
unsigned char value;
int x, a;
value = 0x0;
WriteCommand(DISPLAY_ON, CS1);
WriteCommand(DISPLAY_ON, CS1);
SetStartLine(0);
for (x=0;x < 8;x++)
{
SetPage(x);SetColumn(0);
for (a = 0 ;a < 128; a++)
WriteData(&value, 1);
}
}