회원가입 ID/PW 찾기

1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.

콘텐츠 수 120
판매자 보해소주 판매 납포인트 무료 평점 0점 / 총 0명 참여


8051 타이머 정복 - 제2부 -



제1부 : 8051 타이머 개요
제2부 : 타이머 관련된 SFR 레지스터 분석
제3부 : 타이머 동작모드 분석 및 예제 프로그램 작성
제4부 : 타이머 활용 및 정리




2. 타이머/카운터와 관련된 SFR 레지스터 분석

제1부에서 언급한 것 처럼 8051의 두개의 타이머(타이머0, 타이머1)는 각각 4가지의 동작모드를 가지고 있습니다. 이 4가지 동작모드를 각각 모드0, 모드1, 모드2, 모드3이라 합니다. 다시 말해 타이머0과 타이머1은 각기 서로 다른 방식으로 타이머 기능을 수행할 수 있다(예컨대, 타이머0는 모드1,타이머1은 모드2)는 뜻이 됩니다. 이들 4가지 동작모드에 대한 특징을 간략히 언급을 드리자면,


모드 0 : 13비트 타이머
모드 1 : 16비트 타이머
모드 2 : 8비트 타이머 (with auto reload)
모드 3 : 타이머0는 2개의 8비트 타이머, 타이머1은 시리얼 클럭신호로 사용



잠깐!!!
"모드 0,1은 타이머 비트수만 다르고 방식은 거의 같다는 점, 모드2는 8비트이나 auto reload(자세한 것은 후술함)기능이 제공된다는 점, 모드3은 타이머0과 타이머1이 각각 서로 다르게 동작한다는 점"을 반드시 머리속에 기억하고 다음 단계로 넘어가도록 하겠습니다.


일반적으로, 8051에서 타이머의 사용은 다음과 같은 순서를 통하여 이루어집니다.


① 타이머 인터럽트 관련 레지스터 설정 (IE 및 IP) // cf. 폴링방식의 경우엔 ①은 불필요
② 타이머 관련 레지스터 (TMOD 및 TCON) 설정 (타이머 별 각 동작모드는 여기서 설정하게 됨)
③ 인터럽트 서비스루틴 또는 타이머 처리루틴 구현 (어셈블러 또는 C언어로 코딩)


제2부의 핵심은 위의 3단계에 대한 정확한 이해입니다. 그럼 지금부터 각 단계에 대한 각론을 설명하도록 하겠습니다.


(1) 타이머 인터럽트 관련 레지스터 설정

첫번째 단계에의 요점을 먼저 말씀드리자면, 여러분은 타이머를 사용하기 위해 인터럽트 방식과 폴링모드 방식의 차이를 정확히 이해하고 인터럽트 방식의 타이머를 사용할 경우 어떤 과정을 밝아야 하는가입니다.

타이머의 키포인트는 "특정 시간의 경과 시점을 어떻게 알 수 있는가"하는 점입니다. 8051에서 타이머는 이를 위하여 "오버플로우 비트"라는 것을 이용합니다. 타이머0는 TF0, 타이머1은 TF1이라는 오버플로우 비트(Overflow-Bit)를 각각 이용합니다. 타이머와 카운터는 SFR 레지스터 영역중 TL, TH(타이머0는 TH0,TL0; 타미어1은 TH1,TL1)이라는 레지스터에 일정 주기로 +1씩 값을 증가시켜 나가는데 이 값이 0xFFFF로서 모든 비트가 1로 채워진 뒤, 다시 +1이 증가할 경우 각 레지스터는 자리올림이 발생하면서 0x0000으로 되돌아 옵니다. 이 때 자리 올림된 비트 "1"을 바로 오버플로우 비트라고 부릅니다. 타이머0에서는 TF0, 타이머1에서는 TF1에 오버플로우비트 "1"이 저장됩니다. 따라서, 우리는 이 TF0와 TF1의 비트값이 "1"로 되어 있는지 아닌지를 확인함으로써 일정주기의 시간이 경과 했는지를 알 수 있게 되는 것이죠.

그럼 이 값은 어떠한 방법으로 확인이 가능할까...?

이를 위해 크게 두 가지가 존재하는데, CPU가 오버플로우가 발생했다는 사실을 우리가 작성한 프로그램에 알려주는 방법(이를 인터럽트 방식이라고 함)과 사용자가 직접 TF0, TF1의 비트 값을 직접 조사하여 확인하는 방법(이를 폴링방식이라고 함)이 그것입니다. 인터럽트 방식과 폴링방식은 그 장단점이 서로 있기 때문에 어느 것이 좋다고 단언할 수는 없을 것 같습니다. 다만, 인터럽트 방식과 폴링방식으로 구현하는 것에 있어서 코딩방법 상에 차이점이 있으므로 그 부분을 설명드리자면 아래와 같습니다.






A. 폴링방식

void main()
{

    while(1) {
        ...
        if (TF0) {AAA();}
        ...
    };

    ...
}

void AAA()
{
    ...
    타이머관련 루틴 처리;
    ...
    TF0 = 0;
}

B. 인터럽트 방식

void BBB() interrupt 1
{
    ...
    타이머관련 루틴 처리;
    ...
}

void main()
{
    ...
    타이머인터럽트관련 레지스터 설정;
    ...

    while(1)
    {
        ...
        다른 업무를 수행
        ...
    };

}


먼저 "폴링 방식"은 main함수내에서 while()문과 같이 무한루프를 돌면서 오버플로우가 발생했는지를 지속적으로 체크하는 방식입니다. 루프를 계속 돌면서 오버플로우가 발생했을 경우(예컨대, TF0가 1로 세팅된 경우) 후속함수 AAA()를 호출하여 관련된 프로세스를 수행하고 되돌아옵니다. 그리고, 다시 루프를 돌면서 오버플로우가 발생된 경우 다시 AAA()함수를 실행하는 형식이죠. 위의 폴링방식은 코딩 자체가 순차적이기 때문에 유지보수면에서 유리합니다. 또한 처리루틴 대부분이 무한루프 내에서 조건분기문 형식으로 이루어지기 때문에 가독성 또한 높습니다. 그러나, 폴링방식의 문제점은 오버플로우가 일어나지 않은 시점에도 지속적으로 TF0를 체크해야 하기 때문에 CPU의 대부분이 이 무한루프를 처리하는 부분에 집중되어 성능면에서 비효율적이라는 것입니다. 간단한 예제나 응용프로그램의 경우엔 폴링방식이 작성하기 쉽지만, 운영체제라던가 로우레벨 영역에서의 프로그램을 작성할 때는 폴링방식은 그다지 이용되지 않습니다.
참고로, 폴링방식의 경우 타이머관련 처리 함수인 AAA()가 자신의 임무를 종료하고 main()함수로 리턴하기 전에 반드시 TF0를 0으로 클리어 해주어야 합니다. 인터럽트 방식이 아닌 경우 CPU가 타이머관련 업무를 끝냈는지 알 방법이 없기 때문에 유저가 소프트웨어적으로 TF0를 클리어 해주어야 하는 것입니다.

그 다음 "인터럽트 방식"을 보도록 하죠. 위에 B의 인터럽트 방식은 먼저 main()함수가 시작되면서 타이머 인터럽트 설정을 먼저 해야합니다. 타이머 인터럽트가 활성화 되면 CPU는 오버플로우의 발생여부를 감시하게 됩니다. main()함수는 while()내지는 기타 다른 문장에서 타이머 처리와는 관련 없는 다른 업무를 수행합니다. 그런 도중 타이머에서 오버플로우가 발생했을 경우 CPU는 main()함수를 도중에 잠시 멈추어 놓고 곧바로 BBB()함수를 호출합니다. 이게 바로 전통적인 인터럽트서비스 루틴이라 불리는 것입니다. 인터럽트 서비스 루틴이라는 것을 컴파일러에게 알려주기 위하여 함수 정의부분에 interrupt라는 키워드와 인터럽트벡터 번호를 붙이게 됩니다. 따라서, 소스를 보자 마자 "아! 이 부분은 인터럽트 서비스루틴이구나!!"하고 금방 알아볼수가 있지요. CPU가 인터럽트 서비스 루틴에 들어오면 TF0는 자동으로 "0"으로 클리어됩니다. 따라서, 소프트웨어적으로 TF0를 클리어 할 필요가 없습니다. 인터럽트 서비스루틴인 BBB()함수가 종료가 되면 CPU는 다시 제어권을 main()함수로 넘겨주고 아까 멈추었던 문장의 다음 문장부터 실행을 합니다.

바로 위의 세단계 중 첫번째인 ① 과정이 바로 인터럽트방식으로 구현할 경우에 해당하는 사항입니다. (폴링방식의 경우 ①과정은 필요 없음) 따라서, 프로그래머는 내가 타이머인터럽트를 사용하겠다는 것을 미리 선언해 주어야 할 필요가 있는데, 8051은 SFR중에 하나인 "IE(Interrupt Enable Register)레지스터"를 통하여 인터럽트 사용여부를 확인합니다.



타이머를 배울 때 어려운 점이 바로 이겁니다. 타이머는 그 자체 뿐만이 아니라 인터럽트나 시리얼 인터페이스와도 연관이 되어 있어서 처음 배우는 사람에겐 좀 벅찬 감이 있죠. (민법총칙도 모르는데 물권법, 채권법 어쩌구 떠드는 거랑 똑같습니다요.. ㅋㅋ)
IE 레지스터는 인터럽트를 사용할 지를 결정해주는 정해주는 레지스터입니다. 인터럽트의 사용 선언은 IE 레지스터의 비트7에 해당하는 EA비트가 담당합니다.


EA=1 : CPU에 정의된 인터럽트를 사용함
EA=0 : 모든 인터럽트를 사용하지 않음


고전적인 8051계열의 칩은 전통적으로 "외부인터럽트 2개, 타이머/카운터인터럽트 2개, 그리고 시리얼 인터럽트 1개" 등 총 5개를 인터럽트를 지원합니다. 개량형 타입은 그보다 더 많은 수의 인터럽트를 제공합니다만 위의 5개는 모든 칩에서 기본적으로 제공되는 것들입니다. 이 5개의 인터럽트는 사용자가 선택적으로 사용이 가능한데 이를 지정해주는 비트가 바로 IE레지스터의 비트0~비트4가 되겠습니다.(비트5의 ET2는 AT89S52에서 제공하는 타이머2에 대한 인터럽트 인에이블 비트이므로 AT89S51에서는 제공되지 아니함) 위의 그림처럼 타이머0는 비트1, 타이머1은 비트3을 각각 "1"로 세팅하면 해당 인터럽트를 사용할 수 있겠군요.
EA=1로 세팅되어 있어도 각각의 인터럽트 인에이블 비트가 "0"으로 되어 있는 경우에는 인터럽트가 비활성화 됩니다.

"1"로 세팅된 인터럽트가 여러개(가령 모든 인터럽트가 "1"로 설정되어 있는 경우) 존재할 경우에 어떤 인터럽트를 가장 먼저 수행할 지는 CPU에 정의가 되어 있는 방식을 따르거나 아니면 IP(Interrupt Priority Register)레지스터를 설정하여 우선순위를 사용자가 지정할 수 있습니다. IP 레지스터의 사용은 본 강좌와는 크게 문제되지 않으므로 차후에 별도의 인터럽트 강좌를 통하여 말씀드리도록 하겠습니다.(굳이 알고 싶으신 분은 데이터시트나 관련서적을 참고해 주세요)

따라서, main()함수를 시작해서 제일 먼저 해야 할 것이 바로 레지스터를 설정해 주는 작업이 되겠군요.







void port_init();

void main()
{
    port_init();
    ...

}

void port_init()
{
    /* Enable Interrupt */
    IE = 0x80; // EA = 1;
    /* Enable Timer 0,1 */
    IE |= 0x08; // Timer 1
    IE |= 0x02; // Timer 0
    /* Set Interrupt Priority, if necessary */
    ...
}




(2) 타이머 관련 레지스터

타이머인터럽트 설정이 끝나면 타이머 관련 레지스터를 설정해야 하는데 타이머와 관련된 SFR는 TMOD와 TCON 레지스터 2개입니다. 먼저 TMOD레지스터에 대해 살펴보겠습니다. TMOD(Timer Mode Register) 레지스터는 다음과 같습니다.



우리는 앞서 8051에는 타이머0, 타이머1 이렇게 2개의 타이머를 제공된다는 사실을 배웠습니다. 타이머0, 타이머1은 각각 독립적으로 자체의 동작모드를 정할 수 있는데 그것을 설정하는 레지스터가 바로 TMOD레지스터입니다. 보시는 바와 같이 하위니블(b0~b3)은 타이머0, 상위니블(b4~b7)은 타이머1의 동작모드를 설정할 수 있습니다. 각각의 타이머는 모드0, 모드1, 모드2, 모드3의 4개의 동작모드 중에 어느 하나를 취할 수가 있는데, 각 타이머의 동작모드를 정해주는 비트가 M0, M1비트입니다. 동작모드별 비트설정은 아래와 같습니다.







M1 M0 동작모드
0 0 모드 0
0 1 모드 1
1 0 모드 2
1 1 모드 3


각 모드의 자세한 설명은 제3부에서 상술할 예정이므로, 일단 타이머0,1 각각의 동작모드를 설정하는 방법은 TMOD레지스터의 M1, M0비트를 통해서 이루어진다는 것만 기억하시면 되겠습니다. 그 다음 C/T비트라는것이 있는데 클럭소스를 외부핀으로부터 받을지 아니면 CPU내부의 클럭소스를 통해서 받을 지를 결정하는 비트입니다. 우리는 제1부에서 이 입력소스가 외부에서 공급될 경우를 "카운터", 내부에서 공급될 경우를 "타이머"라 정의한다고 배웠습니다. 우리는 타이머를 사용하는 것이므로 C/T=0으로 설정하면 됩니다. GATE핀은 추후에 다시 설명할 것인데 일단 0으로 설정하기로 하겠습니다.

자!!! 이제 타이머0과 타이머1을 어느 동작모드에서 작동시킬지 정하는 방법을 배웠습니다. 이제 TCON레지스터에 대해서 알아보기로 하죠.



TCON(Timer Conterol Regiser)레지스터는 이름에 나와있다시피 타이머의 동작을 제어하는 레지스터입니다. 쉽게말해 타이머를 ON/OFF하는 레지스터로 보시면 되겠습니다. 그런데 주의할 게 TCON레지스터의 하위 니블(b0~b3)은 타이머하고는 전혀 관계 없는 외부인터럽트(INT0,INT1) 제어에 대한 비트인데 쓸데없이 TCON레지스터에 들어 있습니다. 의아스러우시겠지만 괜시레 혼동하지 마시구요. 이 부분은 인터럽트편에서 뵙기로 하고 상위니블(b4~b7)을 살펴보도록 하겠습니다.
좀 낯익은 비트가 보이죠? 바로 TF0와 TF1비트가 보입니다. 이 비트가 바로 타이머가 오버플로우 난 경우 "1"로 자동으로 설정되는 비트입니다. 인터럽트 방식의 경우엔 프로그램이 인터럽트 서비스루틴에 진입하면서 자동으로 클리어 되고, 폴링방식의 경우엔 사용자가 인위적으로 "0"으로 클리어 해주어야 한다는 점을 떠올려 보시기 바랍니다.
그럼 이제 남은 비트는 TR0과 TR1이군요. 눈치 채신 분들도 계시겠네요. *^^* 바로 이 비트가 바로 타이머 시작과 정지를 담당하는 비트입니다. 타이머0의 시작/정지는 TR0가, 타이머1의 시작/정지는 TR1이 담당합니다. 이 비트가 "1"이면 타이머는 시작되고, "0"으로 클리어되면 타이머가 정지됩니다.


(3) 인터럽트 서비스루틴 또는 타이머 처리루틴 구현

이제 타이머 인터럽트의 설정과 관련된 부분은 끝났습니다. 따라서, 인터럽트 서비스 루틴만 구현하면 완성입니다. 타이머1을 모드2, 타이머0를 모드0으로 설정하여 동작시킬 경우 소스는 아래와 같은 뼈대를 구성하게 될 것입니다.








void port_init();
void timer_init();


void timer0_handler() interrupt 1
{
    ...
}

void timer1_handler() interrupt 3
{
    ...
}


void main()
{
    port_init();
    timer_init();
    ...
    while(1) {
    ...
    };

}

void timer_init()
{
    TMOD = 0x20; // Timer 1 : mode 2, Timer 0 : mode 0
    TR1 = 1; // TCON |= 0x40; Timer 1 start
    TR0 = 1; // TCON |= 0x10; Timer 0 start
}


void port_init()
{
    /* Enable Interrupt */
    IE = 0x80; // EA = 1;
    /* Enable Timer 0,1 */
    IE |= 0x08; // Timer 1
    IE |= 0x02; // Timer 0
    /* Set Interrupt Priority, if necessary */
    ...
}



별로 어렵지 않죠? 자 그럼 다음 시간에는 타이머0,1의 4가지 동작모드에 대해서 배우도록 하겠습니다. 아울러 예제프로그램 작성시 Keil 컴파일러 사용법에 대해서도 설명하도록 하겠습니다.


profile
붕붕 2007.11.03 16:49
오 잘봐씁니다^_^
profile
yahoosm 2007.11.25 17:31
설명을 너무 잘하시네요^^ 감동!
profile
ssonic00 2008.03.10 15:50
너무 열심히 배우고 있습니다.
profile
kayer 2008.04.12 23:49
어렵네요 ㅠㅠ
profile
울프썬 2008.04.15 23:19
^^좋은자료 감사합니다^^
profile
Zosys 2008.04.21 14:00
감사합니다^^
profile
뿡뿡이 2008.05.18 19:33

감사합니다^^;

profile
아이구머쩌라 2008.05.22 11:49
잘보고 갑니다^^
profile
호랭이 2008.05.23 10:32
설명 굿  이해 배리구웃~~~
profile
바람돌돌 2008.06.19 16:23
좋네요 ㅋ
profile
무정 2008.06.21 11:09

초보라 읽을땐 이해....조금지나면 뭔말인지....열공하려고요 감사..

profile
A.T.O 2008.07.07 23:16

감사~

profile
사사사 2008.09.22 14:12
좋은자료ㄳ
profile
데니스 2008.09.24 11:39
감사합니다.
profile
꿀꿀 2008.10.01 22:51
오오오 감사해요 !! ㅋ
profile
외뿔공룡 2008.10.10 20:57
쉬운 설명 감사합니다.
profile
오뎅 2008.10.17 13:28
정말 감사합니다.ㅋㅋ
profile
단단다다 2009.10.16 03:20
감사합니다!
profile
leo 2009.11.27 16:21
많은 도움이 되었습니다.
profile
물지않아요 2009.11.30 13:49
많은도움이되었어요!!
profile
피타고라니 2009.12.01 16:00
감사합니다ㅎㅎ
profile
hunix 2009.12.14 17:45
많은 도움이 되었습니다. 정말 감사합니다.
profile
평생동안 2009.12.28 10:56
자료감사합니다~
profile
오호 2010.01.07 11:07
좋습니다~~~
profile
라온아비 2010.02.24 09:48
강좌 잘 읽었습니다.
profile
jyp9125 2010.04.08 17:45

잘읽었습니다~

profile
천상천하 2010.04.09 12:40
감사합니다.
profile
흑화향 2010.04.29 10:58

8051을 배우면서 많은 부분을 모르고있지만 오늘 타이머라는 부분에 대해 많은것을 배우고 갑니다 ㅎ
친절한 설명 감사드립니다~

profile
wotmd 2010.05.07 21:09
감사합니다.
profile
마쵸 2010.05.10 00:05
많이 노력해야 할 것 같네요ㅠ 감사합니다^^!
profile
종박 2010.05.25 19:20
하 인터럽트의 차이를 알았어요!
profile
끈기 2010.06.06 17:21
설명 짱이다!
profile
절제하는늑대 2010.06.07 17:57
dd
profile
진진진 2010.06.09 17:23
감사합니다.
profile
Do 2010.06.11 20:13
잘봤습니다.
profile
박진철 2010.06.29 09:41
좋은 정보 감사합니다
profile
고수되고파 2010.07.12 14:50
헉 여기도 배꼽~~~
profile
고수되고파 2010.07.12 22:43
점점 어려워요~~~폴링,인터럽트
profile
devilforce 2010.07.13 09:51

내용이 갑자기 좀 많아졌네요 ㅠ

profile
대빵자두 2010.07.19 22:12
정말 감사합니다
profile
Hyeon 2010.08.10 13:16

정말 유용하네요..

profile
꼬마최민수 2011.07.20 14:53

감사합니다!! 엄청 쉽게 설명을 해주신 것 같은데 저로써는 좀 어렵네요...ㅠㅠ 열공 열공~!~!

profile
Interrupter 2011.09.30 08:52

좋은 자료 감사합니다.

profile
컴쟁이 2012.05.17 00:07
강좌 잘보고 갑니다...
profile
코알라공원 2015.10.05 09:13

감사합니다

profile
시나브로69 2017.06.24 13:03
감사합니다.
search
List of Articles
번호 분류 제목 평점 포인트 판매자 등록일 구매수 조회 수
공지 공공의 목적으로 공유하고자 하는 소프트웨어는 '소프트웨어 자료실'에 업로드를 요청드립니다.
공지 구매후 평점 댓글을 남겨주시면 구매포인트의 20%를 돌려드립니다.
118 강좌 & 팁 OP-amp의 특징과 설계시 주의사항 [3] 5P dmz1723 2019-06-24 15 359
117 강좌 & 팁 PCB 비용 절감을위한 기본 지침 [4] 무료 아크마 2018-06-17 0 712
116 강좌 & 팁 인쇄 회로 기판 (PCB)에 사용되는 개념과 용어 [6] 무료 아크마 2018-06-17 0 1191
115 강좌 & 팁 알티움을 유지보수하면 좋은 이유 (1) / Altium 17 Draftsman 무료 아크마 2018-01-06 0 268
114 강좌 & 팁 VHDL 기초이론 [2] 5P 태양인이제마 2017-12-26 14 287
113 강좌 & 팁 [국문번역] Programmable-Gain Transimpedance Amplifiers Maximize Dynamic Range in Spectroscopy Systems 5P 오로랏 2017-08-26 4 129
112 강좌 & 팁 이론상 가장 빠른 정렬 알고리즘 [1] 10P 오로랏 2017-08-26 4 362
111 강좌 & 팁 와이어 솔더링 노하우 [10] 5P 아그네스 2017-04-04 16 448
110 강좌 & 팁 vi Editor “Cheat Sheet” [2] 5P 아크마 2017-01-30 2 115
109 강좌 & 팁 AVR 기초강좌_1.보드에 프로그램 다운로드하기_퓨즈설정 [16] 무료 소중이 2010-05-18 0 3130
108 강좌 & 팁 미국 전선 규격 환산 5P 아크마 2012-12-30 2 240
107 강좌 & 팁 EMI 및 EMI 필터 설명, 설계, 주의사항 등 전반적인 내용 [1] 50P 솔개처럼 2016-12-16 8 305
106 강좌 & 팁 노이즈방지 PCB 설계법 [33] 5P 직장인 2016-07-21 31 760
105 강좌 & 팁 Fluorescent Lamps, Ballasts, and Fixtures [2] 5P 오로랏 2016-05-28 0 65
104 강좌 & 팁 [PCB설계] 전압에 따른 최소 도체 간격 & 패턴폭과 허용전류 & TH경에 따른 패턴폭 [6] 5P 킬유21 2015-11-06 13 554
103 강좌 & 팁 2015년 1월~2월에 진행을 하였던 모바일 로봇입니다. [1] 5P 한백금설 2015-05-14 8 459
102 강좌 & 팁 Rc Car를 이용하여 만든 자동주차시스템입니다. [3] 5P 한백금설 2015-05-14 5 627
101 강좌 & 팁 자작 라인 트레이서 [1] 무료 윤컴 2015-05-02 0 317
  • 위대한 사람은 모두가 겸손하다.
    - 레싱
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.