8051( 중급 9부 - Graphic LCD ) |
요즈음에는 그래픽 LCD가 핸드폰에도 사용이 될 정도로 보편화 되어 있슴다. 그래픽 LCD를 핸들링 하려면 아무래도 C로 작성하는 편이 훨씬 용이 할검다. 연산도 많고 알고리즘 구현도 많이 해야 하기 때문임다. 그래픽 알고리즘이 정리가 잘 되어 있는 책으로는 "Advanced Graphics in C"라는 책이 있슴다. 산적은 DOS 시절에 구입을 했기 때문에 지금도 그책이 나오고 있는지는 몰겠슴다. 이 책은 PC상에서 그래픽을 구현하기 위한 책이기는 하지만 알고리즘 정리가 잘되어 있어서 8051에 적용하는데도 무리가 없을검다. 먼저 점을 찍는 알고리즘을 보기로 함다. 예를 드는 그래픽 LCD는 256 x 64의 monochrome LCD로 가정 함다.
video RAM 00 01 02 03 ....... 0x1F --첫번째 라인 76543210765432107654321076543210 20 21 22 23 ....... 0x3F --첫번째 라인 76543210765432107654321076543210 여기에서 두번째 라인의 왼쪽에서 두번째 위치에 pixel을 찍는다고 가정을 함다. 그러면 좌표상으로는 x=1, y=1이 됨다. 제일 위쪽의 원점은 x=0, y=0이기 때문임다. 주어진 좌표를 이용해서 video RAM의 address를 구하기로 함다. y = 0일때의 video RAM의 address는 0x00이 됨다. 그리고 y = 1일때의 video RAM의 address는 0x20가 얻어 짐다. 이것은 가로가 256 pixel로 구성된 LCD를 기준으로 했기 때문에 256 / 8 = 32 = 0x20이 되기 때문임다. y 값이 1 증가시 마다 RAM의 address는 0x20씩 증가 함다. 그리고 x값이 8의 배수로 address는 1씩 증가 함다. 8개의 pixel이 한 바이트의 address를 차지 하기 때문임다.
그러므로 x 값을 8로 나눈 값을 앞에서 얻어진 RAM의 address에 더해 줌다. 마지막으로 x를 8로 나눈 나머지값을 구함다. 이 나머지 연산에 의해 얻어진 값으로 테이블을 조회해서 원하는 pixel에 대한 16진값을 구함다. 만일 얻어진 값이 1이라면 0x80, 2라면 0x40 이라는 값을 얻어냄다. 앞에서 주어진 좌표에 의해 RAM의 address를 구하면 y x ( 256 / 8 ) + x / 8 = 1 x 32 + 1 / 8 = 32 = 0x20 가 얻어 짐다. 그리고 x를 8로 나눈 나머지를 구하면 x % 8 = 1 % 8 = 1 이 얻어 짐다. 위에서 구한 address에 의해 현재의 video RAM에 씌여진 값을 읽어 들임다. 그 값에 x % 8 에 의해 구해진 값에 의해 40H를 OR 시키면 원하는 위치에 pixel이 찍힘다. 이때 단순한 OR가 아니고 XOR를 시키게 되면 현재의 위치의 pixel이 반전 됨다.위의 함수를 추적 해 보기로 함다. x = 1, y = 1을 대입하면 RAM_address = y * XMAX / 8; 에 의해 32( 0x20 ) 가 얻어 지고 RAM_address += x / 8; 에 의해 32( 0x20 ) 가 얻어 짐다. resident = x % 8; 에 의해 1 이 얻어 짐다. current_data가 00H라 가정하고 method를 OR로 가정하면 실제 RAM_address에 쓰여지는 데이터는 x_mask[ resident ]; 에 의해 x_mask[ 1 ] = 0x40 이 됨다. 위의 함수는 산적이 그래픽 LCD를 가지고 있지 않은 관계로 시험은 해보지 못했슴다. 하지만 아랫쪽의 설명에 의해 수치로 검증 하였으므로 확실하게 구현 될것임다. 위와 같이 video RAM에 pixel을 표시하는 방법은 과거 8 bit apple 시절 부터 사용하는 방식임다. 산적은 8 bit apple 시절에 이처럼 그래픽을 구현해본 경험이 있슴다.
#define XMAX 256 /* 가로가 256 pixels */ #define YMAX 64 /* 세로가 64 pixels */ #define write_io( address, value ) ((( char *)0x010000 )[ address ] = value ) #define read_io( address ) ((( char *)0x010000 )[ address ] ) #define OR 1 #define XOR 2 void point_xy( int x, int y, int method ) { unsigned char x_mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; unsigned char current_data; int resident; int RAM_address; /* video RAM 영역을 초과 하는 값이 주어질때는 리턴한다. */ if( x < 0 || x > XMAX || y < 0 || y > YMAX ) return; RAM_address = y * XMAX / 8; RAM_address += x / 8; resident = x % 8; current_data = read_io( RAM_address ); /* 현재 video RAM의 값을 읽어 들임 */ if( method == OR ) write_io( RAM_address, current_data | x_mask[ resident ] ); else if( method == XOR ) wrtie_io( RAM_address, current_data ^ x_mask[ resident ] ); }
'Programming > 8051' 카테고리의 다른 글
8051( 중급 11부 - serial 통신 ) (0) | 2009.11.29 |
---|---|
8051( 중급 10부 - A/D ) (0) | 2009.11.29 |
8051( 중급 8부 - RS485 기타 serial data 다루기 ) (0) | 2009.11.29 |
8051( 중급 7부 - RS485 ) (0) | 2009.11.29 |
8051( 중급 6부 - RS485 ) (0) | 2009.11.29 |