본문 바로가기

프로젝트/TFT LCD 한글 출력 (아두이노)

Hangul_SD.H 를 이용한 한글 출력 ( 폰트파일 필요함 )

한글 폰트파일과  인덱스 파일이 필요 합니다. 두 파일의 구조는 여기를 참고

Hangul_SD.H
 
//        HanGul.SD.H    ver 1.0     아두이노용 한글 출력 클래스
//
//        제작자  :  신 옥 진
//          
//        재배포 금지 링크를 사용 하세요.
//
//   Index1 구조 ( 4 Byte Record )  [폰트offset : 4byte Long]    
//   Index2 구조 ( 8 Byte Record )  [폰트코드 : 4byte Long][폰트offset : 4byte Long]  
//
//   Index2 사용시 소스코드에 #define _INDEX_2_ 코드 넣어야 함
//
//   < 소스 코드 순서 >
//   #define   _TFTLCD_      myLcd              // myLcd는 원하는 이름으로 하고 include 앞에 선언
//   #define _INDEX_2_                     // 인덱스방법 2로 사용시에 만  (없을시 방법1)                                      
//   #include "c:\\Arduino\\HanGul_TFT.H"       // 헤더파일 전체 경로                                        
//   HanGul_TFT  ht;                            // 한글출력 클래스
//
//   폰트파일과 인덱스파일은 SD카드 "UTF_8//" 에 있는 것으로 함
//   바꿀려면  아래 define 부분을 수정하면 됨 (주의) 디렉토리 표시가 윈도우와 다름 '\'아니고  '/'사용                          

#ifndef _Hangul_TFT_          
#define _Hangul_TFT_      

#ifdef _INDEX_2_
#define _INDEX_FILE_ "UTF_8//fIndex2.idx"  //  인덱스2 파일
#else
#define _INDEX_FILE_ "UTF_8//fIndex1.idx"  //  인댁스1 파일
#endif
#define _FONT_FILE_  "UTF_8//Hangul.utf"   //  폰트 파일

                           
#include <SPI.h>              
#include <SD.h>                
#include <Adafruit_GFX.h>                                          
#include <UTFTGLUE.h>

#ifndef _MY_COLOR_               //  Color 정의
#define _MY_COLOR_
#define cBlack        0x0000
#define cWhite        0xFFFF
#define cRed          0xF800      
#define cGreen        0x0400
#define cBlue         0x001F
#define cSilver       0xC618
#define cGray         0x8410
#define cMaroon       0x8000
#define cYellow       0xFFE0
#define cOlive        0x8400
#define cLime         0x07E0
#define cAqua         0x07FF
#define cTeal         0x0410
#define cNavy         0x0010
#define cFuchsia      0xF81F
#define cPurple       0x8010
#define cTransparent  0xFFFFFFFF
#endif


UTFTGLUE  _TFTLCD_(0x9488,A2,A1,A3,A4,A0);  

#define  BASE_CODE  0xE28A82


struct Box               // 문자열의 사각형 좌표
{
   int x,y,x2,y2;  
} ;

class HanGul_TFT
{
  private:
      unsigned short _HANGUL_FONT[16];               // 폰트 저장변수
      File _Index_File_,_Font_File_;       // 인덱스파일 , 폰트파일            
      int  _color=cWhite;                  // 폰트색상
      int  _bkColor = cBlack;              // 폰트배경색      

  public:  
      Box  box;    
    HanGul_TFT(int pin)
    {
      SD.begin(pin);    
      pinMode(A0, OUTPUT);                  
      digitalWrite(A0, HIGH);               //  TFT LCD 시작    
   
    HanGul_TFT::_Index_File_ = SD.open(_INDEX_FILE_);   // 인덱스 파일 오픈  
    HanGul_TFT::_Font_File_  = SD.open(_FONT_FILE_);   // 폰트   파일 오픈  
    }    
    HanGul_TFT(){ HanGul_TFT(10) ; }
    void end();                     // 한글클래스 종료  : 사용 안해도 됨
    void color(int _c ) ;           // 글자색
    void color(int _c ,int _bk);    // 글자색,  배경색
    void fill(int _c);              // 바로 앞에 출력한 문자열을 _c 색으로 채우기
    void fill() ;                   // 배경색으로 채우기
    void rect(int _c);              // 바로 앞에 출력한 문자열에 _c 색으로 테두리 그리기
    void rect();                    // 문자색으로 테두리 그리기
    void under(int _c);             // 바로 앞에 출력한 문자열에 문자색으로 밑줄 그리기
    void under();                   // 문자색으로 밑줄 그리기
    void print( String s, int x, int y , int mx, int my );  // x,y좌표에 가로 mx배 ,세로 my배로 문장 출력
    void print( String s,int  x, int y  );                  //  1배
    void print( String s,int  x, int y ,int m  );           //  m배
   
  private:
    void _setDot_Func( int col, int row, int x, int y,int mx,int my ,int c );  //폰트의 1bit에 해당하는 점 그리기
    void _drawFont_Func( int x, int y,  int mx , int my);    
    #ifdef _INDEX_2_
    void getFont( long code );
    #endif    
};



void HanGul_TFT::end()         //   사용 안해도 됨
{
    _Index_File_.close();
    _Font_File_.close();
}  

void HanGul_TFT::color(int _c )
{
  _color=_c;    
}

void HanGul_TFT::color(int _c ,int _bk)
{
  _color=_c;
  _bkColor=_bk;

}

void HanGul_TFT::fill(int _c)                 // 문자열을  _c색상으로 채우기
{
    _TFTLCD_.setColor( _c  );    
    _TFTLCD_.fillRect(box.x,box.y,box.x2,box.y2);    

}

void HanGul_TFT::fill() { fill(_bkColor); }   // 문자열을  배경색상으로 채우기  // 문자열 지우기에 이용

void HanGul_TFT::rect(int _c)                 // _c색상으로 문자열의 외곽선 그리기
{
    _TFTLCD_.setColor( _c );
    _TFTLCD_.drawRect(box.x,box.y,box.x2,box.y2);    
}

void HanGul_TFT::rect() { rect(_color); }       // 문자색상으로 문자열의 외곽선 그리기

void HanGul_TFT::under(int _c)                  // 문자열에 _c색상으로 밑줄
{
    _TFTLCD_.setColor( _c );
    _TFTLCD_.fillRect(box.x, box.y2-2,box.x2,box.y2+1);    
}
void HanGul_TFT::under(){ under(_color); }                               // 문자열에 문자색상으로 밑줄

void HanGul_TFT::print( String s,int  x, int y  ) {  print( s, x, y , 1 ,1 ); }

void HanGul_TFT::print( String s,int  x, int y ,int m  ) { print( s, x, y , m, m  );  }



void HanGul_TFT::_setDot_Func( int col, int row, int x, int y,int mx,int my ,int c )
{                      
    _TFTLCD_.setColor( c );  
    for(int dx=0 ; dx< mx ;dx++)      
       for( int dy=0;dy<my;dy++)  
          _TFTLCD_.drawPixel(   x+col*mx+dx   ,y+row*my+dy  );  
}

void HanGul_TFT::_drawFont_Func( int x, int y,  int mx , int my)
{                                   // 문자(1자) 그리기
   
    for( int row=0; row< 16 ; row++)    // 폰트 bit 세로방향
    {
          for(int col=0;col<16;col++)      // 폰트 bit 가로방향
          {                                    
                if( _HANGUL_FONT[row] & 0b1000000000000000 )   _setDot_Func(  col,  row, x, y, mx, my, _color);
                else      _setDot_Func(  col,  row, x, y, mx, my, _bkColor  );        
                _HANGUL_FONT[row] <<= 1;                    // bit가 1이면 점그리기 함수 호출
          }
    }
}


#ifdef _INDEX_2_    //  Index 방법 2번이면
void HanGul_TFT::getFont( long code )
{
    long low=0, high = 11746;
    long now = 5873;
    long hCode,hIdx;
    long temp=-1;

    while(true)
    {
        _Index_File_.seek(now*8);
        _Index_File_.read(&hCode,4);     // 한글코드 읽기      
        if( hCode == code )
        {
        _Index_File_.seek(now*8+4);
        _Index_File_.read(&hIdx,4);
        _Font_File_.seek(hIdx);
        _Font_File_.read(_HANGUL_FONT ,32);
        return;
        }
    else if( hCode > code ) high = now;
    else  low = now;          
    now=(low+high)/2;
    if( now==temp) return;
    else temp=now;
    }  
}
#endif


void HanGul_TFT::print( String s, int x, int y , int mx, int my )
{  
    box.x=x;
    box.y=y;
    box.y2=y+16*my-1;    

    _TFTLCD_.setTextSize(my*2);            

    for( int p=0; p <s.length() ;p++)
    {                                                
        if(  isAscii(s[p])  )
        {      
            if( s[p]==0x0d )break;                                        
            _TFTLCD_.setCursor(x,y);  
            _TFTLCD_.setTextColor(_color,_bkColor);                                                                                                    
            _TFTLCD_.println(s[p]);          
            if( s[p]==0x20 ) x+=8*my;
            else x+=12*my;        
        }
        else
        {    
            _TFTLCD_.setColor( _color)  ;
           
                  long code =byte(s[p]);              
                  code = code << 8;
                  code+=byte(s[p+1]);              
                  code = code << 8;
                  code+=byte(s[p+2]);  
                  #ifdef _INDEX_2_
                   getFont(code);    
                  #else
                   code-= BASE_CODE;                
                   _Index_File_.seek(code*4);

                   long fPoint;
                   _Index_File_.read( &fPoint,4);

                   _Font_File_.seek( fPoint);
                   _Font_File_.read( _HANGUL_FONT ,32);    
                  #endif            
                  _drawFont_Func( x,  y, mx, my) ;
                  x+=16*mx;
                  p+=2;
                                 
         } // isASCII else
    }// p 스트링 길이 반복  
    box.x2=x-1;
}

/*
void HanGul_TFT::print( String s, int x, int y , int mx, int my )
{                        // 문자열을 그리는 함수
    box.x=x;                    
    box.y=y;    // 문자열 상자박스 좌표
    box.y2=y+16*my-1;    

    _TFTLCD_.setTextSize(my*2);  //  TFT LCD 내장 폰트 사이즈 설정          

    for( int p=0; p <s.length() ;p++) //문자열 가로방향으로 진행
    {                                                
        if(  isAscii(s[p])  )       // 문자가 아스키코드(내장폰트)
        {      
              if( s[p]==0x0d )break;    // 문자열 끝이면 빠져 나감                                    
              _TFTLCD_.setCursor(x,y);  
              _TFTLCD_.setTextColor(_color,_bkColor); // 내장폰트 색깔                                                                                                    
              _TFTLCD_.println(s[p]);          
              if( s[p]==0x20 ) x+=8*my; //공백은 가로로 8dot 이동  
              else x+=12*my;            //가로로 16Dot 이동
        }
        else
        {    
                     _TFTLCD_.setColor( _color)  ;
                    long code =byte(s[p]);      // 3Byte 문자(UTF-8)      
                    code = code << 8;    // 상위 Byte에서 하위byte로 읽어오기  
                    code+=byte(s[p+1]);              
                    code = code << 8;
                    code+=byte(s[p+2]);  
                   
                            code-= BASE_CODE;                
                            _Index_File_.seek(code*4);

                            long fPoint;
                            _Index_File_.read( &fPoint,4);

                            _Font_File_.seek( fPoint);
                            _Font_File_.read( _HANGUL_FONT ,32);  
                    //}
                    _drawFont_Func( x,  y, mx, my) ;
                    x+=16*mx;
                    p+=2;
                                 
        } // isASCII else
}// p 스트링 길이 반복  
box.x2=x-1;
} */

#endif
아두이노 소스 파일
  #define   _TFTLCD_      myLcd              // TFT LCD 이름 정의/ 
#define   _INDEX_2_         
#include  "D:\\myHeader\\StreamReader.H"        
#include  "D:\\myHeader\\Hangul_SD.H"    
                                    
HanGul_TFT  ht(53 );     // Mega 사용시 SD카드 SS pin  53    Uno 사용시 10 또는 생략
//  HanGul_TFT  ht;   //  Uno 사용시

void setup()
{
  int y=0;     
       
  StreamReader txt("my.txt",53);    
                            
  myLcd.InitLCD();            
  myLcd.setRotation(3);   //3 가로 480x320  //2 세로   320x480
  myLcd.clrScr();      
   
   
   while( ! txt.endf())
   {     
     ht.print( txt.readLine() ,0,y,2,3);   
   
     y=y+48;
     if(y>280 ){
        y=0;    
        myLcd.clrScr();      
     }
  }
  txt.close();
  ht.end();
}

void loop()
{
 
}