#include "src/io_Header.h"
const int __attribute__((progmem)) string[][16] = { 
  0x00, 0x00, 0x1800, 0x18fc, 0x1980, 0x1980, 0x1980, 0x7980, 0x18c0, 0x18c0, 0x1860, 0x1830, 0x181c, 0x1800, 0x00, 0x00, //가
  0x00, 0x00, 0x1800, 0x180c, 0x180c, 0x180c, 0x180c, 0x780c, 0x180c, 0x180c, 0x180c, 0x1ff8, 0x1800, 0x1800, 0x00, 0x00, //나
  0x00, 0x00, 0x1800, 0x1bf8, 0x180c, 0x180c, 0x180c, 0x780c, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ff8, 0x1800, 0x00, 0x00, //다
  0x00, 0x00, 0x1800, 0x18fc, 0x1980, 0x1980, 0x1980, 0x78f8, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ff8, 0x1800, 0x00, 0x00, //라
  0x00, 0x00, 0x1800, 0x19fc, 0x198c, 0x198c, 0x198c, 0x798c, 0x198c, 0x198c, 0x198c, 0x198c, 0x19fc, 0x1800, 0x00, 0x00, //마
  0x00, 0x00, 0x1800, 0x198c, 0x198c, 0x198c, 0x198c, 0x79fc, 0x198c, 0x198c, 0x198c, 0x198c, 0x18f8, 0x1800, 0x00, 0x00, //바
  0x00, 0x00, 0x1800, 0x1860, 0x1860, 0x1860, 0x1860, 0x7870, 0x18f0, 0x18f0, 0x1998, 0x1998, 0x1b0c, 0x1800, 0x00, 0x00, //사
  0x00, 0x00, 0x1800, 0x18f8, 0x198c, 0x198c, 0x198c, 0x798c, 0x198c, 0x198c, 0x198c, 0x198c, 0x18f8, 0x1800, 0x00, 0x00, //아
  0x00, 0x00, 0x1800, 0x1bfc, 0x1860, 0x1860, 0x1860, 0x7860, 0x18f0, 0x18f0, 0x1998, 0x1998, 0x1b0c, 0x1800, 0x00, 0x00, //자
  0x00, 0x00, 0x1800, 0x18f0, 0x1800, 0x1bfc, 0x1860, 0x7860, 0x1860, 0x18f0, 0x18f0, 0x1998, 0x1b0c, 0x1800, 0x00, 0x00, //차
  0x00, 0x00, 0x1800, 0x18fc, 0x1980, 0x1980, 0x1980, 0x79fc, 0x18c0, 0x18c0, 0x1860, 0x1830, 0x181c, 0x1800, 0x00, 0x00, //카
  0x00, 0x00, 0x1800, 0x1bf8, 0x180c, 0x180c, 0x180c, 0x79fc, 0x180c, 0x180c, 0x180c, 0x180c, 0x1ff8, 0x1800, 0x00, 0x00, //타
  0x00, 0x00, 0x1800, 0x1ffc, 0x1800, 0x19b0, 0x19b0, 0x79b0, 0x19b0, 0x19b0, 0x19b0, 0x19b0, 0x1ffc, 0x1800, 0x00, 0x00, //파
  0x00, 0x00, 0x1800, 0x18f0, 0x1800, 0x1bfc, 0x1800, 0x78f0, 0x1998, 0x1998, 0x1998, 0x1998, 0x18f0, 0x1800, 0x00, 0x00, //하
  0x00, 0x00, 0x00, 0x180, 0x180, 0x3c0, 0x3c0, 0x660, 0x660, 0x7e0, 0xc30, 0xc30, 0xc30, 0x00, 0x00, 0x00, //A
  0x00, 0x00, 0x00, 0x7f0, 0xc30, 0xc30, 0xc30, 0x7f0, 0xc30, 0xc30, 0xc30, 0xc30, 0x7f0, 0x00, 0x00, 0x00, //B
  0x00, 0x00, 0x00, 0x7c0, 0xc60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xc60, 0x7c0, 0x00, 0x00, 0x00, //C
  0x00, 0x00, 0x00, 0x3f0, 0x630, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0x630, 0x3f0, 0x00, 0x00, 0x00, //D
  0x00, 0x00, 0x00, 0x7f0, 0x30, 0x30, 0x30, 0x7f0, 0x30, 0x30, 0x30, 0x30, 0x7f0, 0x00, 0x00, 0x00, //E
  0x00, 0x00, 0x00, 0x7f0, 0x30, 0x30, 0x30, 0x7f0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, //F
  0x00, 0x00, 0x00, 0x7c0, 0xc60, 0x1830, 0x30, 0x30, 0x1f30, 0x1830, 0x1830, 0x1c60, 0x1fc0, 0x00, 0x00, 0x00, //G
  0x00, 0x00, 0x00, 0xc30, 0xc30, 0xc30, 0xc30, 0xff0, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0x00, 0x00, 0x00, //H
  0x00, 0x00, 0x00, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x00, 0x00, 0x00, //I
  0x00, 0x00, 0x00, 0x300, 0x300, 0x300, 0x300, 0x300, 0x300, 0x300, 0x330, 0x330, 0x1e0, 0x00, 0x00, 0x00, //J
  0x00, 0x00, 0x00, 0xc60, 0x660, 0x360, 0x1e0, 0xe0, 0x1e0, 0x360, 0x660, 0xc60, 0x1860, 0x00, 0x00, 0x00, //K
  0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xfe0, 0x00, 0x00, 0x00, //L
  0x00, 0x00, 0x00, 0x1818, 0x1818, 0x1c38, 0x1c38, 0x1e78, 0x1e78, 0x1bd8, 0x1bd8, 0x1998, 0x1998, 0x00, 0x00, 0x00, //M
  0x00, 0x00, 0x00, 0xc30, 0xc70, 0xc70, 0xcf0, 0xdb0, 0xdb0, 0xf30, 0xe30, 0xe30, 0xc30, 0x00, 0x00, 0x00, //N
  0x00, 0x00, 0x00, 0x7c0, 0xc60, 0x1830, 0x1830, 0x1830, 0x1830, 0x1830, 0x1830, 0xc60, 0x7c0, 0x00, 0x00, 0x00, //O
  0x00, 0x00, 0x00, 0x7f0, 0xc30, 0xc30, 0xc30, 0xc30, 0x7f0, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, //P
  0x00, 0x00, 0x00, 0x7c0, 0xc60, 0x1830, 0x1830, 0x1830, 0x1830, 0x1830, 0x1e30, 0xc60, 0x1fc0, 0x00, 0x00, 0x00, //Q
  0x00, 0x00, 0x00, 0x7f0, 0xc30, 0xc30, 0xc30, 0xc30, 0x7f0, 0xc30, 0xc30, 0xc30, 0xc30, 0x00, 0x00, 0x00, //R
  0x00, 0x00, 0x00, 0x7e0, 0xc30, 0xc30, 0x30, 0x1e0, 0x700, 0xc00, 0xc30, 0xc30, 0x7e0, 0x00, 0x00, 0x00, //S
  0x00, 0x00, 0x00, 0xff0, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x180, 0x00, 0x00, 0x00, //T
  0x00, 0x00, 0x00, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0xc30, 0x7e0, 0x00, 0x00, 0x00, //U
  0x00, 0x00, 0x00, 0xc30, 0xc30, 0xc30, 0x660, 0x660, 0x660, 0x3c0, 0x3c0, 0x180, 0x180, 0x00, 0x00, 0x00, //V
  0x00, 0x00, 0x00, 0x318c, 0x318c, 0x318c, 0x33cc, 0x1bd8, 0x1e78, 0x1e78, 0xc30, 0xc30, 0xc30, 0x00, 0x00, 0x00, //W
  0x00, 0x00, 0x00, 0xc30, 0xc30, 0x660, 0x3c0, 0x180, 0x180, 0x3c0, 0x660, 0xc30, 0xc30, 0x00, 0x00, 0x00, //X
  0x00, 0x00, 0x00, 0xc30, 0xc30, 0x660, 0x660, 0x3c0, 0x3c0, 0x180, 0x180, 0x180, 0x180, 0x00, 0x00, 0x00, //Y
  0x00, 0x00, 0x00, 0xff0, 0xc00, 0x600, 0x300, 0x180, 0x180, 0xc0, 0x60, 0x30, 0xff0, 0x00, 0x00, 0x00, //Z
};
unsigned char FontColor = 0; // 문자 색상 설정 변수
unsigned char cnt_FontColor = 0; // 문자 색상 카운터 변수
unsigned int Sel_Char = 0;  // 문자 선택 변수
ISR(TIMER2_OVF_vect)  // 타이머/카운터 인터럽트 서비스 루틴, Tick time per 1mS!
{
  static unsigned int cnt = 0; // 타이머 카운터 변수
  cnt++;
  if (cnt >= 1000)  // 1Sec가 되면...
  {
    cnt = 0;  // 1초 카운터 변수 초기화 
    Sel_Char = Sel_Char + 2;  //문자 선택 변수 증가
    if (Sel_Char > 39) // string 배열변수의 0행부터 39행을 지정, 39 이상이 되면...
    {
      Sel_Char = 0;  //문자 선택 변수 초기화
      cnt_FontColor++; //문자 색상 카운터 변수 증가
      if(cnt_FontColor>3){ //문자 색상 카운터 변수값이 3 이상이 되면... 적색, 녹색,
// 청색으로 색상이 변함
      cnt_FontColor = 0; //문자 색상 카운터 변수 초기화
      }
    }
  }
}
void setup()
{
  //입출력 레지스터 설정 초기화
  DDRB = 0x3f;  // PORTB 5~0 핀 출력으로 설정
  DDRC = 0x08;  // PORTC 3 핀 출력으로 설정
  DDRD = 0xfc;  // PORTD 7~2 핀 출력으로 설정
  //Timer/Conunter Interrupt initialization
  TCCR2A = 0x00;
  TCCR2B = 0x04;  // 타이머 카운터2 노멀 모드, 64분주 
  TIMSK2 = 0x01;  // 타이머 카운터2 인터럽트 허용
  TCNT2 = 0x06; // 타이머 카운터2 초기값: 6
  SREG = 0x80;  // 인터럽트 허용
}
void loop()
{
  static unsigned int i_cnt = 0;  //for문을 위한 사용자 변수
  unsigned int Buff[16] = { 0 };
  // 16x16 도트매트릭스1 문자 사용자 배열
  unsigned int Buff2[16] = { 0 };
  // 16x16 도트매트릭스2 출력 사용자 배열
  unsigned char High, Low, High2, Low2 = 0;
  // 마스킹을 위한 상위 및 하위 바이트 사용자 변수
  switch(cnt_FontColor){ //문자 색상 카운터 변수 스위치문
    case 0: FontColor = Red;break; // 문자를 적색으로 표현
    case 1: FontColor = Green;break; // 문자를 녹색으로 표현
    case 2: FontColor = Blue;break; // 문자를 청색으로 표현
  }
  for (i_cnt = 0; i_cnt < 16; i_cnt++)  // 출력할 문자 복사하기 위한 for문
  {
    Buff[i_cnt] = pgm_read_word(&string[Sel_Char][i_cnt]);
    // 1열부터 16열까지의 16x16 도트매트릭스1 데이터 복사
    Buff2[i_cnt] = pgm_read_word(&string[Sel_Char+1][i_cnt]);
    // 17열부터 32열까지의 16x16 도트매트릭스2 데이터 복사
  }
  for (i_cnt = 0; i_cnt < 16; i_cnt++)
  {
    High = (Buff[i_cnt] >> 8);  //16x16 도트매트릭스1 상위 바이트 저장
    Low = (Buff[i_cnt] &0xff);  //16x16 도트매트릭스1 하위 바이트 저장
    High2 = (Buff2[i_cnt] >> 8);  //16x16 도트매트릭스2 상위 바이트 저장
    Low2 = (Buff2[i_cnt] &0xff);  //16x16 도트매트릭스2 하위 바이트 저장
    row_dynamic(i_cnt);
    // 행(Row) 선택하기 row_dynamic 함수 호출, 인자값 i_cnt값이 전달 됨
    Shift_Register(High, Low, i_cnt, FontColor);
    // 저장된 16x16 도트매트릭스1 데이터 전송
    Shift_Register(High2, Low2, i_cnt, FontColor);
    // 저장된 16x16 도트매트릭스2 데이터 전송
    ActivePulse();
    // 데이터 전송 후 래치신호를 전송하는 ActivePulse함수 호출
  }
}
