Programming/8051

8051( 중급 9부 - Graphic LCD )

청솔1 2009. 11. 29. 15:27

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이 반전 됨다.

#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 ] );
	}
위의 함수를 추적 해 보기로 함다. 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 시절에 이처럼 그래픽을 구현해본 경험이 있슴다.
 
 

 

'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