extern prog_uchar E_font[128][16];
extern prog_uint16_t KSTable[2350] ;
extern prog_uchar table_cho[21];
extern prog_uchar table_joong[30];
extern prog_uchar table_jong[30];
extern prog_uchar bul_cho1[22];
extern prog_uchar bul_cho2[22];
extern prog_uchar bul_jong[22];
extern prog_uchar K_font[360][32] ;
void GLCD_Init()
{
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_CS1);
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_CS2);
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_RST);
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_RW);
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_RS);
SetBit(GLCD_CONTROL_PORT_DIR,GLCD_EA);
GLCD_DATA_PORT_DIR = 0xFF;
ClearBit(GLCD_CONTROL_PORT,GLCD_RST);
DelayUS(10);
SetBit(GLCD_CONTROL_PORT,GLCD_RST);
ClearBit(GLCD_CONTROL_PORT,GLCD_RW);
g_GLCD.pos.x = 0;
g_GLCD.pos.y = 0;
g_GLCD.ShowCursor = 0;
g_GLCD.posCursor.x = 0;
g_GLCD.posCursor.y = 0;
CLR_EA;
CLR_CS1;
CLR_CS2;
CLR_RS;
GLCD_Command(0x00,0x3F); // CS1, CS2 display ON
GLCD_Command(0x00,0xC0); // CS1, CS2 display position
DelayMS(1);
GLCD_String(0,0," ");
GLCD_String(1,0," ");
GLCD_String(2,0," ");
GLCD_String(3,0," ");
}
void GLCD_Command(BYTE byteSignal,BYTE byteCommand){
// E=0, DI = 0;
CLR_EA;
CLR_RS;
if(0x02 == (byteSignal&0x02))
{
SET_CS1;
}
else
{
CLR_CS1;
}
if(0x01 == (byteSignal&0x01))
{
SET_CS2;
}
else
{
CLR_CS2;
}
DelayUS(1);
GLCD_DATA_PORT = byteCommand;
SET_EA;
CLR_EA;
SET_CS1;
SET_CS2;
DelayUS(1);
}
// x,y 좌표를사용자가변경할수있다.
void GLCD_SetXY(BYTE x, BYTE y)
{
g_GLCD.pos.x = x;
g_GLCD.pos.y = y;
}
// 문자의세로길이는16bit 라서위/아래를나누어출력해야한다.
// 문자출력시위/아래
// x : x position
// y : y position
// row 0: upper
// 1: lower
void GLCD_SetXY_ROW(struct _POSITION_ pos,BYTE upperrow)
{
if(upperrow == 0) // 출력한문자의데이터가위쪽이면
GLCD_Command(0x00,0xB8 + pos.x*2);
else // 출력한문자의데이터가아래쪽이면
GLCD_Command(0x00,0xB8 + pos.x*2 + 1);
if(pos.y <= 7) // 좌측LCD 이면
GLCD_Command(0x01,0x40 + pos.y*8);
else // 우측LCD 이면
GLCD_Command(0x02,0x40 + (pos.y-8)*8);
}
void GLCD_WriteData(BYTE byteSignal,BYTE byteChar,BYTE bBlock){
if(1 == bBlock)
{
byteChar = ~byteChar;
}
CLR_EA;
SET_RS;
if(0x02 == (byteSignal&0x02))
{
SET_CS1;
}
else
{
CLR_CS1;
}
if(0x01 == (byteSignal&0x01))
{
SET_CS2;
}
else
{
CLR_CS2;
}
DelayUS(1);
GLCD_DATA_PORT = byteChar;
SET_EA;
CLR_EA;
SET_CS1;
SET_CS2;
DelayUS(1);
}
BYTE GLCD_ReadData(BYTE byteSignal)
{
BYTE byteChar;
CLR_EA;
SET_RS;
SetBit(GLCD_CONTROL_PORT,GLCD_RW);
GLCD_DATA_PORT_DIR = 0x00;
if(0x02 == (byteSignal&0x02))
{
SET_CS1;
}
else
{
CLR_CS1;
}
if(0x01 == (byteSignal&0x01))
{
SET_CS2;
}
else
{
CLR_CS2;
}
DelayUS(1);
SET_EA;
CLR_EA;
byteChar = GLCD_DATA_INPUT;
GLCD_DATA_PORT_DIR = 0xFF;
ClearBit(GLCD_CONTROL_PORT,GLCD_RW);
SET_CS1;
SET_CS2;
return byteChar;
}
// 8x16 크기의영문출력
void GLCD_English(BYTE Ecode,BYTE bBlock)
{
BYTE i, byteCS;
if(g_GLCD.pos.y <= 7) // 좌측LCD 선택
byteCS = 0x01;
else // 우측LCD 선택
byteCS = 0x02;
if(g_GLCD.ShowCursor==1)
{
GLCD_RemoveCursor();
}
// 먼저세로의크기16중상단8개만출력
GLCD_SetXY_ROW(g_GLCD.pos,0);
for(i = 0; i <= 7; i++)
{
GLCD_WriteData(byteCS, pgm_read_byte(&E_font[Ecode][i]),bBlock);
}
// 세로의크기16중하단8개만출력
GLCD_SetXY_ROW(g_GLCD.pos,1);
for(i = 8; i <= 15; i++)
{
if((g_GLCD.ShowCursor == 1))
{
// 커서를출력한다면
g_GLCD.posCursor = g_GLCD.pos;
GLCD_WriteData(byteCS,pgm_read_byte(&E_font[Ecode][i]) | 0x80,bBlock);
}
else
GLCD_WriteData(byteCS,pgm_read_byte(&E_font[Ecode][i]),bBlock);
}
g_GLCD.pos.y++;
if(g_GLCD.pos.y == 16)
{
g_GLCD.pos.y = 0;
if(++g_GLCD.pos.x >=4) g_GLCD.pos.x=0;
}
}
// 16x16 크기의한글출력
void GLCD_Korean(UINT16 Kcode,BYTE byteBlock)
{
BYTE i, byteCS;
BYTE cho_5bit, joong_5bit, jong_5bit;
BYTE cho_bul, joong_bul, jong_bul=0, jong_flag;
unsigned int character;
BYTE Korean_buffer[32]; // 임시버퍼
if(g_GLCD.pos.y == 15) // 마지막1칸이라면공백을출력하고다음으로.
GLCD_English(0x20,byteBlock);
if(g_GLCD.pos.y <= 7) // 좌측LCD 선택
byteCS = 0x01;
else // 우측LCD 선택
byteCS = 0x02;
// 일단초성/중성/종성을얻고
cho_5bit = table_cho[(Kcode >> 10) & 0x001F];
joong_5bit = table_joong[(Kcode >> 5) & 0x001F];
jong_5bit = table_jong[Kcode & 0x001F];
if(jong_5bit == 0) // 종성이없을경우
{
jong_flag = 0;
cho_bul = bul_cho1[joong_5bit];
if((cho_5bit == 1) || (cho_5bit == 16)) joong_bul = 0;
else joong_bul = 1;
}
else // 종성이있다면
{
jong_flag = 1;
cho_bul = bul_cho2[joong_5bit];
if((cho_5bit == 1) || (cho_5bit == 16)) joong_bul = 2;
else joong_bul = 3;
jong_bul = bul_jong[joong_5bit];
}
// 초성데이터값가져오기
character = (UINT16)cho_bul*20 + (UINT16)cho_5bit;
for(i = 0; i <= 31; i++)
Korean_buffer[i] = pgm_read_byte(&K_font[character][i]);
// 중성데이터가져와서합치기
character = (UINT16)8*20 + (UINT16)joong_bul*22 + (UINT16)joong_5bit;
for(i = 0; i <= 31; i++)
Korean_buffer[i] |= pgm_read_byte(&K_font[character][i]);
// 종성이있을경우합치기
if(jong_flag == 1)
{
character = (UINT16)8*20 + (UINT16)4*22 +(UINT16)jong_bul*28 + (UINT16)jong_5bit;
for(i = 0; i <= 31; i++)
Korean_buffer[i] |= pgm_read_byte(&K_font[character][i]);
}
// 반전추가예정
// if(TRUE == byteBlock){
// for(i = 0; i <= 31; i++)
// Korean_buffer[i] = ~Korean_buffer[i];
// }
// 16 x16 크기에서좌측상단출력
GLCD_SetXY_ROW(g_GLCD.pos,0); // 상단8 출력
for(i = 0; i <= 7; i++)
GLCD_WriteData(byteCS,Korean_buffer[i],byteBlock);
// 16 x16 크기에서좌측하단출력
GLCD_SetXY_ROW(g_GLCD.pos,1);
for(i = 16; i <= 23; i++)
{
if(g_GLCD.ShowCursor == 1)
GLCD_WriteData(byteCS,Korean_buffer[i] | 0x80,byteBlock);
else
GLCD_WriteData(byteCS,Korean_buffer[i],byteBlock);
}
g_GLCD.pos.y++;
// 16 x16 크기에서우측상단출력
GLCD_SetXY_ROW(g_GLCD.pos,0); // display upper right row
for(i = 8; i <= 15; i++)
GLCD_WriteData(byteCS,Korean_buffer[i],byteBlock);
// 16 x16 크기에서우측하단출력
GLCD_SetXY_ROW(g_GLCD.pos,1);
for(i = 24; i <= 31; i++)
{
if(g_GLCD.ShowCursor == 1)
GLCD_WriteData(byteCS,Korean_buffer[i] | 0x80,byteBlock);
else
GLCD_WriteData(byteCS,Korean_buffer[i],byteBlock);
}
g_GLCD.pos.y++;
if(g_GLCD.pos.y == 16)
{
g_GLCD.pos.y = 0;
g_GLCD.pos.x++;
}
}
void GLCD_String(BYTE x,BYTE y,BYTE const *string)
{
BYTE character1;
unsigned int character2;
g_GLCD.pos.x = x;
g_GLCD.pos.y = y;
while(*string != '\0')
{
character1 = *string;
string++;
if(character1 < 0x80)
GLCD_English(character1,FALSE);
else
{
character2 = 256*character1 + (*string & 0xFF);
string++;
GLCD_Korean(character2,0);
}
}
}
void GLCD_ShowCursor(UINT8 _show)
{
g_GLCD.ShowCursor = _show;
}
void GLCD_RemoveCursor()
{
BYTE byteData[8];
BYTE byteCS=0;
if(g_GLCD.ShowCursor == 0)
return;
GLCD_SetXY_ROW(g_GLCD.posCursor,1);
if(g_GLCD.posCursor.y <= 7) // 좌측화면이면
byteCS = 0x01;
else
byteCS = 0x02;
GLCD_ReadData(byteCS);
byteData[0] = GLCD_ReadData(byteCS);
if(byteData[0] & 0x80 )
{
// 커서가black 이면
byteData[0] &= 0x7F;
byteData[1] = GLCD_ReadData(byteCS) & 0x7F;
byteData[2] = GLCD_ReadData(byteCS) & 0x7F;
byteData[3] = GLCD_ReadData(byteCS) & 0x7F;
byteData[4] = GLCD_ReadData(byteCS) & 0x7F;
byteData[5] = GLCD_ReadData(byteCS) & 0x7F;
byteData[6] = GLCD_ReadData(byteCS) & 0x7F;
byteData[7] = GLCD_ReadData(byteCS) & 0x7F; }
else
{
// 커거서white이면(주로문자의블럭지정에서사용)
byteData[0] |= 0x80;
byteData[1] = GLCD_ReadData(byteCS) | 0x80;
byteData[2] = GLCD_ReadData(byteCS) | 0x80;;
byteData[3] = GLCD_ReadData(byteCS) | 0x80;
byteData[4] = GLCD_ReadData(byteCS) | 0x80;
byteData[5] = GLCD_ReadData(byteCS) | 0x80;;
byteData[6] = GLCD_ReadData(byteCS) | 0x80;
byteData[7] = GLCD_ReadData(byteCS) | 0x80;
}
GLCD_SetXY_ROW(g_GLCD.posCursor,1);
GLCD_WriteData(byteCS,byteData[0],0);
GLCD_WriteData(byteCS,byteData[1],0);
GLCD_WriteData(byteCS,byteData[2],0);
GLCD_WriteData(byteCS,byteData[3],0);
GLCD_WriteData(byteCS,byteData[4],0);
GLCD_WriteData(byteCS,byteData[5],0);
GLCD_WriteData(byteCS,byteData[6],0);
GLCD_WriteData(byteCS,byteData[7],0);
} |