PC에서 받은 데이터를 CLCD에 출력하는 예제입니다.

 

 

 

<Character LCD 초기화>

 

 

 

 

 

 

< PC로부터 수신된 데이터 출력 >

 

 

 

 

 

< PC프로그램 화면 >

http://avr128.com/35 에 있는 시리얼 통신 프로그램을 사용했습니다.

 

 

 

윈도우에 기본적으로 제공되는 하이퍼터미널 프로그램을 사용해도 됩니다.^^

 

 

 

 

원문은 http://avr128.com 에 있습니다.

 

 

 

 

 

 

 

주요 코드

 

main.c 일부

/*

    EX_09_02.c

 

    PC에서USART0 로받은데이터를LCD에출력

    AVRStudio 4.18

    2011-08-16

 

    http://avr128.com

 

*/

 

#include <avr/io.h>

#include "WAT128.h"

 

int main()

{

    INT16S iRxData;

 

    OpenSCI0(57600);    // USART 0 열기

 

    CLCD_Init();        // LCD 초기화

 

    while(1)

    {

        iRxData=GetByte0();

        if( 0<= iRxData && iRxData<=255 ){

            

            // CLCD 에출력

            CLCD_PutChar(iRxData);

            PutChar0(iRxData); // echo 보내기

        }

    }

}

 

 

 

 

 

 

전체 소스

 


 

Posted by WhiteAT
,

 

 

PORTA에 연결된 8개의 LED 를 순차적으로ON 하는 예제입니다. 

 

D0: ●○○○○○○○

D1: ○●○○○○○○

D2: ○○●○○○○○

D3: ○○○●○○○○

D4: ○○○○●○○○

D5: ○○○○○●○○

D6: ○○○○○○●○

D7: ○○○○○○○●

PORTA의 0 ~ 7 포트까지 LED 8개가 연결되어 있고 LED에 불이 들어오게 하려면 해당되는 포트에 '0'을 출력하면 됩니다. D0(PORTA.0에 연결된 LED)부터 D7까지 차례대로 일정시간 ON된 후 OFF 되게 만들어 보겠습니다.

단 마지막 LED 가 ON/OFF 된 후에는 다시 처음으로 되돌아가서 무한 반복해야 합니다.

 

 

 

PORTA 에 대한 실험을 해보겠습니다. 실험에 사용할 회로와 WAT보드의 연결 방법은 아래와 같습니다.

 

 

 

 

 

 

 

 

 

< WAT-AVR128_EXT 보드와 WAT-IO&ADC 보드를 연결 중 >

 

 

 

 

 

< WAT-AVR128_EXT 보드와 WAT-IO&ADC 보드 연결 완료 >

 

 

 






 

 

원문은 http://avr128.com 에 있습니다.

 

 

 

 

 

 

주요 코드

 

main.c 일부

/*

    EX_01_01.c

 

    LED 순차적으로ON 하기

    AVRStudio 4.18

    2011-08-15

 

    http://avr128.com

 

*/

 

#include <avr/io.h>

 

// 일정시간딜레이

void Delay()

{

    register unsigned long i;

    for(i = 0; i < 300000; i++)

    {

        asm volatile(" PUSH R0 ");

        asm volatile(" POP R0 ");

        asm volatile(" PUSH R0 ");

        asm volatile(" POP R0 ");

        asm volatile(" PUSH R0 ");

        asm volatile(" POP R0 ");

        asm volatile(" PUSH R0 ");

        asm volatile(" POP R0 ");

        asm volatile(" PUSH R0 ");

        asm volatile(" POP R0 ");    

    }

}

 

int main()

{

    DDRA = 0xFF; // ALL OUTPUT

    PORTA = 0xFE;    // PORTA.0 LED ON

 

    while(1)

    {

        Delay();

 

        if(PORTA == 0x7F)    // 마지막LED 가ON 되었다면.

        {

            // 처음LED ON 되게

            PORTA = 0xFE;    // PORTA.0 LED ON

        }

        else                // 그렇지않다면

        {

            PORTA <<= 1;    // 한칸이동한후

            PORTA |= 1;        // 마지막LED 는OFF 되게

        }

    }

}

 

 

 

 

 

 

전체 소스

 

EX_01_01.zip

 

Posted by WhiteAT
,

 

그래픽 LCD 에 영문, 원, 사각형 선(라인)을 출력 하는 예제입니다.

 

 

 

 

 

 

원문은 http://avr128.com 에 있습니다.

 

 

 

 

주요 코드

 

main.c 일부

/*

    

필요한보드

    1. WAT-AVR128 (모듈)

    2. WAT-AVR128 EXT (확장보드)

    3. WAT-GLCD (모노그래픽LCD)

 

기능

    그래픽LCD 에사각형, 원, 라인을그린다.

 

 

    http://avr128.com

 

    

    2011-08-10 : 사각형, 원, 라인그리기기능추가

 

*/

 

 

#include <avr/io.h>

#include "WAT128.h"

 

 

#ifdef _USE_GLCD_

#include "gfont.h"

#endif

 

 

int main(){

 

    int i=0;

 

 

//    OpenSCI0(57600); // 디버깅포트

 

    GLCD_Init();

    GLCD_String(0,0," AVR128.com");

 

 

    // 외각선(사각형) 그리기

    GLCD_DrawRect(0,0,127,63);

 

    // 대각선그리기

    GLCD_DOT_Line(0,0,127,63);

    GLCD_DOT_Line(0,63,127,0);

 

    // 원그리기

    GLCD_DOT_DrawCircle(64,32,10);

    GLCD_DOT_DrawCircle(32,32,14);

    GLCD_DOT_DrawCircle(96,32,14);

 

    while(1)

    {

 

    }

}

 

 

 

 

 

 

wat128.h 일부

// 점찍기

void GLCD_SetPixel(int x1,int y1,BOOL _b);

 

// 라인그리기

void GLCD_DOT_Line(int x1,int y1,int x2,int y2);

 

// 원그리기

void GLCD_DOT_DrawCircle(int x1,int y2,int _size);//

 

// 사각형그리기

void GLCD_DrawRect(int x1,int y1,int x2,int y2);

 

 

 

 

 

wat128.c 일부

 

void GLCD_SetPixel(int x1,int y1,BOOL _b)

{

    BYTE byteCS = 0;

    BYTE byteData;

 

    if(x1>=128 || y1>=64)

        return;

 

    if(x1<64 )

    {

        byteCS = 0x01;    

    }

    else

    {

        x1 = x1%64;

        byteCS = 0x02;

    }

 

 

    GLCD_Command(byteCS,0x40 + x1);    // x 좌표지정

    GLCD_Command(0x00,0xB8 + y1/8);    // y 좌표지정

 

 

    GLCD_ReadData(byteCS); //read 하면처음에이상한값이나온다;; 그냥버림

    

 

    byteData = GLCD_ReadData(byteCS);

 

    if(_b==1)

        byteData |= 1<<(y1%8);

    else

        byteData &= ~(1<<(y1%8));

 

    GLCD_Command(byteCS,0x40 + x1);    // x 좌표지정

    GLCD_Command(0x00,0xB8 + y1/8);    // y 좌표지정

 

    GLCD_WriteData(byteCS, byteData,0);

 

}

 

 

void GLCD_DOT_Line(int x1,int y1,int x2,int y2)

{

    int i;

    int y=y1;

    for(i=x1;i<=x2;i++)

    {

        if(y1 <y2)

            y = y1+(i-x1)*(y2-y1)/(x2-x1);

        else

            y = y1-(i-x1)*(y1-y2)/(x2-x1);

        GLCD_SetPixel(i,y,1);

    }

 

}

 

void GLCD_DOT_DrawCircle(int x1,int y1,int _size)

{

    int i;

    int j;

    int y=0;

    int Lasty=0;// dot 간의간격이클경우임의의선을그려준다.

 

    for(i=x1-_size;i<=x1+_size;i++)

    {

        y= round(sqrt((_size*_size )-(i-x1)*(i-x1)));

 

        GLCD_SetPixel(i,y1+y,1);

        GLCD_SetPixel(i,y1-y,1);

 

        if(Lasty !=0)

        {

            // 좌측처리

            if(Lasty +1< y1+y)

            {

                // dot 사이의간격이너무벌어진것이다.

                for(j=1;j<(y1+y)-Lasty;j++)

                {

 

                    GLCD_SetPixel(i-1,y1-y+j,1);    // 좌측상단

                    GLCD_SetPixel(i-1,y1+y-j,1);// 좌측하단에끊어진부분

 

                    //sprintf(g_temp,"\r\nLasty:%dm j:%d",Lasty,j);

                    //PutString0(g_temp);

 

                }

 

            }

            // 우측처리

             else if(Lasty -1 > y1+y)

            {

                // dot 사이의간격이너무벌어진것이다.

                for(j=1;j<Lasty - (y1+y);j++)

                {

                    sprintf(g_temp,"\r\nLasty:%dm i:%d, j:%d, y1+y-j:%d",Lasty,i,j,y1+y-j);

                    PutString0(g_temp);

 

                     GLCD_SetPixel(i,y1-y-j,1);// 우측상단

                     GLCD_SetPixel(i,y1+y+j,1);// 우측하단에끊어진부분

 

 

                }

 

            }

 

        }

 

        Lasty = y1+y;

    }

}

 

void GLCD_DrawRect(int x1,int y1,int x2,int y2)

{

 

    int i=0;

    for(i=x1;i<=x2;i++)

    {

        GLCD_SetPixel(i,y1,1);

        GLCD_SetPixel(i,y2,1);

 

    }

    for(i=y1+1;i<=y2-1;i++)

    {

        GLCD_SetPixel(x1,i,1);

        GLCD_SetPixel(x2,i,1);

 

    }

 

 

 

}

 

 

 

 

 

전체 소스

 



Posted by WhiteAT
,

 

 

 

그래픽 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
Posted by WhiteAT
,

 

 

WAT-KEY 4x4 예제

 

WAT-KEY 4x4 배열을 PC 에서 실시간으로 모니터링 하는 예제

http://avr128.com/27

 

 

 

 

WAT-IO&ADC 예제

 

로터리 스위치의 값을 FND 4자리 중 제일 앞자리에 표시하는 예제

http://avr128.com/25

 

가변 저항의 값에 따라 LED 를 켜는 예제

http://avr128.com/24

 

 

 

Posted by WhiteAT
,

WAT-AVR128_EXT 보드

AVR키트 2011. 7. 20. 15:53

 

 

다른 보드에 연결

 

WAT-AVR128_EXT 보드(확장 보드)를 사용하면 다른 보드와 쉽게 연결 할 수 있습니다.

 

 

 

보드명

보드 설명

WAT-KEY 4x4

4x4 배열의 매트릭스 키보드 보드

WAT-CLCD

Character LCD 보드

WAT-GLCD

Graphics LCD 보드

WAT-IO&ADC

LED, FND 와 가변 저항 테스트 보드

추가 예정

 
   

 

 

 

 

WAT-KEY 4x4 보드

 

WAT-KEY 4x4 보드

4x4 배열로 스위치를 장착하여 MCU의 8개의 핀과 VCC 핀만으로 16개의 스위치를 제어하는 예제를 제공합니다.

 

 

 

 

 

 

 

Posted by WhiteAT
,

WAT-AVR128 모듈

AVR키트 2011. 7. 20. 15:53


제품 소개

 

WAT-AVR128 Module은 Atmel 의 ATMEGA128A을 장착한 모듈로 ATMEGA128A 구동에 필요한 기본적인 부품과 회로를 포함하고 있으며, SP3232 RS-232C IC를 장착하여 PC와의 통신을 쉽게 할 수 있게 도와주는 제품입니다.

 

특징

 

 

사용 전압: 3.3V ~ 5.0V

AD 채널 수: 8채널 10bit

CLOCK: 11.0592 Mhz (보레이트 115200bps에서 오류률 0%)

시리얼 통신: 2채널

2채널을 TTL LEVEL 레벨과 RS-232C 레벨의 두 가지 모두 제공

ISP: ISP 커넥터 제공

크기: 40.6(가로) x 48.8mm (세로)

소켓: 2.54mm 2줄 핀 헤더 사용

 

 

 

 

 

 

 


 

 

외부 장치 연결

 

 

핀 정의

 

좌 측

우 측

1. VCC

2. VCC

41. VCC

42. VCC

3. ADC7/TDI

4. ADC6/TDO

43. AD0

44. AD1

5. ADC5/TMS

6. ADC4/TCK

45. AD2

46. AD3

7. ADC3

8. ADC2

47. AD4

48. AD5

9. ADC1

10. ADC0

49. AD6

50. AD7

11. AREF

12. AVCC

51. ALE

52. NC

13. PE0

14. PE1

53. A15

54. A14

15. PE2

16. PE3

55. A13

56. A12

17. PE4

18. PE5

57. A11

58. A10

19. PE6

20. PE7

59. A09

60. A08

21. GND

22. GND

61. GND

62. GND

23. PB0

24. PB1

63. /RD

64. /WR

25. PB2

26. PB3

65. PD7

66. PD6

27. PB4

28. PB5

67. PD5

68. PD4

29. PB6

30. PB7

69. PD3

70. PD2

31. NC

32. NC

71. PD1

72. PD0

33. PG3

34. PG4

73. TXD0_12V

74. RXD0_12V

35. nRESET

36. NC

75. TXD1_12V

76. RXD1_12V

37. GND

38. GND

77.GND

78.GND

 

 

ISP 핀

10핀 ISP용 커넥터를 제공하여 ISP로 프로그램 라이팅이 가능합니다.

아래처럼 보드 좌측의 1번과 10p 플랫케이블의 적색 1번 핀 방향을 맞춰서 연결해야 합니다.

 




 

 

RS-232C 통신용 핀

 

RS-232C용 통신에 사용되는 핀은 3핀으로 구성되어 PC와의 통신 연결이 쉽습니다.

 

 

 

 

외부 장치 연결

 

핀헤더 소켓을 사용하여 외부 장치와 연결하여 사용할 수 있습니다.

 

WAT-AVR128_EXT 보드(확장 보드)를 사용하면 외부 보드와 쉽게 연결 할 수 있습니다.



 







WAT-KEY 4x4 예제

 

WAT-KEY 4x4 배열을 PC 에서 실시간으로 모니터링 하는 예제

http://avr128.com/27

 

 

 

 

WAT-IO&ADC 예제

 

로터리 스위치의 값을 FND 4자리 중 제일 앞자리에 표시하는 예제

http://avr128.com/25

 

가변 저항의 값에 따라 LED 를 켜는 예제

http://avr128.com/24

 

 

 



매뉴얼  (최신 자료는 http://whiteat.com/57204 에서 제공됩니다.)

WATAVR128_manual.pdf


 

예제 소스  

AVR128_example.zip

 


회로도

WATAVR128_sch.pdf




Posted by WhiteAT
,

 

WAT-AVR128보드로 키 패드를 읽어 PC로 전송하는 방법입니다.

 

키 패드 제어에 대한 자세한 설명은 아래 주소를 참조하세요

http://avr128.com/26

 

 

 

 

 



 

 

 

 

SW16을 누를 경우

 

 

 

 

 

 

SW13, SW14, SW15, SW16을 동시에 누를 경우

 

 

 

 

 

SW1, SW6, SW11, SW16을 동시에 누를 경우

 

 









 

 

 

메인 소스 AVR Studio 4.18 용

 

 

 

/*

    

필요한보드

    1. WAT-AVR128 (모듈)

    2. WAT-AVR128 EXT (확장보드)

    3. WAT-KEY 4x4 (키패드)

=> WAT-KEY 4x4 보드를PORTA 에연결한 예

 

 

기능

    4x4 배열의키상태를시리얼통신으로PC에서실시간으로감시한다.

    - MFC (VC6.0)

    - C# (VS2008)

 

 

컴파일러: AVRStudio 4.18

 

    http://avr128.com

 

*/

 

 

#include <avr/io.h>

#include "WAT128.h"

 

 

void OperatingFromPC();

 

int main(){

 

    // 시리얼통신으로PC에전송하기위한보레이트설정

    InitSCI0(57600);

 

 

    // 키패드초기화

    InitKey4x4();

 

 

    while(1)

    {

        // 키패드의값을읽어서PC로전송

        OperatingFromPC();

 

    }

}

 

 

BOOL    bPCHeadCheckOK = FALSE;

INT16US g_uiPCRecevingDataCount = 0;

BYTE    g_bytePCData[RX_BUFFER_SIZE];

 

//! rx 버퍼초기화

void RXClearFromPC(){

    g_uiPCRecevingDataCount = 0;

    bPCHeadCheckOK = FALSE;

}

 

//! rx 처리루틴

void OperatingFromPC(){

    BYTE byteCommand;

 

    INT16S iRxData;

    iRxData=GetByte0();

    if( 0<= iRxData && iRxData<=255 ){

 

        

        if (TRUE == bPCHeadCheckOK)

        {

            // STX 를통과했다면(이미나왔다면)

            g_bytePCData[g_uiPCRecevingDataCount] = iRxData;

            if(++g_uiPCRecevingDataCount>=RX_BUFFER_SIZE )

            {

                g_uiPCRecevingDataCount =0;

            }

 

            if (COMM_ETX == iRxData )

            {

                byteCommand = g_bytePCData[0];

                switch(byteCommand)

                {

                case 0x10:    // key 4x4

                    if ( g_uiPCRecevingDataCount>=7)

                    {

                        if (COMM_ETX == g_bytePCData[6] )

                        {

                            SendKey4x4( GetKey4x4());

                        }

                        RXClearFromPC();

                    }

                    break;

 

                default:

                    RXClearFromPC();

                    break;

                }            

            }

        }

        else

        {

            // STX 가나오지않았다면STX 가나올때까지기다린다.

            if (COMM_STX == iRxData)

            {

                bPCHeadCheckOK = TRUE;

                g_uiPCRecevingDataCount = 0;

 

            }else{

 

            }

        }

    }

}

 

 

 

 

 

 

 

 

 

C# .NET 2008 소스 (PC용 어플리케이션 소스)

 

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using System.IO.Ports;

using System.Diagnostics;

 

namespace WATkey4x4

{

public partial class frmMain : Form

{

 

// 수신 데이터 보관용 버퍼

List<byte> m_buff = new List<byte>();

 

// 4x4 배열의 버튼 묶음

List<Button> m_Buttons = new List<Button>();

 

 

public frmMain()

{

InitializeComponent();

 

// 시리얼 통신 초기화

m_sp1 = new SerialPort();

m_sp1.DataReceived += new SerialDataReceivedEventHandler(m_sp1_DataReceived);

 

 

// 한번에 처리하기 위해 모든 버튼을 묶음

m_Buttons.Add(this.btnSW1);

m_Buttons.Add(this.btnSW2);

m_Buttons.Add(this.btnSW3);

m_Buttons.Add(this.btnSW4);

m_Buttons.Add(this.btnSW5);

m_Buttons.Add(this.btnSW6);

m_Buttons.Add(this.btnSW7);

m_Buttons.Add(this.btnSW8);

m_Buttons.Add(this.btnSW9);

m_Buttons.Add(this.btnSW10);

m_Buttons.Add(this.btnSW11);

m_Buttons.Add(this.btnSW12);

m_Buttons.Add(this.btnSW13);

m_Buttons.Add(this.btnSW14);

m_Buttons.Add(this.btnSW15);

m_Buttons.Add(this.btnSW16);

 

}

 

void m_sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)

{

// 수신된 데이터를 처리하자.

int iRecSize = m_sp1.BytesToRead;

 

if (iRecSize != 0)

{

 

byte[] buff = new byte[iRecSize];

m_sp1.Read(buff, 0, iRecSize);

 

foreach (byte by in buff)

{

m_buff.Add(by);

}

}

 

 

 

// STX 찾기

 

while (true)

{

if (m_buff.Count <= 0) break;

if (m_buff[0] == 0x02) break;

else

{

m_buff.RemoveAt(0);

}

}

 

if (m_buff.Count >= 8)

{

bool bSame = true;

 

if (0x02 != m_buff[0]) bSame = false;

if (0x03 != m_buff[7]) bSame = false;

 

if (true == bSame)

{

 

// CRC 를 체크해야 하는데 생략 ;;

 

UInt16 byteData = Convert.ToUInt16(m_buff[2]);

byteData <<= 8;

byteData += Convert.ToUInt16(m_buff[3]);

 

 

// 버튼을 하나씩 꺼내서 눌러졌는지 아닌지를 검사하자

foreach (Button btn in m_Buttons)

{

// SW1

if (byteData % 2 == 1)

{

// 눌러졌으면 RED

btn.BackColor = System.Drawing.Color.Red;

}

else

{

// 눌러지지 않았으면 Control(기본색)

btn.BackColor = System.Drawing.SystemColors.Control;

}

byteData >>= 1;

}

 

// 수신 버퍼에서 지금 처리된 데이터를 제거하자

m_buff.RemoveRange(0, 7);

 

 

 

}

else

{

// 수신 버퍼 초기화

m_buff.Clear();

 

}

}

}

 

 

private void btnOpen_Click(object sender, EventArgs e)

{

// 컴포트 열기

this.btnOpen.Enabled = false;

m_sp1.PortName = txbComNum.Text; // 컴포트명

m_sp1.BaudRate = Convert.ToInt32(txbBaud.Text); // 보레이트

 

m_sp1.Open();

 

tmr50mS.Enabled = true;

tmr50mS.Start();

}

 

private void btnClose_Click(object sender, EventArgs e)

{

// 컴포트 닫기

tmr50mS.Stop();

m_sp1.Close();

this.btnOpen.Enabled = true;

}

 

private void TmrRequest(object sender, EventArgs e)

{

// 키패드 값을 요청하자

byte[] byteData =new byte[100];

int iLength=0;

 

byteData[iLength++] = 0x02;

byteData[iLength++] = 0x10;

 

byteData[iLength++] = 0x00;

byteData[iLength++] = 0x00;

byteData[iLength++] = 0x00;

byteData[iLength++] = 0x00;

 

byteData[iLength++] = 0xCC; // CRC 체크를 생략한다;

 

byteData[iLength++] = 0x03;

 

m_sp1.Write(byteData,0,iLength);

}

}

}

 

 

 

 

 

 

 

 

 

 

 

 

필요한 보드

 

 

WAT-AVR128 (ATMEGA128A 모듈)

WAT-AVR128 EXT (ATMEGA128A 외부 인터페이스 보드)

WAT-KEY 4x4 (4x4 키 패드 보드)

 

 

 

 

프로젝트 파일(전체 소스) 다운로드

 

ATMEGA128 소스 &  C# 소스:  ( 압축파일 안의 App 이름이 있는 폴더가 c# 소스입니다.)

EX_01_05 다운로드

 


 

Posted by WhiteAT
,

 

 

로터리(Rotary) 스위치 값을 FND(4401ASR)에 표시하는 예제입니다. 회로는 아래와 같이 구성합니다.

 

PORTA.0: 로터리 0에 연결 (입력)

PORTA.1: 로터리 0에 연결 (입력)

PORTA.2: 로터리 0에 연결 (입력)

PORTA.3: 로터리 0에 연결 (입력)

 

 

PORTA.4 : FND 1자리에 SEL 신호 (출력)

PORTA.5 : FND 2자리에 SEL 신호 (출력)

PORTA.6 : FND 3자리에 SEL 신호 (출력)

PORTA.7 : FND 4자리에 SEL 신호 (출력)

 

 

PORTB: FND 데이터 신호(출력)

 

 

 

 

 

WAT-AVR128, WAT-IO&ADC 보드에서의 실행

 

 

 

WAT-AVR128와 WAT-IO&ADC 보드에서의 실행 결과 입니다.

 

 





 

초기 상태 – 로터리 스위치가 0 이라 FND 에 0234을 표시합니다.

 

 

 

 

 

 

4 – 로터리 스위치가 4 라서 FND 에 4234을 표시합니다.

 

 

 

 

 

7 – 로터리 스위치가 7 이라서 FND 에 7234을 표시합니다.

 

 

 

 

 

 

 

 

메인 소스 AVR Studio 4.18 용

 

 

/**********************************************

 

로터리(Rotary) 스위치값을FND(4401ASR)에표시하는예제

 

PORTA.0 : 로터리0에연결(입력)

PORTA.1 : 로터리0에연결(입력)

PORTA.2 : 로터리0에연결(입력)

PORTA.3 : 로터리0에연결(입력)

 

 

PORTA.4 : FND 1자리에SEL 신호(출력)

PORTA.5 : FND 2자리에SEL 신호(출력)

PORTA.6 : FND 3자리에SEL 신호(출력)

PORTA.7 : FND 4자리에SEL 신호(출력)

 

 

PORTB : FND 데이터신호(출력)

 

 

 

 

Main Clock : 11.0592Mhz

 

 

 

 

 

Tools : AVR Studio 4.16

테스트보드: WAT-AVR128 보드+ WAT IO&ADC

 

http://avr128.com

 

*********************************************/

 

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdio.h>

 

#include "wat128.h"

 

 

 

int main()

{

 

    // FND4 초기화

    InitFND4();

 

    // 로터리초기화

    InitRotary();

 

 

    while (1)

    {

        // 로터리스위치값을int 형으로받기            

        g_FND[0] = GetRotaryInt();

 

        // FND 4자리표시

        DisplayFND4(g_FND[0],g_FND[1],g_FND[2],g_FND[3]);

 

    }

 

}

 

 

 

 

원문은 http://avr128.com 에 있습니다.

 

 

주요 부품

ATMEGA128 - 1EA

로터리 스위치 – 1EA

SSR-10

POWER 5V/1A

 

 

 


프로젝트 파일(전체 소스) 다운로드

 





Posted by WhiteAT
,

 

가변저항의 변화에 따라 PORTA 에 연결된 LED 상태를 변화시키는 예제(소스)입니다.

 

PF1(ADC1) 핀에 연결된 가변 저항(5K) 값을 읽어

PORTA 에 연결된 LED에 출력

 

가변저항 0.6K 이하 => LED1개 ON

가변저항 1.2K 이하 => LED2개 ON

가변저항 1.8K 이하 => LED3개 ON

가변저항 2.4K 이하 => LED4개 ON

가변저항 3.0K 이하 => LED5개 ON

가변저항 3.6K 이하 => LED6개 ON

가변저항 4.2K 이하 => LED7개 ON

가변저항 4.2K 초과 => LED8개 ON

 

 

 

 

WATSIM 시뮬레이션 결과

 

WATSIM 에서는 ADC 기능을 추가할 예정이라

현재는 시뮬레이션이 안됩니다.

 

 

 

 

 

WAT-AVR128 보드에서의 실행

 

 

WAT-AVR128 과 WAT-IO&ADC 보드를 연결한 결과 입니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

메인 소스 AVR Studio 4.18

 

 

/**********************************************

 

PF3(ADC3) 핀에연결된가변저항(5K) 값을읽어

PORTA 에연결된LED에출력

 

가변저항0.6K 이하=> LED1ON

가변저항1.2K 이하=> LED2ON

가변저항1.8K 이하=> LED3ON

가변저항2.4K 이하=> LED4ON

가변저항3.0K 이하=> LED5ON

가변저항3.6K 이하=> LED6ON

가변저항4.2K 이하=> LED7ON

가변저항4.2K 초과=> LED8ON

 

 

 

 

Main Clock : 11.0592Mhz 

 

 

 

 

 

Tools : AVR Studio    4.16

테스트보드: WAT-AVR128 보드+ WAT IO&ADC

 

http://avr128.com  

 

*********************************************/

 

#include <avr/io.h>

#include <avr/interrupt.h>

#include <stdio.h>

 

#include "wat128.h"

 

 

// AD 값보관

UINT16 g_adc1;

 

int main()

{

           INT16 uiTemp; // 임시변수

 

           // LED 출력용포트

           DDRA = 0xFF;

 

           // ADC 초기화

           InitADC();

 

 

           while (1)

           {  

 

                     g_adc1 = 0;

 

                     // 노이즈를생각해서값을16번읽어평균을낸다.

                     for(uiTemp = 0; uiTemp<16;uiTemp++){

                                ADMUX=0x40 | 0x01;

                                ADCSRA = 0xD7;                  
                                while((ADCSRA & 0x10) != 0X10);

                                g_adc1 += ADCL + (ADCH*256);

                     }

                     g_adc1>>=4;

                    

                     if( g_adc1 <128)                       // 1/8 회전

                                PORTA = 0xFE;

                     else if( g_adc1 <256)                 // 2/8 회전

                                PORTA = 0xFC;

                     else if( g_adc1 <384)                 // 3/8 회전

                                PORTA = 0xF8;

                     else if( g_adc1 <512)                 // 4/8 회전

                                PORTA = 0xF0;

                     else if( g_adc1 <640)                 // 5/8 회전

                                PORTA = 0xE0;

                     else if( g_adc1 <768)                 // 6/8 회전

                                PORTA = 0xC0;

                     else if( g_adc1 <896)                 // 7/8 회전

                                PORTA = 0x80;

                     else 

                                PORTA = 0x00;

 

 

 

           }

 

}

 

 

 

 

 

 

 

 

 

 

 

주요 부품

ATMEGA128 - 1EA

LED 8EA

가변저항 5K – 1EA

POWER 5V/1A

 

 

 

 



프로젝트 파일 다운로드

프로젝트 파일(소스 포함):






가변저항에 대해 정리하였습니다.

http://avr128.com/23

 

 

Posted by WhiteAT
,