그래픽 LCD 에 커서 있는 영문을 출력 하는 예제입니다.
원문은 http://avr128.com 에 있습니다.
주요 코드
wat128.h 일부
#define GLCD_CS1 0 // 좌측LCD 선택 #define GLCD_CS2 1 // 우측LCD 선택 #define GLCD_RST 2 // RESET #define GLCD_RW 3 // Read/Write #define GLCD_RS 4 // Command/Data #define GLCD_EA 5 // Enable
#define SET_EA SetBit(GLCD_CONTROL_PORT,GLCD_EA) #define CLR_EA ClearBit(GLCD_CONTROL_PORT,GLCD_EA)
#define SET_CS1 SetBit(GLCD_CONTROL_PORT,GLCD_CS1); #define CLR_CS1 ClearBit(GLCD_CONTROL_PORT,GLCD_CS1); #define SET_CS2 SetBit(GLCD_CONTROL_PORT,GLCD_CS2); #define CLR_CS2 ClearBit(GLCD_CONTROL_PORT,GLCD_CS2);
#define SET_RS SetBit(GLCD_CONTROL_PORT,GLCD_RS); #define CLR_RS ClearBit(GLCD_CONTROL_PORT,GLCD_RS);
#define GLCD_DATA_PORT PORTA // DATA 레지스터 #define GLCD_DATA_PORT_DIR DDRA // DATA 방향레지스터 #define GLCD_DATA_INPUT PINA // DATA 입력레지스터
#define GLCD_CONTROL_PORT PORTB // CONTROL 레지스터 #define GLCD_CONTROL_PORT_DIR DDRB // CONTROL 방향레지스터
struct _POSITION_ { UINT8 x; // X 좌표 UINT8 y; // Y 좌표 };
// GLCD 관련구조체 struct _GLCD_INFO_ { struct _POSITION_ pos; // 현재출력중인좌표 struct _POSITION_ posCursor; // 커서위치 UINT8 ShowCursor; // 커서를보여줄것인지/아닌지 };
struct _GLCD_INFO_ g_GLCD; // GLCD 구조체
void GLCD_Init(); // GLCD 초기화 void GLCD_Clear(); // GLCD 화면초기화 void GLCD_Command(BYTE byteSignal,BYTE byteCommand); // COMMAND void GLCD_SetXY(BYTE x, BYTE y); // 좌표이동 void GLCD_SetXY_ROW(struct _POSITION_ pos,BYTE row); // DATA 관련좌표이동
void GLCD_WriteData(BYTE byteSignal,BYTE byteChar,BYTE bBlock); // 데이터쓰기 BYTE GLCD_ReadData(BYTE byteSignal); // 데이터읽기 void GLCD_English(BYTE Ecode,BYTE bBlock); // 영문출력 void GLCD_Korean(UINT16 Kcode,BYTE byteBlock) ; // 한글출력 void GLCD_String(BYTE x,BYTE y,BYTE const *string); // 문자열출력 void GLCD_ShowCursor(UINT8 _show); // 커서를show/hide 한다. void GLCD_RemoveCursor(); // 현재커서를안보이게한다.(제거한다) |
wat128.c 일부
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);
} |
main.c
/*
필요한보드 1. WAT-AVR128 (모듈) 2. WAT-AVR128 EXT (확장보드) 3. WAT-GLCD (모노그래픽LCD)
기능 그래픽LCD 에커서있는영문을표시한다.
http://avr128.com
2011-08-08 : 주석추가
*/
#include <avr/io.h> #include "WAT128.h"
#ifdef _USE_GLCD_ #include "gfont.h" #endif
int main(){
int i=0;
GLCD_Init(); GLCD_ShowCursor(1); // 커서를 보이게 하자.
GLCD_SetXY(0,0); GLCD_String(0,0,"AVR128.com ");
while(1) { // 약200ms 마다커서가있는'E' 출력 GLCD_English('E',0); DelayMS(200); } } |
'AVR키트' 카테고리의 다른 글
WAT-AVR128, EX_01_01, 순차적으로 LED ON 예제 (0) | 2011.08.16 |
---|---|
그래픽 LCD 도형(원, 사각형, 라인) 그리기 (0) | 2011.08.10 |
WAT-AVR128 예제 (소스 제공) (0) | 2011.07.20 |
WAT-AVR128_EXT 보드 (0) | 2011.07.20 |
WAT-AVR128 모듈 (0) | 2011.07.20 |