요술고양이의 Digital Life




블로그에 내손으로 만드는 MP3라는 포스트에 나온 동영상을 보셨다면, 마이크로프로세서상에 테트리스를 동작하는 화면을 보셨을겁니다. (아래 동영상 후반)

 


그 때 테트리스를 만들고 나서, 정리하는 기분으로 가볍게 원리만 소개해 볼까하고 작성해놓은 카페 글을 블로그에 다시 한번 정리 해두려고 작성한 포스트입니다. 소스가 공개되어 있거나 특별한 무언가를 기대하신분은 실망하시겠지만.. 마이크로프로세서 상에 게임을 만들어 올려보고 싶다고 생각되시는 분은 한번 참고할만하지 않을까? 싶어서 내용을 작성하였습니다.


1. 테트리스 제작 동기

처음에는 테트리스를 마이크로프로세서 상에서 동작하도록 만들어 보고 싶었습니다. 일단 가장 간단하고 쉬운 룰을 갖고 있어서 프로세서에 포팅하는데 큰 무리가 없을 것 같았고, 개인적 공부가 되지 않을까? 싶어서 였지요.. 그래서 우선 인터넷 상에서  돌아다니는 소스를 참고하려고 했습니다. 그러나 윈도우 프로그래밍에 익숙치 않은 제가 해당 소스를 보자하니 간단할 것이라고 여긴 소스가 꽤나 복잡하게 보였고, 얼핏 보기엔 소형 마이크로 프로세서 용으로 적용하기엔 해당 소스들이 메모리를 낭비하는 경향이 있고 해서 공부하는 겸, 알고리즘 공부하는겸 아싸리 그냥 제가 테트리스 원리를 구현 해보았습니다.

그러므로 일반적으로 알려진 원리랑 다를 수도 있고 매우 단순합니다.
허나 프로그래밍에는 한가지 길만 있는 것은 아니니 너그럽게 봐주셨으면 좋겠습니다. ^^

2. 테트리스는?

테트리스 게임 박스 사진 - 출처 : 테트리스 컴퍼니 http://www.tetris.com

1984년 모스크바의 알렉시파지트노브에 의해 처음으로 개발된, 퍼즐 게임입니다. 게임 방식은 대부분 아리라 생각되는데 각기 다른 모양으로 붙어 있는 4개의 블럭을 차곡차곡 쌓아서 한 줄 이상을 채우면 없어지는 퍼즐형 게임으로 누구나 쉽게 할 수 있어 최근까지도 많은 사람들이 꾸준하게 즐기는 게임입니다.

 

 Alexey Pajitnov - 출처 : 테트리스 컴퍼니 http://www.tetris.com


2. 테트리스게임의 기본 사항

 테트리스를 제작하기에 앞서 간단하게 알아둘 기본 사항에 대하여 알아보겠습니다.

 # 테트리스의 보드

 

 

 < 닌텐도의 테트리스 DS >

  테트리스의 배경이 되는 보드입니다. 보통 테트리스의 보드 사이즈는 가로 10칸, 세로 20칸 정도 입니다. 물론 그것보다 더 큰 사이즈도 있고 작은 사이즈도 있지만 보드 자체가 너무 크면 한줄 없애는데 시간이 오래걸리기 때문에 사이즈 10 x 20가 테트리스의 적정수준으로 여겨져 10 x 20 사이즈를 기본으로 하기로 했습니다.

 # 테트리스의 블럭 모양(Shape)

< 테트리스의 블럭 모양 - 출처 : 네이버 포토 앨범(4004nari 님) >

 위 그림은 가장 기본적인 테트리스의 모양(shape) 입니다. 7가지 모양이 있고 특징이라고 하면 모두 4개의 작은 블록으로 구성되어 있다는 점 입니다. 테트리스 컴퍼니 홈페이지에 가니 이렇게 떨어지는 블럭 모양을 Tetriminos(falling blocks)라고 부르는 것 같습니다. 그러니 위의 패턴은 테트리미노스라고 총칭하고 각각 모양에 대한 특별한 이름은 없으므로 테트리스 컴퍼니 홈페이지에서 표현하는 알파벳 이름으로 부르도록 하겠습니다. 위 그림 순서상으로 O, I, S, Z, T, L, J 가 되겠습니다.

# 게임의 룰

 테트리스는 계속 꾸준히 리메이크되어 제작되어 왔기에 테트리스의 기본적인 룰 이외에 세세한 부분에서는 약간씩 차이를 보입니다. 테트리스에서 가장 기본적인 룰은 한줄을 맞추면 그 해당하는 줄이 삭제가 되는 것으로 어느 버젼을 막론하고 모두 동일합니다. 그러나 회전에 관련 된 부분에서 부터는 차이가 생기는데, 여러가지 테트리스를 하다 보면 블럭 회전을 한 방향으로 하는 것도 있고 양방향(왼쪽, 오른쪽) 모두 회전 가능한 버젼도 있습니다. 그리고 회전 시 주변에 벽이나 다른 블럭이 있으면 회전이 안되는 버젼도 있고 벽이나 블럭이 있더라도 반대 방향으로 밀리면서 강제로 회전하는 버젼도 있습니다. 그 외의 부분으로는 시간의 흐름에 따라 블럭이 떨어지는 속도가 빨라지는 룰이나 삭제한 라인수에 따라 블럭이 떨어지는 속도가 빨라지는 룰이 있습니다. 그리고 T스핀, 아이템의 존재 유무, 기본 패턴외에 다른 모양의 존재 유무등 다양한 게임의 룰이 존재합니다.

 물론 여기에서는 가장 쉽고 간편한 룰 몇가지만 설명할 생각입니다. ^^

3. 하드웨어 구성

하드웨어 구성은 자세한 것 까진 필요없는 것 같고 간단하게만 언급하고자 합니다.

가장 먼저 프로세서와 그래픽을 표현할 수 있는 GLCD 또는 TFT-LCD가 필요하고 특이한 테트리스 게임을 만들기 위해서 도트LED가 사용되기도 합니다.

 

사용자 입력은 터치스크린도 있고 제가 만든 것처럼 조이스틱도 가능하며, 가볍게 택트 스위치 정도만 사용해도 쉬울 것 입니다.

3. 테트리스 기본 알고리즘


 테트리스의 알고리즘은 크게 보자면 테트리미노스의 랜덤 생성, 낙하,  회전, 충돌 확인, 보드의 라인 체크 및 삭제 등이 있겠습니다. 최대한 이해가 쉽게 되도록 올려보겠습니다.

# 테트리미노스와 보드의 표현 방법

 테트리미노스와 보드의 표현 방법이라는 말이 어울릴지 모르겠지만.. 보통 테트리미노스와 보드를 표현하는데 보통은 배열변수를 많이 사용합니다. 요컨테 테트리미노스는 7가지 Shape와 4가지 방향에 대한 Pattern을 갖고 있고 하나의 패턴을 표현하기 위해 메모리 공간은 칸수로 보자면 최대 4 x 4 크기를 갖습니다. (I 모양 때문)

 

 그래서 위의 패턴들을 배열로 표현한다고 하면 O 모양을 표현한다고 할 시 아래와 같이 선언을 해주게 됩니다. 

 char tetriminos[7][4][4][4] = {
{
    { 1, 1, 0, 0 },                              <-- 얼추 네모 모양이 나오지요? ^^
    { 1, 1, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 }
},

... 생략 ...

게임 보드도 마찬가지로 배열로 마진을 두어 char game_board[12][21] 정도로 선언해줄 수 있겠습니다.

그러나 블록 모양은 const 형으로 선언을 해주면 롬 코드에 삽입이 되기 때문에 램에 대한 부하가 줄지만, 그래도 최대한 자원을 아끼어 램이나 롬이 적은 MCU에도 적용을 가능하게 하고자 일단은 최대한 다이어트를 시켜보기로 하겠습니다.

그렇기 위해서 제일 쉬운 방법은 배열을 쓰되, 바이트의 비트까지 활용을 하는 것입니다.
단, 하단의 방법으로는 단순히 모양만 결정할 수 있습니다. (블럭의 특정 부분에 아이템 등을 삽입한다던가는 불가능)

// 테트리미노스의 7가지 모양과 4가지 방향
 unsigned short tetriminos[7][4] = {

     {0x6600, 0x6600, 0x6600, 0x6600},       // O
     {0xF000, 0x4444, 0xF000, 0x4444}        // I
     {0x6C00, 0x8C40, 0x6C00, 0x8C40},    // S
     {0xC600, 0x4C80, 0xC600, 0x4C80},    // Z
     {0xE400, 0x8C80, 0x4E00, 0x4C40},    // T
     {0x2E00, 0xC440, 0xE800, 0x88C0},    // L
     {0x8E00, 0x44C0, 0xE200, 0xC880},    // J

}

위에 선언된 배열 중 O 모양을 (0x6600) 4비트씩 나누어 보면..

0
x
6      0 1 1 0
6      0 1 1 0
0      0 0 0 0
0      0 0 0 0

(맨 좌측은 0x6600 값을 세로로 쓴 것 입니다.)

위와 같이 모양을 만들어 낼 수 있습니다.  (참고로 위에 나오는 그림과 위치가 조금 다른데 O 모양의 경우 코드 상으로는 중간쯤에 위치 시켰습니다.) 

이보다 더 줄이는 방법은.. 배열로 가장 기본모양만 잡아놓고 삼각함수를 이용하여 해당 테트리미노드의 값을 회전시키는 방법입니다. 이는 연산이 필요하기 때문에 소형 마이크로 프로세서에 오히려 어울리지 않을 수 있지만 또 다른 하나의 방법이 될 수 있습니다.

 PIC18시리즈나 16비트급으로 진행하실 생각이 있는 분들은 롬과 램이 하위 모델에 비해 비교적 넉넉하므로 큰 배열 변수를 사용하여 배열 칸마다 개개별 설정(각기 다른 칼라 적용, 아이템 적용))을 해보시길 바랍니다. 

일단은 다이어트 된 배열 변수로 진행하겠습니다.

# 보드의 표현

그럼 블럭 모양을 다이어트 시켰다면 게임 보드 또한 2차 배열이 아닌 1차 배열 변수로 줄여보겠습니다.

unsigned short game_board[21];     // 16비트 크기를 갖는 변수

그리고 보드에 초기 값을 설정해줍니다.

 for ( i = 0; i < 20; i++ ) game_board[i] = 0xE007;   // 1110000000000111
 game_board[20] = 0xFFFF;                               // 1111111111111111


참고로 위와 같이 초기 값을 설정한 보드는 아래와 같이 벽과 바닥에는 1인 값을 갖게 됩니다.
게임 보드는 최상위가 0 최하위 바닥이 20이 되겠습니다.

00 :   1110000000000111
01 :   1110000000000111
02 :   1110000000000111
          .. 중간 생략 ..
18 :   1110000000000111
19 :   1110000000000111
20 :   1111111111111111

게임이 시작 되면 앞으로는 다음 처럼 진행이 될 것 입니다. 

00 :   1110000000000111
01 :   1110000100000111
02 :   1110000111000111
          .. 중간 생략 ..
18 :   1111100010000111
19 :   1111100111000111
20 :   1111111111111111


그럼 좀 더 참고하기 쉽도록 맵에 대한 벼열 변수 값을 실제로 그래픽으로 표현 해보겠습니다.


위 그림을 보면 노란색 내부 영역이 실제 게임에서 테트리미 노스가 움직이는 영역이 됩니다.
 
# 테트리미노스 생성

테트리미노스는 보드 최상단 중간에 생성하며, 테트리미노스는 다양한 값을 갖고 있습니다.

unsigned char shape;                  // 테트리미노스의 7가지 모양
unsigned char pattern;                 // 테트리미노스의 4가지 패턴
unsigned char cur_line;               // 테트리니노스의 현재 라인
unsigned char cur_col;                // 테트리니노스의 현재 칸 
unsigned short temp_line[4]          // 테트리미노스 라인 임시 저장소

(변수 이름은 작명에 대한 센스는 그냥 그려려니 하시길 ^^)

위의 변수선언은 간단하게 설정한 테트리미노스 관련 값 들입니다. 테트리스 게임을 제작 시 디스플레이 장치를 GLCD가 아닌 TFT-LCD로 진행하려면 색 정보정도 추가해주는 편이 좋구요.. 위에는 간단하게 설명하기 위해서 일반 변수로 선언을 해주었는데, 구조체로 선언하는 것이 훨씬 좋을 꺼라 고 봅니다. 

그럼 void NewTetriminos(void)라고 함수를 작성하여 새로운 블럭을 설정해보겠습니다.

먼저 생성 함수 이전 또는 생성 함수 자체내에서는 블럭 모양 값을 정해주어야 합니다.

예를 들면, 아래와 같습니다.

shape = TMR2 % 7;    // 단순한 블럭 랜덤 생성 (여기서 TMR2는 dsPIC33F256GP710 Timer2 레지스터 값 임)
pattern = 0;                // 패턴은 초기 패턴 값으로 설정

생성되는 블럭은 랜덤 관련 함수를 만들어 사용해주시는 편이 좋고.. 테트리스는 지속적으로 사용자 입력을 받기 때문에.. (회전, 강제 낙하, 좌, 우 이동) 위와 같이 단순하게 타이머로 계산해도 맨 처음을 제외하고눈 게임 도중 계속 일정한 패턴으로 블럭이 생길 확률은 적은 편 입니다.

그리고 일단은 현재 낙하되는 테트리미노스외에 다음으로 생성될 테트리미노스(Next Block)까진 고려하지 않겠습니다. (실제 동영상에는 적용되어 있습니다.)

다음으로는 shape 값에 해당하는 테트리미노스 모양을 4비트씩 추출해서 저장합니다.

temp_line[0] = (tetriminos[shape][pattern] & 0xF000) >> 6;
temp_line[1] = (tetriminos[shape][pattern] & 0x0F00) >> 2;
temp_line[2] = (tetriminos[shape][pattern] & 0x00F0) << 2;
temp_line[3] = (tetriminos[shape][pattern] & 0x000F) << 6;

보시면 시프트 연산을 같이 수행하는데, 이는 임시 라인 변수의 temp_line(16비트) 중간에 블럭 값을 추출하여 저장하기 위함입니다.

만약 T 모양 테트리미노스 값을 추출한다고 하면.. 다음과 같이 됩니다.

16bit      MSB 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00 LSB
temp_line[0] = 0   0   0   0   0   0   0   1   0   0   0   0   0   0   0   0 
temp_line[1] = 0   0   0   0   0   0   1   1   1    0   0   0   0   0   0 
temp_line[2] = 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 
temp_line[3] = 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  

연두색으로 하이라이트 된 부분은 보드의 벽이 있는 부분으로 절대 테트리스 모양이 상위 3비트와 하위 3비트 위치에 생성되거나 위치되지 않도록 조심합니다.

그리고 이 녀석은 보드와 최상단과 보드의 중간에 생겨야 하므로 

cur_line = 0;                 // 테트리미노스 현재 라인 (최상위 라인)
cur_col = 9;                // 테트리미노스의 현재 칸  (그림 상 붉은 색으로 하이라이트 된 부분이 위치할 곳)

현재 라인과 현재 칸을 위와 같이 초기화 해줍니다. 참고로 빨간색으로 하이라이트 된 것은 테트리미노스 위치의 기준점 입니다.

# 테트리미노스의 회전

회전은 특별할 것이 없습니다. 회전은 pattern 를 하나씩 증가 시키거나 감소시켜 해당 값을 추출해서 임시저장소에 넣어주면 됩니다.

pattern++;            // 패턴 값 증가

일단 한쪽 방향으로만 도는 것만 고려한다고 가정하면 

if(pattern == 4) pattern = 0;

배열의 포인터를 벗어나지 않도록 위와 같이 작업을 추가해주면 되겠지요? 다만 회전을 어느 위치에서(칸) 했는지 모르므로 일단 각 4비트를 제일 최하위로 시프트 한 후

temp_line[0] = ((tetriminos[shape][pattern] & 0xF000) >> 12) << (cur_col - 3);
temp_line[1] = ((tetriminos[shape][pattern] & 0x0F00) >> 8) << (cur_col - 3);
temp_line[2] = ((tetriminos[shape][pattern] & 0x00F0) >> 4) << (cur_col - 3);
temp_line[3] = ((tetriminos[shape][pattern] & 0x000F) << (cur_col - 3);

현재 커서만큼 재차 왼쪽으로 시프트해주면 됩니다. 현재 커서에서 3을 빼주는 것은 게임상 보드의 벽에 해당하는 3비트 값을 제하기 위해서 입니다. 위의 연산은 사용자에 따라 최적화 할 수 있으니 실제 코딩시에는 간결하게 작성해보시기 바랍니다. ^^

 # 테트리미노스의 이동

이동도 특별하게 해줄 것은 없고 cur_col은 왼쪽으로 이동하면 +1 해주고 오른쪽으로 이동하면 -1 해주고 temp_line 값을 그에 맞게 왼쪽, 오른쪽 시프트를 1씩 해주면 됩니다. 낙하의 경우는 단순히 cur_line을 증가시켜 주면 되는 것이지요..

좌우 이동의 경우 temp_line[i] <<= 1; 또는 temp_line[i] >>= 1;
낙하의 경우 cur_line++;

단, cur_line 값이 최소 2보다 커야하고 13보다 작은 3 ~ 12 사이의 값을 유지하도록 하는

즉, 벽에 해당하는 상위 3비트와 하위 3비트에 테트리미노스의 영역이 진입하지 않도록 유의해야 하는데. 

아직 설명하지 않았지만.. 그전에 충돌 확인을 먼저 하게 되므로 특별히 이동으로 인한 충돌 걱정 필요는 없습니다.

# 충돌 확인

충돌확인이 늦게 설명되었는데, 테트리미노스의 생성, 낙하, 회전, 이동은 모두 충돌 확인을 거친 이후 실행해야합니다.

예를 들어, 테트리미노스의 생성 시 만약 충돌이 감지되었다면 최상위에 어떠한 블럭이 있는 상태에서 블럭이 생성되는 것이므로 그것은 게임 오버를 뜻하게 되고 낙하 시 충돌이 감지되었다면 바닥이므로 그곳에 테트리미노스가 굳어버리게 되며, 이동 및 회전 중에 충돌이 감지되면 이동 또는 회전을 금지시키면 됩니다.

signed char Collision(void)
{

     if( ((game_board[cur_line] & temp_line[0]) != 0) | ((game_board[cur_line + 1] & temp[1]) != 0) |
      ((game_board[cur_line + 2] & temp[2]) != 0) | ((game_board[cur_line + 3] & temp[3]) != 0) )
        return -1;         // 충돌
     else

        return 0;  // 충돌 없음
}

충돌 감지는 어렵지 않습니다. 게임 보드 배열 변수의 현재 라인부터 4줄과 AND 연산을 하여 0이 나오는지 1이 나오는지
확인하면 되는 것 입니다.

예를 들어.. cur_line이 5이고 cur_col이 12에 T모양이 위치한 상태에서 왼쪽 이동을 누른다고 할 시

테트리미노스

16bit      MSB 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00 LSB
temp_line[0] = 0   0   0   0   1   0   0   0   0   0   0   0   0   0   0   0  
temp_line[1] = 0   0   0   1   1   1    0   0   0   0   0   0   0   0   0 
temp_line[2] = 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0 
temp_line[3] = 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0  

게임보드

16bit           MSB 15|14|13|12|11|10|09|08|07|06|05|04|03|02|01|00 LSB
game_board[5] =  1   1   1   0   0   0   0   0   0   0   0   0   0   1   1   1  
game_board[6] =  1   1   1   0   0   0   0   0   0   0   0   0   0   1   1   1  
game_board[7] =  1   1   1   0   0   0   0   0   0   0   0   0   0   1   1   1  
game_board[8] =  1   1   1   0   0   0   0   0   0   0   0   0   0   1   1   1  

일단은 temp_line 배열변수를 전부 왼쪽으로 1만큼 시프트 연산을 시킵니다. 다음 게임 보드와 AND 연산을 합니다. temp_line[1]과 game_board[6]의 AND 연산 시 0이 아니게 되므로 충돌이라고 반환하면 됩니다.

그렇게 때문에 생성, 낙하, 회전, 이동은 모두 아래와 같은 방식으로 루틴을 수행하면 됩니다.

1. cur_line 또는 cur_col, pattern 등을 증, 감 시켜 temp_line 값을 수정한다.

2. 충돌 검사를 시도한다. 
   만약 충돌이 아니면 해당 값을 그대로 적용시키고, 만약 충돌이라면 해당 값을 이전으로 되돌린다.



일단 가벼운 원리만 제공하고자 해서 썰렁하지만 여기 까지 입니다. -_-;

항상 제가 쓴 글치고 용두사미가 아닌 글이 없을정도로.. 제 스스로도 수정하면서 다시 보니 허전~~ 하네요~

그리고 천천히 다시 살펴보니 제 스스로도 무식하게 코딩을 했구나 또는 안해도 될 연산을 한게 아닌가 하는 부분이 눈에 보입니다. 차후에 기회가 되면 천천히 다시 제작하면서 제대로 된 원리와 제작 방법에 대해 남겨 보고자 합니다.


Comment +2

  • 헛~ 테트리스를 만드는 방법까지 올려 놓으셨군요. ;)
    처음에는 뭔가 싶어 호기심에 봤다가 깜짝 놀랐습니다. ㅎㅎ
    좋은 글 잘 보고 갑니다. ;)


이전 포스트에서는  FET(또는 TR)과 ADC를 이용하여 터치스크린을 쓰는 방법을 올렸는데
이번엔 TI社의 TSC2003라는 컨트롤러를 이용해서 사용하는 법에 대하여.. 아주 간략(?)하게 올려보겠습니다.

그럼 먼저 특징부터 살펴보겠습니다.

2.5V TO 5.25V OPERATION
◆ INTERNAL 2.5V REFERENCE
◆ DIRECT BATTERY MEASUREMENT(0.5V TO 6V)
◆ ON-CHIP TEMPERATURE MEASUREMENT
◆ TOUCH-PRESSURE MEASUREMENT
◆ I2C INTERFACE SUPPORTS:
◆ Standard, Fast, and High-Speed Modes
◆ AUTO POWER DOWN
◆ TSSOP-16 AND VFBGA-48 PACKAGES

 간단하게 살펴보면 2.5~5.25V 동작 범위를 가지며, 터치스크린의 좌표뿐만 아니라 온도, 배터리, 터치스크린의 압력까지 잴 수 있다고 하는군요! 그리고 I2C를 이용하여 통신을 할 수 있는 것을 알 수 있습니다.

그럼 TSC2003의 핀 다이어그램을 살펴보겠습니다. 패키지는 TSSOP-16으로 16핀 디바이스인데..
저는 점퍼선 날려서 힘들게 납땜하여 사용해보았는데 깔끔한? 마무리와 정신건강을 위해 변환 기판을 사용하시길 바랍니다.



[그림 1] TSC2003 핀 다이어그램



아래는 TSC2003 레퍼런스 회로도 입니다.


[그림 2] TSC2003 레퍼런스 회로도



 TSC2003은 위 레퍼런스 회로도 구성으로 동작이 잘 되는데, 만약 위의 회로도와 같은 저항이 없을 경우.. 대체용으로 I2C 핀에는 10 ~ 20k 정도면 될 것 같고.. /PENIRQ 핀의 경우는 데이터시트를 참고하면 30K~100K 범위에서 선택을 하도록 되어있습니다.

 휴대용 기기가 아니거나 배터리 측정을 하지 않을 것이라면.. 전원핀을 제외하고 터치스크린과 연결하기 위한 X+, X-, Y+, Y- 핀과 I2C 통신용 SCL, SDA 핀과 /PENIRQ핀 정도 사용하면 됩니다. (여기서 /PENIRQ는 PEN INTERRUPT 핀으로.. 터치스크린이 눌렸을 때 0으로 떨어집니다.)

 만약 한 I2C 버스 라인에 1개 이상 같이 연결할 경우는 A0, A1 핀을 이용합니다. 그렇기 때문에 한 버스라인에 총 4개를 연결 할 수 있겠습니다.
 
데이터시트에는 위 컨트롤러의 동작 및 원리가 체계적으로 잘 정리 되어있으나 간략(?)한 설명을 위해 모두 생략하고 바로 본론으로 들어가보겠습니다.

 앞서 좌표 이외에 온도, 압력등 많은 요소를 부가적으로 측정할 수 있다고 했는데.. 이 모든 것이 ADC를 멀티플렉스로 바꾸어 가며 측정을 하는 것입니다. 좌표 값 또한 ADC를 사용하며.. I2C 통신으로 컨트롤 바이트를 보내주면 해당 값에 따라 ADC가 측정할 핀을 선택하게 되고 그 선택 된 핀의 값을 돌려주게 됩니다.

 그럼 I2C 통신을 하기 위해서.. 컨트롤 바이트나 해당 어드레스 주소를 살펴보겠습니다.
I2C 통신에 대해 잘 모르시는 분은..  참고 : http://cafe.naver.com/micropic/116 (회원가입 필요)

 먼저 어드레스 바이트입니다. 어드레스 바이트는 컨트롤러나 디바이스를 선택하기 위한 데이터로 SPI에서는 /CS(칩 셀렉트)핀을 주로 사용한다면.. I2C에서는 어드레스 바이트를 통하여 해당 컨트롤러나 디바이스 선택을 하게 됩니다. I2C에서 보통 주소크기는 7비트나 10비트 이며, TSC2003은 7비트 체계를 사용합니다.
 아래 그림과 같이 0번 비트는 읽기/쓰기를 선택하기 위한 비트로써 사용되고 있습니다.


[그림 3] TSC2003 어드레스 바이트


TSC2003의 경우는 어드레스 바이트에서 상위 4비트는 1001로 고정되어 있고, 위에 회로도에서 언급했던 A1과 A0핀 연결에 따라 하위 비트들은 가변적이 되겠습니다. 그리고 앞서 언급했던 0번째 비트는 해당 디바이스에서 읽기 작없을 할 것 인지 쓰기 작업을 할 것인지에 따라 값을 바꾸어주며 일반적으로 '1'은 읽기 '0'은 쓰기가 되겠습니다.

 그래서 I2C 버스라인에.. 1개의 TSC2003을 사용하고 읽기를 한다고할 경우 0x91(0b10010001) 값을 보내면 됩니다. 

다음은 어드레스 바이트에 이어 컨트롤 또는 커맨드 바이트 입니다. 커맨드 바이트는 보통 읽어올 데이터 위치나 레지스터를 선택하는데 많이 쓰입니다. TSC2003 커맨드 바이트는 아래와 같은 형식을 갖고 있습니다.


[그림 4] TSC2003 커맨드 바이트


• C3 - C0 : Configuration bits로 멀티플렉스로 ADC 값을 읽어올 부분을 선택합니다.


[그림 5] C3 - C0 커맨드 테이블



• PD1-PD0 : Power-down bits로 파워 관련 제어 및 /PENIRQ, Internal reference, ADC를 ON, OFF 할 수 있으며, 설정은 아래와 같습니다.


[그림 6] Power-Down 모드 테이블


PD1, PD0 = 0 으로 놓으면 lowest power mode라는데, 터치스크린이 쓸일이 없을 때는 해당 명령을 취해주시면 됩니다. 그리고 Internal reference는 ADC 비교전압의 기준을 2.5V로 삼는 것으로 외부 전압이 조금 불안정 하다면 또는 휴대용 기기에서 순간 또는 방전으로 인한 외부 전압강하가 있을 시 사용하는게 좋지 않을까 합니다.

ADC도 보면 ON, OFF를 할 수 있다고 하는데.. 실제적으로 OFF를하고 좌표 측정을 해도 측정이 잘(?) 되는데 데이터 시트에는 It is recommended to set PD0 = 0 in each command byte to get the lowest power consumption possible. 라고 명시되어 있어 배터리나 외부 아날로그 디바이스 측정을 위한 ADC를 꺼두는게 아닐까 합니다.

해석에 있어서 개인적으로 명쾌하질 못하기 때문에 이부분에 관하여서는 데이터시트를 참고하시길 바랍니다. 

• M : Mode bit. 비트로 0일 경우는 12비트 1일 경우는 8비트로 ADC가 설정이 됩니다.
• X : Don’t care.

 그럼 마지막으로 전체적인 통신 다이어그램을 보고 끝마치겠습니다.


[그림 7] TSC2003 통신 다이어그램


# 참고문헌
[1] 데이터 시트 : http://focus.ti.com/lit/ds/symlink/tsc2003.pdf
[2] TSC2003 제품 페이지 : http://focus.ti.com/docs/prod/folders/print/tsc2003.html






1

  • 감사합니다 2014.01.11 02:59 신고

    데이터시트를 봐도 회로가 잘 안들어왔는데 풀어서 설명해주신 글로 이해가 쏙쏙 되네요. ^^

 
 터치스크린에는 여러 방식이 있습니다. 그 중 보통 값싸고 자주 쓰이는 터치스크린 방식은 저항막 방식입니다.
대부분 4선을 많이 쓰기 때문에 보통 4선 저항막 터치 스크린이라고 많이 불립니다.
 
 일반적으로 컨트롤 IC(TSC2003이나 ADS7846 또는 ADS7843)를 사용하면 간편하게 쓸 수 있지만.. 우리는 간단하게 ADC와 TR을 이용해보도록 하겠습니다. 회로는 지니의 LCD 갖구놀기의 dk_sentec(네이버 아이디)님께서 제공해주신 회로도를 바탕으로 원래는 C1815 자리에 N-채널 FET가 있었지만.. 저는 간편하게 흔히 구할 수 있는 범용 NPN, PNP TR로 구성해 보았습니다.
 
 그 대신 dk_sentec님께서 제공해주신 정보로는 FET대신 일반 TR사용시 ADC 입력값이 약 0.5V정도 작아진다고 하였습니다. 그로 인해  감도가 떨어질 수 있으니 유의 하시길 바랍니다.
 
 
 먼저 회로도 보시고 저항막 터치 스크린에 대해 간단히 설명드리겠습니다.



 위 그림은 제가 구성한 위에는 회로도 입니다. OrCAD Student 버젼으로 LCD도 비스무리 하게 그려봤습니다.
그리고 아래의 저항막 스크린에 대한 자료 및 그림은 마이크로소프트웨어 2006년 3월호에 연재 된 기사를 참고로 쓰고 그렸음을 먼저 밝힙니다. 

 4선 저항막 터치 스크린은 아래 첫 번째 그림과 같이 X(+), Y(+) 또는 XP, YP 그리고 X(-), Y(-) 또는 XM, YM 으로 4선의 핀으로 구성되어 있습니다. X 축과 Y축은 떨어져 있는 상태이며.. 만약 특정 영역에 압력을 가하게 될 경우 X축 저항과 Y축 저항은 맞닿게 되어.. 두 번째 그림과 같이.. 등가 회로가 형성됩니다.



이렇게 형성되기 위해서는 + 쪽에는 VCC를 - 쪽에는 GND를 연결해주며.. 중간에 눌린 위치로 전압이 흘러 들어 오면.. 이것을 ADC로 캐치하게 됩니다. 

# X 값과 Y 값을 가져오기 위해선 아래와 같은 절차를 다릅니다.

 그전에 맨위의 회로도를 보시면 X(+)에 해당하는 것을 X2 핀에 연결하고.. X(-)에 해당하는 것을 X1에 연결하였는데.. LCD에는 어느 핀이 X+ 인지 X-인지 나와있지 않아서 임의로 연결했습니다. 그러나 저항이기 때문에 방향성이 없기 때문에.. 큰 상관은 없으며.. 테스트 시 별다른 특이사항 없이 잘 동작함을 확인하였습니다.

혹시 잘 못 되었다면.. 단순히 연결을 바꾸어 주시면 됩니다.

 그럼  먼저 X 좌표 ADC 값을 얻기 위해서..

(1) X(+)(현재 X2 핀)에 VCC 전압을 인가합니다. 위의 회로도의 경우는 왼쪽의 X2에 VCC가 들어갈 수 있도록 맨 왼쪽의 PIN0을 LOW로 만들어 줍니다.

(2) X(-)(현재 X1 핀)의 경우에는 GND로 만들어 주기 위해 PIN2를 HIGH로 해줍니다. 그 다음엔 Y(+)(현재 Y2 핀, ADC Channel 1)에서 ADC를 읽습니다. 단, Y(-)(현재 Y1 핀)에는 아무것도 연결 하지 않습니다. 그렇기 때문에 PIN3은 LOW를 유지합니다.

 요렇게 하면 X 좌표 ADC 값을 얻게 되는 것이고.. Y좌표는 단순히 그 반대로 해주시면 됩니다.

그럼 간단히 소스로 설명을 드리자면..
PORTB의 하위 4비트를 X+, Y+, X-, Y- 로 설정하였고..
ADC는 PORTA의 0번 핀과 1번 핀을 각각 Channel 0과 Channel 1로 보았습니다.

먼저 포트B를 출력하여 X좌표를 얻을 수 있도록 합니다.

 # CCS-C 컴파일러

  portb = 0b00000110;      // xp = 0, yp = 1, xm = 1, ym = 0;
  set_adc_channel(1);    // X 좌표 값 ADC 채널 설정
  delay_ms(1);              // 채널 변환 시 간혹 값이 튀는 것을 위한 딜레이
  x = read_adc();           // 해당 ADC 채널에서 값을 읽어온다.

  portb = 0b00001001;      // xp = 1, yp = 0, xm = 0, ym = 1;
  set_adc_channel(0);    // Y 좌표 값 ADC 채널 설정
  delay_ms(1);              // 채널 변환 시 간혹 값이 튀는 것을 위한 딜레이
  y = read_adc();           // 해당 ADC 채널에서 값을 읽어온다.



1

1


연초부터 기나긴 포스트 릴레이를 하고 있는 요술고양이 입니다.
방문해주시는 분도 많고 격려해주시는 분도 많아...

취미전자 활성화를 위해..
네이버 블로그 -> 네이버 카페에서 진행했던 마이크로프로세서 기초 강좌를..

티스토리에서 다시 한번 포스팅합니다.
지난 포스팅을 그냥 스크랩해도 되겠지만 워낙 기간이 지난 포스트들의 내용이고
스스로 불만족스러운 부분을 계속 수정하여 작성하려고 합니다.

3번째 revision 강좌로써~
많은 분들이 전자에 관심을 갖고 정보를 나누었으면 좋겠습니다.

1. 강좌 취지

저는 본래 전자전공이 아니었습니다. C언어도 잘 못하는 어중이떠중이 컴퓨터공학도였을 뿐이었지요..
그런데 무슨 바람이 들었는지 모르겠지만 갑자기 군대 다녀오고 하드웨어가 하고 싶었습니다.

그래서 걍 하드웨어 공부하면서 흥미를 얻어 전과를 해버렸습니다. 하하
하지만 독학을 하다보니 그 어려움은 말로 못하더군요..

그래서 최소한 저와 같은 어려움을 겪는 학생에게 도움이 되고자..
그리고 이쪽과 전혀! 무관한 전공이지만 취미공작을 하고 싶으신 분들을 위해서..

최대한 쉽게 접근할 수 있도록 글을 작성하려고 합니다.

칭찬해주신 것 만큼 실력은 없지만! 요런 것이라도 나누는 정으로 블로그를 꾸려나갈까 합니다.

참고로 나 전자 좀 할줄 알고 마이크로프로세서 좀 만질줄 아신다 하시는 분은
요 강좌 카테고리에 그리 신경쓰지 않으셔도 됩니다.

강좌의 대부분은 저처럼 초보시절을 겪고계신 분들을 위한 포스트가 될 것 입니다.

2. 마이크로프로세서란 무엇인가?

여러분께 가장 먼저 알려드려야 하는 대목인 것 같습니다.
마이크로프로세서란 무엇인가?

여기서 프로세서의 아키텍쳐가 어떻고 내부 구조는 어떠하며, 동작 원리, 전압 특성 등을 나열하면..
골치만 아프겠지요~ 그래서 그런 이야기는 모두 싹 패스합니다.
지금 설명하는 저도 자신있게 설명하기 힘들고.. 이 글을 보실 분들에게도 이해만 안되는 글일 뿐입니다. 

그래도 간단하고 쉽게 이해를 해보도록 합니다!

자 그럼! 마이크로프로세서란 무엇일까요? 

마이크로가 주로 쓰이는 뜻 처럼 말 그대로 소형 프로세서입니다. TTL이나 CMOS IC들은 정해진 특성대로만 움직이는 데 비해.. 마이크로 프로세서는 프로세서 내에 프로그램을 주입해서 자신이 원하는 동작 특성을 구현 할 수 있습니다.

참고로 마이크로프로세서 내부에는 ROM, RAM 그리고 각종 컨트롤러가 내장되어 있기 때문에..
펌웨어라고 하는 프로그램을 작성하여 내부 ROM에 기입을 하면, 내부 RAM 사용하여 연산을 하고 명령어를 처리하여, 각 명령에 맞는 동작 특성을 보여주게 됩니다.

 우리가 쓰는 많은 전자제품에는 이러한 마이크로프로세서가 거의 다 들어가 있으며, 다양한 역할을 수행하는 만큼 정말 수많은 마이크로프로세서가 존재를 합니다. 이러한 마이크로프로세서를 제어하는 것은 매우 어렵고 복잡할 수 있으나 그 원리를 이해하면, 간단한 리모콘이라던가 무선자동차 같은 것도 개조하여 제어할 수도 있고, 밝기를 제어할 수 있는 조명, 디지털 시계, 게임 조이스틱, 무선 통신 등등 우리가 상상하는 대부분의 것들을 직접 제어하거나 또는 만들어 볼 수 있습니다.

저는 그 중 수많은 프로세서 중에서..

Microchip사의 PIC 시리즈 프로세서를 중심으로 여러분께 원리를 설명하고, 강좌를 이어가고자 합니다.
참고로 MCU의 동작은 대동소이하므로 어느 프로세서를 하나 습득하신다면 다른 프로세서를 사용하는 것에는 큰 차이가 없음을 밝힙니다. 

3. PIC 마이크로 프로세서는 무엇인가?

 이미 앞서 언급한 것 처럼 마이크로프로세서라는 것은 종류가 꽤 많이 있습니다. 우리가 쓰는 일반 PC도 인텔, AMD, VIA 등 각기 다른 종류의 CPU 제조업체가 있는 것 처럼 마이크로프로세서 또한 여러 회사마다 각기 다른 여러가지 프로세서를 제조하고 있습니다.

그 중 PIC는 Microchip사에서 제조하는 마이크로프로세서로서 PICxxxxxxxx 와 같은 이름으로 시작합니다.
PIC는 그 자체로도 종류가 많으며 간략하게 설명을 드리자면 다음과 같습니다.

PIC10 시리즈 - 극 소형 8비트 프로세서
PIC12 시리즈 - 베이스 8비트 프로세서 (일부 미드레인지)
PIC16 시리즈 - 미드레인지 8비트 프로세서 (일반적으로 많이 사용)
PIC18 시리즈 - 하이엔드 8비트 프로세서 (고급 성능 및 컨트롤러 내장)
PIC24 시리즈 - 16비트 프로세서
dsPIC30, 33 시리즈 - 16비트 dsp코어 내장 빠른 처리속도의 고급 프로세서
PIC32 시리즈 - MIPS 코어를 이용한 32비트 프로세서

기타 PIC14, PIC17도 있음(일부 제한적인 모델)

여기서 일단 모르는 용어는 가볍게 읽고 넘어가시거나..
궁금하시다면 인터넷에서 용어사전을 찾아보시면 될 것 같습니다. 

4. 8비트와 16비트, 32비트 그리고 MCU와 MPU

 보통 이런 프로세서를 처음 접하면 8비트 프로세서, MCU, MPU라는 말을 많이 접하게 됩니다. 먼저 MCU와 MPU는 Micro Controller Unit와 Micro Processor Unit의 약자로서 컨트롤 위주의 성향이 짙은가 연산 위주의 성향이 짙은가로 구분을 짓습니다. 여기서 언급하는 마이크로프로세서는 MCU라고 대부분이 인식을 하고 있기에 별다른 이유가 없다면 앞으로 마이크로 프로세서는 MCU라고 통칭하겠습니다.

그럼 8비트와 16비트, 32비트의 차이는?
 간단하게 한번의 명령어로 처리할 수 있는 처리단위 입니다.

좀 더 쉽게 풀어쓰자면..
8비트는 2진수로 11111111로서 10진수로는 0 ~ 255를 표현할 수 있습니다.
8비트 프로세서는 즉, 255를 넘는 수를 덧셈하거나 기타 연산을 할 때 한번의 명령어 사이클에 처리 가능하지 못하다는 말이됩니다. 그러나 16비트 프로세서는 65535까지 가능하므로 65535만 넘지 않는다면 그 이하의 수는 한번의 명령어 사이클에 처리가 가능하다는 의미가 됩니다.

5. 마이크로프로세서의 동작

먼저 간단하게 디지털 개념을 집고 넘어갑시다.
컴퓨터는 1과 0 밖에 몰라라는 말을 기억하시나요?

왜 컴퓨터는 2진수를 기본으로 사용할까요?
기본 디지털 개념은 간단합니다.

1 이면 전압이 인가되어 전류가 흐르고 0 이면 흐르지 않는다가 되고
논리로 참 아니면 거짓이 됩니다.

그럼 전압이란 것을 기준으로 논리 참(1)과 거짓(0)을 구분 짓겠습니다.

MCU의 동작 전압은 다양하지만.. 3.3V와 5V가 많이 사용됩니다.
그럼 여기서는 MCU 동작 전압을 5V라고 볼 때
전압이 인가되면 논리가 1이고 아니면 0이라고 했기 때문에..

여기에서 논리 로직은 5V 전압인가를 1로 보고 0V를 0이 됩니다. 

[그림 1] PIC16F84A 핀 다이어그램


자 위에는 16F84A라는 PIC의 한 종류이고 핀 배열을 나타낸 그림입니다.
핀 다리에 이것저것 많이 씌여 있는데 MCLR, VSS, VDD, OSC1/CLKIN, OSC2/CLKOUT 등은 차후에 설명하기로 하고 일단 RAx와 RBx를 봐주세요... 

위 PIC16F84A의 경우에는 실제적으로 우리는 RA0~4, RB0~7를 제어하거나 이용할 것입니다.

보통은 RA부분을 포트A(PORTA), RB부분을 포트B(PORTB)라고 합니다.
(보실 때 구분을 하기 쉽게 포트A는 분홍을 포트B엔 하늘색으로 표시하겠습니다.)

위 포트를 입출력(Input/Output)포트라고 부르거나 GPIO(General Purpose Input Output)포트라고 부릅니다.
입출력 포트라고 부르는 이유는 우리는 임의의 프로그램을 작성하여..
위의 I/O 핀을 입력이 가능한 핀(스위치나 센서를 연결할 때)으로 만들거나  출력이 가능한 핀(LED 불을 켜거나, 모터 등을 제어)으로 만들 수 가 있기 때문입니다.

일반적으로 입출력 핀은 어느 핀이던 상관없이 입출력을 사용자 임의대로 설정할 수 있습니다.

그럼 여기서 하나의 예를 들어보도록 하겠습니다.
(여기서 부터는 정신 바짝! 차리시고 천천히 음미하면서 읽으시길 바랍니다.)



[그림 2] 예시 구성도


 그럼 RA0 ~ 3에 우리는 스위치를 각각 연결했다고 봅시다.
그리고 만약 스위치가 눌리면 [그림 2]와 같이 전압원과 연결되어 5V의 전압이이 MCU로 흘러들어들어가게 될 것입니다. 
(위 그림은 예시를 위한 그림일뿐입니다.)

그리고 RB0~3에는 순서대로 빨강, 노랑, 녹색, 파랑색 불이 들어오는 LED 연결하여 회로구성을 했다고 가정해봅시다.
(참고로 RA4, RB4~7엔 아무것도 연결하지 않은 상태입니다.)

그리고 프로그램을 작성니다.

프로그램에서 먼저 RA0 ~ 3 부분은 스위치를 달았기 때문에 입력으로 설정하고..
RB0~3 부분은 출력으로 설정합니다.
 
그 다음에는 RA0핀을 조사하여 전압이 감지되면 RB0 핀에 전류(전압출력)가 흐르게 하고 다른 핀들도 RA1핀은 RB1핀에.. RA2핀은 RB2핀에.. RA3핀은 RB3핀에.. 위와 같이 매치가 되도록 프로그래밍을 합니다. 

그리고 프로그램을 모두 작성하면 컴파일 합니다.
문제없이 프로그래밍 되었다면 hex란 파일이 생성 될 것이고.. 우리는 이 hex 파일을 MCU 내부에 주입합니다.

참고!

프로그램 주입은 보통 프로그래머란 장비가 있습니다.. (직접 자작도 가능합니다.)
요즘 대부분의 MCU는 내부 롬이 플래시로 되어 있어.. 수만번 쓰기가 가능합니다.

 그렇게 프로그램 주입까지 완료가 되었으면, 동작을 위해서 전원을 켭니다. 그러면 RA0~3중 RA0핀에 연결된 버튼을 눌러봅니다. 그럼 RA0 핀은 전압이 인가되고 전류가 안흐르다가 흘렀으므로 논리적으로는 0에서 1로 값이 변했습니다.

마이크로 프로세서는 논리적으로 1이 되었음을 인지 합니다. 우리는 프로그램을 작성 시 스위치가 눌렀을 경우에 불이 켜지게 했으니.. RB0에 연결된 빨간 LED에 불이 들어 올 것 입니다.

간단하게 본다면 즉 RA0핀이 전압이 인가되어 변화(스위치가 눌렸음)가 생겼으니..
RB1의 핀에 전압 출력을 하여 전류가 흐르게 하여라 라고 명령한 것과 같게되는 겁니다.^^

MCU의 가장 간단한 사용법을 쉽게 생각해보면 RA0~4, RB0~7와 같은 입출력(I/O) 핀에 임의대로 어떻게 전압. 전류를 흐르게 하느냐 마느냐를 프로그래밍으로 제어하는거라고 생각하시면 되겠습니다.

이해가 되셨나요?
조금더 고급? 제어를 해본다면 RA0을 누르면 1초뒤에 불이 켜지고 꺼지게 한다던가..
RA1를 누르면 순차적으로 불이 켜지게 한다던가..
사용자 프로그래밍에 따라 얼마든지 제어를 할 수 있으며...
이런 기본적인 포트 제어를 통하여..
우리는 모든 전자 주변기기를 제어할 수 있게 되는 겁니다.

이번 포스트는 최대한 이해를 위한 포스트였는데..
제대로 설명을 했는지 모르겠습니다.
질문은 대부분 네이버 카페에서 해결하고 있으니, 모르는 부분은 카페에 질문을 해주시면 좋겠네요~

http://cafe.naver.com/micropic

그럼 이번 포스트는 여기까지 하겠습니다.
다음은 마프를 배우기 위해서 필요한 것들에 대해 살펴보도록 하겠습니다.

Comment +8

  • soulbeam 2009.01.02 06:10 신고

    좋은 블로그군요. 공학을 전공했던 한 사람으로서, 이런 좋은 글들이 전자/컴퓨터 공학쪽에 많이 학생들이 관심을 갖게 되는 계기가 되었으면 좋겠군요. 앞으로도 꾸준한 블로깅 부탁드립니다....

  • 저는 전산학과를 졸업했지만 모니터를 벗어 나는 프로그램에 대한 욕심으로 8051 / AVR을 독학하고 있답니다.
    회로 이론에 대해서 하나도 아는게 없다 보니 이래저래 힘드네요 ^^

  • 필링이 2009.10.12 09:37 신고

    저도 컴퓨터공학과에 재학중이지만 임베디드쪽에 대한 관심만 많았던차에 조금이나마 알아갈수있을꺼같아좋네요^^
    정말감사드려요^^

  • 와 감사합니다 재밌네요~ 마이크로 초짜인 저에게도 쏙쏙들어옵니다^-^

  • 김신현 2010.01.04 12:23 신고

    감사합니다~ ㅜ_ㅡ 컴공 전공 하다 이번에 기울기 센서를 사용하려고 하니 정보가 하나도 없어 막막했는데..

    감사합니다~!

  • 이승철 2011.01.21 10:52 신고

    올해 전자과 3학년올라가는데 정말 이해가잘되네요 감사합니다!

  • BlogIcon jsh 2016.11.16 15:48 신고

    고양이님 질문 드리고 싶은게 있어서요 ..


 스타터분들께서 시작할 때 항상 부딛히는 문제나 트러블을 보자면 대부분 비슷 비슷한 문제를 겪는 것 같습니다. 가장 먼저 겪는 문제는 이쪽 분야에 아는게 없거나 또는 어디서 부터 어떻게 시작을 해야할지 모른다는 것이지요.. 그래서 제가 주로 사용하고 제가 운영하는 카페에서 작성하였던 가이드를 블로그에 수정하여 옮겨보고자 하였습니다.

 Micrcochip社의 PIC 프로세서를 이제 막 접해서 사용하거나 스터디를 하실 분들을 위한 초심자 가이드 입니다.

1. Microchip PIC란?

[그림 1] picMicro 시리즈

 (1) PIC(Peripheral Interface Controller) 개요 

 PIC란? Microchip社에서 개발한 RISC 프로세서로 내부에 롬과 램 및 컨트롤러를 탑재한 단일 마이크로프로세서입니다. 참고로 이와 같은 프로세서를 총칭하여 MCU(마이크로 컨트롤러 유닛)이라고 많이 부르며, PIC는 크게 8비트, 16비트, 32비트 계열로 제품군이 형성되어 있습니다. 8비트는 PIC10, 12, 14, 16, 17, 18 시리즈가 있으며, 16비트는 PIC24H, PIC24F, dsPIC30F, dsPIC33F 시리즈가 있고 32비트는 최근에 나온 것으로 현재 PIC32MX 계열이 있습니다.

 특히 8비트 제품군에서는 PIC10, 12는 소형 베이스 라인 PIC16은 미드레인지 PIC18은 하이엔드로 나뉘고, 16비트 제품군에서는 일반 컨트롤용 PIC24 시리즈와 DSP코어가 내장된 dsPIC 시리즈가 있습니다. (PIC14, 17은 특수하게 나왔던 디바이스로 현재는 찾아보기 힘듭니다.)

 (2) PIC 프로세서의 성능 및 장, 단점

 PIC의 일반적인 처리속도는(크리스탈, 레조레이터 사용 경우) 8비트 계열이 1 ~ 12MIPS, 16비트 계열이 30 ~ 40MIPS
32비트 계열이 최대 80 MHz, 1.53 DMIPS/MHz를 갖고 있습니다. 여기서 DMIPS는 Dhrystone Million Instructions Per Second의 약자로서 드라이스톤이라는 것은 프로세서의 종합적인 벤치마킹 기준입니다. MIPS라는 것은 각 프로세스마다 명령어 사이클에 상대적인 것이라 절대적일 수 없지만 대체로 PIC는 평균 이상의 처리속도를 보여주고 있습니다. 그리고 PIC의 철학(?)이 무조건 고성능 지향이 아닌 상황에 맞는 처리 능력과 용량을 갖는 프로세서를 지향하다 보니 ROM과 RAM 용량은 수 바이트 ~ 수 십K 정도로 다양하게 분포하고 있습니다. 

 이러한 PIC의 다양한 제품군은 프로세서 선택에 있어 어플리케이션에 따른 선택권이 있고, 각각 프로세서들간 핀호환이나 기타 컨트롤러가 비교적 호환이 잘 되는 편이라서 마이그레이션이 용이한 장점이 있습니다. 그리고 다른 회사와 달리 딱 한번 프로그래밍이 가능한 C 타입 양산용 디바이스가 있습니다. 

 PIC 학생들이 공부하기에도 부담이 없는 편이고, 마이크로칩 본사 홈페이지에서 샘플 신청이 가능하니 샘플을 신청하여 스터디 및 테스트 할 수 있습니다.

(2) PIC 중에서 자주 접할 수 있는 디바이스

 PIC 프로세서는 비교적 보급?이 잘 된 ATMEL社의 AVR 처럼 왠만한 전자부품 사이트에서 팔지 않으므로 접하기 힘든 프로세서중 하나였으나 최근 전자부품 사이트에서 구입이 용이해졌습니다. 이 중 처음 시작하시는 분들이 자주 보았을 만한 디바이스로는 PIC12F675, PIC16F84(A), PIC16F877(A), PIC18F452 정도입니다. 위에 열겨한 디바이스의 공통점이라면 8비트 계열의 베이스, 미드레인지, 하이엔드 부분에서 평균적인 성능을 보이는 디바이스들 입니다. 다시 말하자면 General Purpose(일반적인 목적용 - 기본 디바이스)인 것이죠, 이 중 스타터 분들께는 최소 PIC16F877A 정도로 시작을 하시는 편이 좋습니다. 국내에선 책도 많이 발간된 PIC16F84A가 있긴 하지만 솔직히 너무 오래된 프로세서이고 기능이 적으므로(어느 정도 스터디하면 금새 밑천이 다 드러나는?) 시작은 PIC16F877A 부터 시작하시고 어느정도 익히셨으면 PIC18 시리즈 그 다음에 16비트 계열 순으로 접하시는 것이 도움이 될 것 같습니다. 그 이유는 상위로 갈 수록 같은 내부 컨트롤러라도 설정 및 개념이 조금씩 확장되기 때문입니다. 간단히 말해 PIC16, 18, dsPIC에서 SPI와 같은 동일한 컨트롤러를 내장하고 있더라도 상위 모델에선 하위 모델보다 세부설정이 가능합니다.

(3) 피해야 할 것들

 커뮤니티에서 간혹 PIC 시리즈 중에 PIC16F가 아닌 PIC16C 계열을 판매하거나 초보에게 좋은 디바이스라며 추천하는 사람이 있는데, 대부분 구형 프로세서가 많은 편이고 해당 C 타입은 OTP(one-time programmable)이라고 하여 딱 한번 밖에 프로그래밍이 가능한 디바이스이니 무턱대고 구입해서 낭패를 보지 마시길 바랍니다. 


2. 컴파일러와 개발 툴 및 개발 장비

2.1 개발환경 
 
(1) MPLAB IDE


[그림 2] MPLAB IDE 실행화면


 MPLAB IDE는 Microchip社에서 제공하는 무료 IDE 입니다. IDE란 통합 개발 환경(Intergrated Developement Environment)의 약자로 MPLAB IDE는 컴파일러가 아닌 코드 작성 및 컴파일을 도와주는 통합 개발 환경입니다. MPLAB IDE는 PIC 관련 컴파일러와 대부분 연동 사용 가능하며, 시뮬레이션 기능, 롬 및 램 사용량 확인, 상용 RTOS 및 시뮬레이션과 같은 서드 파티 툴과 연동을 통하여 다양한 기능을 수행할 수 있습니다. 단, MPLAB IDE를 사용하면서 주의할 점은 MPLAB IDE에서는 유니코드 관련 언어 지원이 미비하여, 윈도우 계정이 한글로 되어 있거나 프로젝프 파일 또는 경로에 한글이 있을 경우 정상 동작을 하지 않으니 꼭 유의하시어 윈도우즈 계정을 영문으로 사용하시길 바랍니다. MPLAB IDE에 자세한 기능 설명 및 다운로드는 아래 링크를 참고 하시길 바랍니다. 

관련 홈페이지:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469&part=SW007002 

간단한 사용 방법:
http://cafe.naver.com/micropic/59 (가입필요)


2.2 컴파일러 

(1) MPASM, MPASM30, MPASM32

  MPLAB IDE 설치 시 자동으로 설치되는 PIC용 어셈블리어 컴파일러입니다. 순서상으로 8비트, 16비트, 32비트용이며, 어셈블리어로 프로그램 작성 시 해당 디바이스에 맞게 컴파일러를 선택하시면 됩니다. 

(2) MPLAB C18, C30, C32

 Microchip社에서 제작한 PIC 전용 C언어 컴파일러 입니다. C18은 PIC18 시리즈 전용이며, C30은 16비트 계열, C32는 32비트 계열을 지원합니다. 이 컴파일러는 MPLAB IDE와 연동하며 사용하며, 보통 다른 컴파일러와 달리 링커 스크립트라고 하는 디바이스별 기본 설정이 되어있는 파일을 필요로 합니다.(C32는 제외) 그러므로 컴파일 시 MPLAB IDE 프로젝트에 꼭 포함시켜야 하며, 링커 스크립트 수정을 통하여 디바이스에 대한 컴파일러 설정을 변경해줄 수 있습니다. 위 컴파일러는 스튜던트 버젼이 무료로 제공되며, C18과 C30은 60일은 정품과 동일 그 이후는 옵티마이징 레벨이 떨어지는 버젼이며, C32는 코드 제한이 있는 무료 버전으로 제공되고 있습니다. 

관련 홈페이지:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=81

(3) CCS-C


[그림 3] CCS-C

 CCS社에서 제작한 C 컴파일러로 Microchip社에서 나온 컴파일러 외 양대산맥(?)중 하나 입니다. CCS-C는 PCB, PCM, PCH, PCD로 나누어 최근 출시된 32비트 계열을 제외한 대부분 PIC 디바이스를 지원합니다. 그 중 PCB는 8비트 계열 중 베이스라인을 지원하는 컴파일러로 PIC12, 16(일부)를 지원하며, 무료로 MPLAB IDE와 함께 제공되고 있습니다. CCS-C는 다른 컴파일러와는 달리 자체적으로 라이브러리를 제공하여, PIC 내부 컨트롤러를 쉽게 사용할 수 있으며, 어느 디바이스를 막론하고 동일한 라이브러리 함수 명령어로 내부 컨트롤러를 설정하고 제어 할 수 있다는 큰 장점이 있습니다. 이러한 특성으로 인해 결과물을 빠르게 작성할 수 있는 컴파일러이고 가격도 다른 컴파일러에 비해 저렴한 장점이 있습니다. 다만, 몇몇 버그성 오류로 인해 사용자 선호도가 약간 극과 극으로 나뉘는 경향이 있지만 빠른 업데이트를 보여주고 있습니다.

관련 홈페이지: http://ccsinfo.com

(4) HiTECH-C


[그림 4] HiTECH-C

 
 Hi Tech社에서 제작한 C 컴파일러로 CCS-C와 양대산맥에 있는 컴파일러입니다. PIC 전 시리즈 컴파일러를 제공하고 있고, 각각 계열별로 컴파일러가 나뉘어 있습니다. CCS-C처럼 특별한 기능이나 특징은 없지만 PIC 컴파일러 중 안정성이 뛰어난 편이라 많은 개발자들이 선호하는 컴파일러이기도 합니다. 마이크로칩에서 제공하는 예제 코드 중에서 HiTECH-C 코드도 많은 편인점을 고려할 때 마이크로칩사에서도 서드 파티 컴파일러중 가장 신뢰하는 컴파일러가 아닐까 생각이 듭니다. MPLAB C 시리즈와 HiTECH C는 비슷해서 코드도 일부만 수정하면 거의 호환이 잘 되는 편입니다.

관련 홈페이지:
http://www.htsoft.com


2.3 개발툴

(1) PICkit2 & 3, ICD2 & 3, Real ICE


[그림 5] Microchip社 개발툴


 Microchip社에서 제공하는 대표적인 PIC용 프로그래머 및 디버거로써 가장 일반적으로 많이 사용되는 툴입니다. 이 중 ICD2(또는 ICD3)가 가장 많이 사용되고 있으며, 모두 USB 인터페이스로 동작합니다. 위의 툴을 기능순으로 나열해보면 PICkit 시리즈 -> ICD 시리즈 -> Real ICE 순이며, 각각 특별하게 기능차이가 큰 것은 아니고 디버그의 능력 및 내부 롬 프로그래밍 속도 차이에 기인합니다. 예를 들어, ICD시리즈는 모든 디바이스 디버그가 가능하지만 Real ICE 보다 디버그 능력(하드웨어 브레이킹 포인트 갯수 등)이 떨어집니다. 스타터 분들께는 심플한 PICkit 시리즈 정도로 충분하며 최근에 업데이트로 32비트 디바이스도 지원하게 되었습니다. 일반적으로 PICkit나 ICD 정도면 새로운 디바이스가 나올 때 마다 내부 프로그램 등이 업데이트가 되기 때문에 향후 지속적으로 사용이 가능합니다.

(2) 공개 개발 프로그램 및 툴

 IC-Prog

 PIC 롬라이팅 프로그램으로 많이 사용되는 프로그램입니다. 특히 JDM 프로그래머와 함께 PIC16F84A, PIC16F877A 롬 프로그래밍에 많이 사용하는 프로그램이 아닐까 싶습니다. 단, 지원하는 디바이스가 PIC16 및 PIC18 일부 디바이스만 지원하며 처음 시작하시는 분들이 사용하기에 간편한 프로그램 입니다.

관련 홈페이지: http://www.ic-prog.com
사용방법: http://cafe.naver.com/micropic/5


WINPIC

 다양한 디바이스를 지원하는 PIC 롬라이팅 프로그램입니다. 그외 다양한 프로그래머를 지원하고 프로그래머에 관한 설정을 세세히 할 수 있기 때문에 공개 프로그램중 활용성이 높은 프로그램입니다.

관련 홈페이지: http://freenet-homepage.de/dl4yhf/winpicpr.html
사용방법: http://cafe.naver.com/micropic/150


PICer

 일본의 Y.Onodera라는 분이 제작한 프로그램 입니다. 패러럴 포트를 사용하며, 전용 프로그래머 회로도와 같이 공개한 프로그램 입니다. 비교적 많은 PIC 디바이스를 지원하며, 현재 USB 버젼으로 새로 개발 중인데 공개로 할 지 미공개(라이센스?)로 할 지 고민하시는 것 같습니다. 만약 USB 버젼을 공개로 내놓을 경우(하드웨어의 경우 FT232를 쓴 버젼입니다.) 16비트의 dsPIC까지 지원 예정이니 심플하고 성능이 훨씬 좋은 프로그램을 기대해봐야겠습니다.

관련 홈페이지: http://einst.hp.infoseek.co.jp
일어번역: http://j2k.naver.com/j2k_frame.php/korean/einst.hp.infoseek.co.jp/PICer/PICer4.html
사용방법: http://cafe.naver.com/micropic/6


PIC-PG1, PIC-PG2, PIC-PG3

 올리멕스社에서 공개한 프로그래머로 PIC-PG1의 경우 제가 아래 링크로 소개한적이 있습니다. 이중 PG1과 PG2는 시리얼 방식이고 PG3는 패러럴 방식으로 비교적 간단한 부품으로 롬라이터 기기를 제작해볼 수 있습니다. PICkit2나 ICD2의 구입이 어려우신분들은 아래의 홈페이지에서 해당 회로도를 참고하여 제작해보시길 바랍니다.

관련 홈페이지: http://www.olimex.com/dev/index.html
사용방법: http://cafe.naver.com/micropic/7


3. PIC 특징 및 사용상 유의할 점

(1) PIC 입출력 설정

 PIC의 포트 입출력은 TRISx 레지스터 설정을 통해 이루어 집니다. 입출력 설정이야 0 또는 1로 하니까 특별할 것은 없지만 요로코롬 설명하는 이유는 AVR 쓰시는 던 분들 때문인데, 입출력 설정이 AVR과는 반대이기 때문입니다. PIC에서는 포트 입출력 설정시 AVR과 반대로 0은 출력, 1은 입력 입니다. 쉽게 외우는(?) 방법은 '0'utput과 '1'nput이라고 외우는 것이지요~ 혼동하지 마시길 바랍니다.

(2) SPI 모듈 핀 설정

 PIC에서 SPI 모듈을 사용하기 위해선 해당 핀을 입출력 설정을 해줍니다. SDO(MSIO) 핀은 출력으로 SDI(MOSI)는 입력으로 먼저 설정을 해주어야 합니다. 그런데 또 요로코롬 설명하는 이유는 AVR과 SPI 핀의 연결방법이 다르기 때문입니다. 아래 그림을 일단 살펴보도록 합니다.


[그림 6] ATMEGA128 SPI 모듈



[그림 7] PIC dsPIC33FJ256GP710 SPI 모듈


 [그림 6, 7]에서 푸른색으로 칠한 부분을 잘 보시면, AVR은 같은 핀끼리 PIC는 크로스 연결을 한 것을 볼 수 있습니다. 이는 AVR에서는 SPI 설정 시 AVR MCU가 마스터냐 슬레이브냐에 따라 입출력 방향이 달라지기 때문이고, PIC는 마스터, 슬레이브에 관계없이 SDO(MISO)는 데이터 출력, SDI(MOSI)는 데이터 입력으로만 동작 되기 때문입니다. 기존 AVR 사용자 분들 께서는 혼동하지 마시고 데이터 시트를 꼭 확인하시길 바랍니다.

4. 트러블 슈팅 가이드 및 FAQ

(1) 프로그램 및 컴파일러 관련

Q. MPLAB IDE를 실행하면 로고만 뜨고 바로 꺼져 버립니다.

A. MPLAB IDE는 한글을 제대로 지원하지 않습니다. XP 사용자 계정이 한글일 경우 실행이 안되는 경우가 있습니다. XP 계정을 영문으로 수정해주세요.

Q. MPLAB IDE에서 파일을 찾을 수 없다고 나오면서 컴파일이 되지 않습니다.

A. MPLAB IDE에서는 한글을 제대로 지원하지 않습니다. 프로젝트 및 소스 파일이 한글이거나 또는 경로에 한글이 들어가 있으면 안됩니다. 영문으로 변경해주세요. 예) c:\프로젝트\test.mcp (x)

Q. MPLAB IDE에서 C18 또는 C30, C32의 라이브러리 및 인클루드 헤더 파일을 찾을 수 없다고 나오면서 컴파일이 되지 않습니다.

A. C18 또는 C30, C32의 설치 경로를 먼저 확인해주시고, 메뉴 - Project - Set Language Tool Location을 선택하여 해당 컴파일러의 위치나 라이브러리 디렉토리 위치를 수동으로 설정해주세요.

Q. MPLAB IDE에서 C18 또는 C30 컴파일러의 위치를 설정해주었는데, 라이브러리를 찾을 수 없다고 나오면서 컴파일이 되지 않습니다.

A. MPLAB C에서는 특별하게 링커스크립트라는 파일이 필요합니다. 해당 컴파일러의 설치 폴더에서 lnk 또는 gld 라는 확장자를 가진 파일이 있습니다. 해당 디바이스와 동일한 이름을 갖고 있는 파일을 프로젝트에 추가시켜주세요.

Q. C18에서 큰 용량의 배열 변수를 선언할 수 없습니다. 어떻게 해야하나요?

A. 이럴경우엔 링커스크립트를 수정해주어야 합니다. 만약을 위해서 링커스크립트를 프로젝트 폴더에 복사해서 프로젝트에 추가하여 사용하시길 바라구요 아래와 같이 변경해주시면 해당 크기 만큼 배열 변수를 선언할 수 있습니다.

예) PIC18F4550

#pragma
udata bigdata
u08 buffer[512];
#pragma udata

먼저 buffer[512]와 같이 대용량 변수 취급 시 필요한 작업으로 먼저 #pragma udata bigdata 같이 섹션을 만들어 줍니다.
여기서 udata 정의되지 않은 램데이터를 뜻하고 bigdata는 임의로 정한 이름입니다.

<변경 전 PIC18F4550 링커스크립트>

// File: 18f4550.lkr
// Sample linker script for the PIC18F4550 processor

LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f4550.lib

CODEPAGE   NAME=vectors    START=0x0            END=0x29           PROTECTED
CODEPAGE   NAME=page       START=0x2A           END=0x7FFF
CODEPAGE   NAME=idlocs     START=0x200000       END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000       END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE       END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000       END=0xF000FF       PROTECTED
ACCESSBANK NAME=accessram  START=0x0            END=0x5F

DATABANK   NAME=gpr0       START=0x60           END=0xFF
DATABANK   NAME=gpr1       START=0x100          END=0x1FF
DATABANK   NAME=gpr2       START=0x200          END=0x2FF

DATABANK   NAME=gpr3       START=0x300          END=0x3FF
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED
SECTION    NAME=CONFIG     ROM=config
STACK SIZE=0x100 RAM=gpr3

 변경전 내용입니다. 위에서 gpr1, gpr2 영역을 합치면 512바이트 크기나 나오므로 합쳐서 큰 램 영역으로 선언을 해주도록 하겠습니다. 

<변경 후 PIC18F4550 링커스크립트>

// $Id: 18f4550.lkr,v 1.3 2004/08/23 18:08:22 curtiss Exp $
// File: 18f4550.lkr
// Sample linker script for the PIC18F4550 processor

LIBPATH .
FILES c018i.o
FILES clib.lib
FILES p18f4550.lib

CODEPAGE   NAME=vectors    START=0x0            END=0x29           PROTECTED
CODEPAGE   NAME=page       START=0x2A           END=0x7FFF
CODEPAGE   NAME=idlocs     START=0x200000       END=0x200007       PROTECTED
CODEPAGE   NAME=config     START=0x300000       END=0x30000D       PROTECTED
CODEPAGE   NAME=devid      START=0x3FFFFE       END=0x3FFFFF       PROTECTED
CODEPAGE   NAME=eedata     START=0xF00000       END=0xF000FF       PROTECTED
ACCESSBANK NAME=accessram  START=0x0            END=0x5F

DATABANK   NAME=gpr0         START=0x60           END=0xFF
DATABANK   NAME=largebank       START=0x100          END=0x2FF  PROTECTED
DATABANK   NAME=gpr3       START=0x300          END=0x3FF
DATABANK   NAME=usb4       START=0x400          END=0x4FF          PROTECTED
DATABANK   NAME=usb5       START=0x500          END=0x5FF          PROTECTED
DATABANK   NAME=usb6       START=0x600          END=0x6FF          PROTECTED
DATABANK   NAME=usb7       START=0x700          END=0x7FF          PROTECTED
ACCESSBANK NAME=accesssfr  START=0xF60          END=0xFFF          PROTECTED
SECTION    NAME=CONFIG     ROM=config
SECTION NAME=bigdata RAM=largebank
STACK SIZE=0x100 RAM=gpr3

 위처럼 gpr1과 gpr2 영역을 하나로 합쳐서..
largebank라는 임의의 이름을 지어주고 큰 영역으로 만듭니다. 그리고 하단에 섹션을 아까 변수 선언 시 임의로 정했던 bigdata로 설정해줍니다. 그러면 buffer 변수는 앞으로 위에 largebank로 설정 된 램 영역에 위치하게 됩니다. 

(2) 개발 툴 관련

Q. ICD2 사용 시 ICD0019: Communications:  Failed to open port: (Windows::GetLastError() = 0x0, '작업을 완료했습니다.')라는 메세지가 나오면서 동작 하질 않습니다.

A. 위의 메세지는 ICD2를 사용하는 USB 포트를 중복 접속할 때 생기는 오류로 간단하게 해볼 수 있는 방법으로는 프로그래머를 none으로 놓고 ICD2를 연결 해제한 후 다시 연결하고 ICD2를 선택하여 정상동작하는지 확인 하는 방법입니다. 자세한 사항은 아래 링크를 참고해주세요. http://cafe.naver.com/micropic/247

Q. PICkit2를 사용하는데 MPLAB IDE에서 컴파일 후 프로그래밍 하면 디바이스가 동작이 잘 되는데, PICkit2 전용 프로그램으로 hex 파일을 라이팅 하면 디바이스가 정상동작 하지 않습니다.

A. hex 파일에 건피그레이션 비트 설정이 포함되지 않아서 hex 파일만 라이팅 하면 정상 동작하지 않는 것입니다. 그러나 MPLAB IDE에서 라이팅 시에는 정상 동작하는 이유는 MPLAB IDE에서 라이팅을 하게 되면 컨피그레이션 비트 설정을 포함하여 롬 라이팅을 시도하기 때문입니다. 이럴 때는 일단 먼저 컴파일 후 메뉴 - File - Export.. 를 선택하여 컨피그레이션 비트 내용을 포함하여 hex 파일을 내보내기를 하고 PICkit2 전용 프로그램으로 그 내보낸 hex 파일을 라이팅하면 정상 동작 될 것 입니다.

(3) 하드웨어 관련
(4) 기타



< Revision >

2008.12.27 이전 - PIC32 추가, ICD3, Pickit3 내용 추가
2008.12.27 DMIPS 내용 수정 및 추가
2009.01.16 전반적인 내용 수정 및 추가

Comment +4


PIC16 시리즈 RB 인터럽트 시 각각의 버튼 인식

  RB 인터럽트의 경우 input 또는 output 상으로 PORTB의 RB4 - RB7 포트에 변화가 있을경우 발생을 한다. EXT 인터럽트와 달리 상승엣지 하강엣지 설정이 없어서 4개의 핀중 어느것 하나라도 0에서 1로 변하던 1에서 0으로 변하던 무조건 인터럽트가 발생한다. 그러하므로 RB4 - RB7 핀에 각각 버튼 또는 신호선을 하나씩 부여하고 인터럽트 사용하는 경우에 어떤 핀이던 값이 변하면 무조건 RB 인터럽트 상태로 진입 하기 때문에 독립적으로 사용할 경우 아래와 같이 따르면 된다.

<컴파일러 : CCS-C 기준 >

버튼은 풀업 저항으로 연결된 버튼이고 버튼이 눌렸을 때는 LOW가 된다고 가정..

#byte portb = 0x06;
 int sw;

 #int_rb
rb_isr() {

    sw = portb & 0xf0;        // 상위니블만 사용하기 위함.

    switch (sw){
         case 0xE0:      // B4핀에 연결된 버튼이 눌린경우  (상위니블 값 1110)
                           // .. 필요한 수행 루틴 구문..
                break;
         case 0xD0:      // B5핀에 연결된 버튼이 눌린경우  (상위니블 값 1101)
                            // .. 필요한 수행 루틴 구문..
                 break;
         case 0xB0:      // B6핀에 연결된 버튼이 눌린경우  (상위니블 값 1011)
                            // .. 필요한 수행 루틴 구문..
                 break;
         case 0x70:      // B7핀에 연결된 버튼이 눌린경우  (상위니블 값 0111)
                            //.. 필요한 수행 루틴 구문..
                 break;
    }

    delay_ms (100);    //채터링 방지

}

 먼저 0xf0과 AND 연산을 하여 portb의 상위니블 값만 읽어들인다. 그 후 switch 문으로 어느 버튼이 눌렸는지 값으로 검출해서 그 구문만 수행한다. 이 것은 특정 구문만 수행할 때 좋고.. 두 개 이상 버튼을 같이 눌렀을 때에 대한 루틴을 추가하고 싶을 땐 case 값만 추가해서 설정해 줄 수 있다.

 마지막으로 딜레이를 100ms를 주는 이유는 버튼을 눌렀다 땠을 때도 순간 짧은 시간에 인터럽트가 두 번이상 걸리지 않도록 일종의 팁과 같은 것이다. 그리고 일종의 채터링 방지를 위한 방법으로도 쓰인다.

Comment +0


약 2주전 대전에 V.O.S 공연이 있었습니다.



평소 V.O.S를 너무 너무 좋아하는 친구가 저에게 질문을 하더군요..

애들이 LED 반짝반짝 빛나는 플랜카드를 가지고 다니는데 어떻게 만드는지 아냐고?

LED 플랜카드 이야기는 처음 들어보는지라..
인터넷을 찾아 LED 플랜카드의 실체를 찾아보았습니다.




아하 이런 것이었군요! 대충 무엇인지 감을 잡았습니다.

보통 우리가 아는 플랜카드는 검은 바탕에 이쁜 글씨를 써서 스타를 응원?하는 도구인데 
요것을 LED로 개량한 플랜카드가 바로 LED 플랜카드 였습니다.

자료를 찾다보니 많은 소녀팬들이 갈망하는 원츄!! 아이템(?) 이더군요~
그런데 이게 제작하는게 쉽지도 않고, 저항 계산법이랑 납땜질을 해야하기 때문에..
많은 소녀팬들은 대신 제작해주는 대행업체나 개인에게 나름 거금?의 돈을 주고 만드는 것 같더랍니다.

대행업체에 맡기기엔 돈은 많이 들 것 같아.. 어떻게 만드는지 가르쳐달라는 친구에게..
친구에게 설명하는 것보다는 내가 직접 만드는게 더 빠르겠다 싶어서

그래서 간만에 좋은일? 한다고 생각을 하고.. 내가 플랜카드를 만들어 주겠다고 약속을 했습니다.

그래서 처음으로 LED 플랜카드라는 것을 만들어 보게 되었습니다.

먼저 친구가 요구한 것은 대충 A4 정도의 크기에 용규(?)라는 이름과 함께..
스페이드 A 카드 모양이면 좋겠다고 하더군요~

알고보니 V.O.S의 박지헌씨의 본명이 박용규라서.. 용규라는 이름을 해달라고 한 것이었습니다.
그리고 A는 박지헌씨가 소심?하다고 하여.. 소심한 A형을을 뜻하도록 A자를 꼭 넣어달라고 했습니다.

(허나 박지헌씨 본인은 공연날 에이스라는 뜻으로 보지는 않았을까? -_- 합니다.. ㅎㅎ)

먼저 제작에 앞서 도안 및 소재를 생각해보았습니다.

처음 만들어 보는지라.. 만능 PCB를 이용해야 하나 아크릴이나 MDF 등을 이용해야하나 고민이 많았지요?
대부분은 아크릴이나 우드락?, MDF 등을 활용해서 더덕더덕 땜질을 하는 것 같더라구요..
뭐 어차피 뒷부분은 안보일테디 크게 신경쓰지 않아도 되겠지요..

고민 끝내 작업은 만능 PCB가 편하지만 구멍이 그대로 보이고, 가격도 비싸고 모양도 안날 것 같아..
마침 자투리 검은색 아크릴을 구해서 이 녀석을 베이스로 하고..

고휘도 LED를 사용하여 만들기로 하였습니다.

그렇게 결정을 하고 도안을 작성하였습니다.



위 사진처럼 약 2가지 도안을 만들었는데.. 제 개인적으로는 하트가 맘에 들었지만..
친구는 스페이드 A를 요구했기 때문에..

스페이드 A를 도안으로 삼고 작업을 시작하였습니다.

아크릴 크기가 A4보다는 약간 큰 아크릴이었기 때문에 도안을 아크릴 실물에 맞게 출력을 해서..
아크릴 위해 붙여놓고 구멍을 뚫었습니다.

참고로 LED를 5파이 짜리를 사용했기 때문에 드릴도 5파이를 사용하여 구멍을 아래와 같이 냈습니다.





뚫는데 생각보다 무지 힘들더군요.. 이왕이면 이쁜 곡선으로 뚫고 싶었는데.. 도안 곧이곧대로 뚫다보니..
공대생이 만든 티가 납니다 -_-;

다음은 LED를 박고 땜질을 했습니다.
(뒷면을 보여드리고 싶으나~ 찍어놓은게 없네요 ~~)




짜잔!

LED 땜질을 하고 불을 켜니 정말 눈이 부십니다!
얼마나 빛이 강한지.. 핸드폰 사진기의 렌즈에 용규라는 글씨가 반사되어 찍혀있네요..

요러코롬 완성하였는데..

스페이드가 불도 안들어온 것이 허전하지 않습니까?
그래서 마이크로프로세서와 쉬프트레지스터를 이용하여 이렇게 만들었습니다.



핸드폰으로 전송해준다고 낮은 해상도로 촬영했더니..
화질이 안습이군요~

여튼 친구는 남들의 부러운(?) 시선을 받으면서..
즐거운 공연을 즐겼다고 합니다!





LED 플랜카드 자작기~ 끝!



 

'Hardware' 카테고리의 다른 글

LED 플랜 카드 제작기  (7) 2009.01.02

Comment +7

  • 기계과 2009.01.02 17:10 신고

    안녕하세요 ^^~ mp3 포스팅 보고 찾아오게 되었습니다.. 저 역시 요술고양이님 처럼... 전자전공은 아니고
    기계과에서 공부를 하고 있습니다.. 하지만 제가 요즘 정말 하고 싶은건 전자공부라서.. 그쪽으로 한번 도전을 해보고 싶은데요.... 사실 제가 아는 전자라고는... 직류나 교류 간단한 부분 배운 정도 밖엔 없습니다... 그야말로 초보중에 생초보지요... c언어는 나름대로 공부를 해오고 있어서... 이제막 시작하는 초보정도 신세만 겨우 면하는 정도구요..... 다름이아니라.. 저 역시 전자 공부를 하고는 싶은데... 어디서부터 시작해야할지 전혀 감이 안잡힙니다... 카페에 들어가봐도.. 제가 알아듣기에는 너무 어려운 내용들만 있구요... MCU에 관한 내용을 공부하기 전에 전자에 대해서 중급 정도의 수준까지는 실력을 쌓고 싶은데요... 거의 아무것도 모르는 초보자가 간단한 제품들의 회로기판 같은 걸 대강 알아볼수 있는 실력이 될수 있을 정도 수준으로 공부를 하려면 어떤 교재들로 공부를 시작하면 좋을까요..?
    공부는 하고 싶은데 ... 너무 막막하고... 볼만한 교재들 몇권만 추천해주셔도 될까요?^^;;;;
    추천해주신다면 앞으로 공부해나가는데 크게 도움이 될것 같아요.. 그리고 올리시는 포스팅들은 관심있게 잘 보고 있습니다~ 좋은 내용 많이 올려주셔서 정말로 감사드립니다~ ^^

    • 전자기초책이랑 디지털공학 책부터 한번 슬슬 읽어보시는게 어떨까? 싶습니다.

      아래는 기초전자 공학책 입니다.
      http://www.yes24.com/Goods/FTGoodsView.aspx?goodsNo=2123317&CategoryNumber=001001002008

  • 기계과 2009.01.02 17:40 신고

    도움주셔서 감사합니다 ^^~ 그런데 링크가 잘못 걸려있어요..^^;;;;

  • 기계과 2009.01.02 17:45 신고

    아... 찾아보니깐 어떤책인지 알것 같네요 ^^~ Floyd 책이군요.. 감사합니다 ^^~ 열심히 공부해봐야겠네요

    • 수정했습니다. 이유는모르겠지만.. 뒤에 aspx뒤에 숫자 1이 더붙었네요.. 디지털공학도 한번쯤은 꼭 보시길 바라고.. 나중에 여유나 지식이 쌓이면 컴퓨터구조까지 보시면 마프시작하기전 기초는 어느정도 다 띄시는 겁니다 ^^

  • 키키 2009.02.20 01:07 신고

    안녕하세요? 제가 led 플랜카드 만들고 싶어서 이것 처것 찾아보다가 여기까지 오게됐네요..
    led플랜카드 만드는거에 대해 제가 궁금한게 있어서 그러는데...
    뭐 쫌 여쭤봐도 될까요? ㅎㅎ
    우선,, led 플랜카드는 일반인도 만들수 있나요??
    그리구 만드는데 비용과 시간은 어느정도 걸리는지..
    그리구 플랜카드 너무 잘 만드셨어요~ 부럽습니다!~

    • 저처럼 막 LED 불빛 돌아가게 하는거 아니라면.. V = IR 공식이랑.. 약간의 인두기 사용법에 익숙해지면 만들 수 있습니다. 비용은 제가 든 비용은 4만원 정도 인데..(아크릴 제외.. 고휘도 LED가 촘촘하게 해서 많이 나옴)
      크기에 따라 다르니 때에 따라 직접 산출해보시면 됩니다. 그리고 마지막으로 시간은 사람 및 숙련도에 따라 각자 다르겠지만 저는 첨은 해보았는데 10 ~ 15시간 정도 걸린거 같습니다. 인두기 사용에 익숙치 않으신 분들은 더 많이 걸릴거라 생각되네요..