그래픽 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);

    }

}

 

Posted by WhiteAT

댓글을 달아 주세요