회원가입 ID/PW 찾기

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

콘텐츠 수 200
판매자 보해소주 판매 납포인트 무료 평점 0점 / 총 0명 참여
8051 타이머 정복 - 제3부 -



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




3. 타이머 동작모드 분석 및 예제 프로그램 작성

안녕하세요, 오늘은 타이머 강좌의 꽃이라 할수 있는 8051 타이머의 동작모드 분석과 응용 실습을 할 차례입니다. 진도 나가기 전에 앞서서 워밍업 차원으로 지난 시간까지 배운 것을 잠시 정리해 보도록 할까요? ^^


ⓐ 타이머/카운터의 구별 : 클럭소스가 내부(크리스털/오실레이터)에서 공급되는지 외부(T0,T1핀)에서 공급되는지에 따라 구분
ⓑ 타이머를 구현하는 방식 : 인터럽방식/폴링방식
ⓒ 타이머를 인터럽트 방식으로 사용할 때 관련된 레지스터 : IE 및 IP 레지스터 (IP는 실습에서는 선택적이므로 설정 안해도 무방)
ⓓ 타이머0, 1의 동작모드 설정에 관련된 레지스터 : TMOD
ⓔ 타이머 제어에 관련된 레지스터 : TCON의 상위 니블(b4~b7)


기억들 나시죠? ^^
그러면 잠시, 이전 시간에서 설명 안하고 넘어가버린 부분들을 살짝 언급 해 보고 이어서 동작모드를 분석해 보도록 하겠습니다.

① 머신싸이클과 타이머와의 관계

CPU에는 기본적으로 머신싸이클이란 것이 존재합니다. 머신싸이클(machine cycle)이란 CPU가 특정 명령을 수행하는데 걸리는 최소시간 단위를 말합니다. 잠시 Atmel사의 홈페이지에서 8051 어셈블러의 인스트럭션 코드를 잠깐 살펴보도록 하겠습니다.

문서보기

문서에서 다음과 같은 어셈블러 명령이 "몇바이트 몇사이클 몇클럭주기" 짜리 문장인지 살펴보세요.






어셈블러 명령 정답(마우스를 긁어보세요)
INC A 1바이트 1사이클 12클럭
ADD A,#data 2바이트 1사이클 12클럭
INC DPTR 1바이트 2사이클 24클럭
MOVX A,@DPTR 1바이트 2사이클 24클럭


위의 보기에서 "바이트"해당 명령문이 코드 메모리상에서 차지하는 메모리 크기를 말하고, "사이클"해당 문장이 실행되는데 걸리는 시간을 뜻하며, "클럭수"이 시간(사이클)을 CPU의 클럭주기로 환산한 값을 의미합니다. 그런데, 가만히 이 값들을 째려다 보면... "1사이클=12클럭" 이란 관계를 엿볼 수 있습니다. 아래의 그림을 잠시 볼까요?



[ 그림 1 : 8051코어의 타이밍 다이어그램 ]


8051 코어는 기본적으로 특정 명령을 수행하기 위하여 클럭신호 2개를 한 단위로 하여 총 6단위(즉, 총 12클럭)를 1싸이클로 하고 있습니다. 6개의 각 단위를 STATE라고 부르며 각 STATE 마다 첫번째 클럭신호 주기를 PHASE1, 두번째 클럭신호 주기를 PHASE2라고 부릅니다. 8051의 모든 명령은 1머신싸이클 또는 2머신싸이클 내에서 모든 기능을 수행하도록 설계되어 있습니다. 따라서, 모든 명령은 클럭신호의 12배에 해당하는 시간을 중심으로 동기화되어 있는 것이죠. 타이머도 이 머신싸이클에 동기화 되어 있기 때문에 타이머의 계수기는 바로 1머신싸이클(=12클럭주기)을 기본단위로 하여 동작합니다.

자아~그럼 도대체 1머신싸이클이란게 도대체 얼마의 시간을 뜻할까요? 예컨대, 12MHz의 크리스털이 장착된 보드를 가정해 보겠습니다.
클럭스피드의 진동수(Hz)는 1초에 클럭신호가 몇 번 진동할 수 있는가를 나타내는 수치입니다. 학생 시절에 배운 물리지식을 떠올려 보면

주기 = 1/진동수, 즉, T = 1/f 이므로

1클럭주기 = 1/클럭주파수 = 1/12MHz = 0.083333㎲

의 아주 짧은시간에 클럭신호가 한번 진동합니다. 따라서, 1머신싸이클은 12클럭이 소요되므로

1머신싸이클 = 12 x (1/12MHz) = 12 x 0.083333㎲ = 1㎲

가 됩니다. 따라서, 이 경우 타이머는 1㎲를 단위로 하여 계수가 되겠죠. 따라서, CPU는 1머신싸이클(1㎲)보다 작은 시간단위는 계산할 수 없는 것입니다. 요즘 펜티엄4 CPU는 2GHz를 훨씬 상회하는데 이만하면 펜티엄칩의 머신싸이클이 얼마나 짧을지는 상상히 가시겠죠? ^^;;

요기까지 설명한 것을 중심으로 결론을 내려볼까요?

CPU의 머신싸이클은 장착된 크리스털(오실레이터)의 주파수에 따라 달라진다!!!

아! 질문이 들어왔군요!!! *^^*

[Q] 클럭주파수가 f인 8051보드의 1머신싸이클은 얼마일까요?

[A]
1clk = 1 / f , 따라서, 1머신싸이클 = 12 x (1 / f). 즉, 클럭속도의 역수에 12를 곱하면 머신싸이클이 얻어집니다.


[Q] 제가 사용하는 보드는 11.0592MHz와 22.1182MHz입니다. 각각의 머신싸이클을 알고 싶습니다.

[A]
위의 첫번째의 공식을 활용하면 되겠네요.


f1 = 11.0592MHz의 경우, 1클럭 = 1 / f1 = 1 / (11.0592MHz) = 0.090422㎲ , ∴ 1머신싸이클 = 12 x (0.090422) = 1.0851㎲
f2 = 22.1182MHz의 경우, 1클럭 = 1 / f2 = 1 / (22.1182MHz) = 0.045212㎲ , ∴ 1머신싸이클 = 12 x (0.045212) = 0.5425㎲



② 타이머의 시작/정지는 TR비트로만 가능할까?

잠시 저번 시간에 배운 TMOD 레지스터를 다시 한번 보도록 하겠습니다.


[ 그림 2 : TMOD 레지스터 ]


TMOD는 타이머0과 타이머1 각각의 동작모드를 설정하는 레지스터라고 배웠습니다. 각 비트에 대해선 한 녀석만 빼고는 설명을 다했는데요. 바로 b3, b7에 해당하는 GATE라는 비트입니다. GATE비트타이머의 START/STOP 기능을 외부신호에 통해서 가능하게 만들어 주는 비트입니다.


GATE = 1 : 외부핀(INT0/INT1)으로 타이머 START/STOP 제어 가능
GATE = 0 : 외부핀으로 제어 불가



GATE = 1 의 경우

INT0/INT1 = 1 이면 타이머 START
INT0/INT1 = 0 이면 타이머 STOP



이런 식으로 타이머를 제어할 수가 있는 것이죠. 우리가 8051을 가지고 스탑워치를 만든다고 가정해 볼까요? 스탑워치에는 START/STOP버튼이 있죠? 버튼을 누르면 시계가 열심히 돌아가다가 다시 버튼을 한번누르면 시계가 멈추죠. 그리고, 다시 누르면 또 시계가 돌아가고... 그런 버튼의 기능을 8051에 구현한다고 해보세요. 이 때 필요한게 바로 외부신호를 통하여 타이머를 START/STOP시킬 수 있는 기능이 필요한것이죠. 그것을 가능하게 해주는 녀석이 바로 TMOD의 GATE비트가 되겠습니다.

자아, 위의 두가지 사항에 대해 이해가 되셨으면 여러분은 타이머의 4가지 동작모드를 파헤칠 준비가 되신겁니다. 축하드리구요. 잠시 숨을 돌리는 차원에서 지난 시간에 머리 속에 꼬옥 넣어달라고 부탁드렸던 4가지 동작모드의 키워드를 다시 써보기로 하죠.


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



(1) 타이머 동작모드 0

먼저, 당부의 말씀!!!

보통 책을 보면 타이머0,1 이란 말에다가 타이머 모드0,1,2,3 이렇게 모드라는 글자만 하나 더 써넣은 책들이 많던데 그러다 보니 헷갈리는 경우가 많더군요. 그래서, 용어를 정확히 구분하기 위해 타이머의 구분은 타이머0, 타이머1 그리고 각각의 모드에 대해서는 그냥 동작모드0,1,2,3이런 식으로 명칭을 붙이기로 합시다. (타이머0 ≠ 타이머모드0 = 동작모드0) 글을 읽으시면서 타이머0를 지칭하는건지 타이머0의 동작모드0을 뜻하는건지 헷갈리지 마시라는 겁니다. 자아, 그럼 시작하겠습니다.


[ 그림 3 : 타이머 동작모드0 의 구성 ]


타이머0,1의 각 동작모드0는 13비트의 크기로 동작하며, 이 때 계수기의 값은 SFR의 THx와 TLx레지스터(x=0,1; 편의상 TH, TL이라 부르면 타이머0,1 모두 해당되는 것으로 함)에 저장됩니다. 여기서 TH레지스터는 0~255의 값을 갖는 카운터기능을 담당하며 TL레지스터는 0~31의 32분주 프리스케일러(prescaler)기능을 담당합니다. 무슨 소리냐구요?

자 그럼 우리가 타이머0에 대해서 동작모드0로 설정한 상태에서 TR0=1을 인가하여 타이머를 동작시킨다고 가정해 봅시다. (타이머1의 동작모드0도 동일하므로 타이머0를 기준으로 설명합니다)

타이머가 START 되면 먼저 TH0와 TL0에 저장된 값(사용자가 초기화 해주지 않으면 둘다 0x00, 0x00으로 세팅)부터 시작해서 1머신싸이클마다 +1씩 TL0의 값을 증가시킵니다. 그러다가 모든 비트가 "1"로 채워진 뒤, 그 다음 싸이클에서 +1이 증가하여 오버플로우가 발생하면 TH0의 값을 1증가시킵니다. 다시 TL0는 0x00부터 1머신싸이클마다 +1씩 증가되어 오버플로우가 발생하면 다시 TH0의 값을 +1 증가 시킵니다. 이렇게 계속 반복해서 TH0와 TL0의 모든 비트가 "1"로 채워진 경우 그 다음 머신싸이클 뒤에 다시 +1이 증가하면 TH0와 TL0 모든 비트가 "0"으로 됩니다. 이때 TF0의 비트가 "1"로 채워집니다. 주의하세요, TF0가 "1"이되는 경우는 TL0가 0x00이 되는게 아니라 TL0, TH0 둘다 0x00이 될 때 "1"로 오버플로우비트(TF0/TF1)가 세팅됩니다.

동작모드0에서 TH0와 TL0의 각 비트를 잠시 들여다 보면





TH0 TL0
b7 b6 b5 b4 b3 b2 b1 b0 b7 b6 b5 b4 b3 b2 b1 b0
1 1 1 1 1 1 1 1 X X X 1 1 1 1 1


TL0에 자리올림이 발생하여 TH0의 값을 +1 증가시키기 위해서 TL0는 b0~b4의 5비트만을 사용하며, 상위 b5,b6,b7는 사용하지 않습니다. 따라서, 5비트만을 가지고 TH0로 자리올림을 해주므로 총 32분주하는 셈입니다. 그래서, TL0는 1머신싸이클마다 분주하므로 프리스케일러(prescaler), TH0는 TL0로부터 자리올림을 받기만 하므로 카운터라 부릅니다. TH0의 8비트, TL0의 5비트 더해서 총 13비트가 타이머 동작모드0에 사용되므로 13비트타이머라고 부르기도 합니다. 왜 동작모드0가 13비트 인지 이해가 되셨죠? *^^*

그럼 위의 [그림3]을 좀 더 분석해 보도록 하겠습니다. C/T=0인 경우는 카운터가 아닌 타이머로 동작하겠네요. (왜냐구요. 그림에 보다시피 CPU의 OSC로 부터 신호를 받잖아요. 근데 바로 옆에 ÷12라는 기호가 있네요. 우리가 앞서 머신싸이클의 개념을 배울 때 1머신사이클 = 12클럭이라고 했죠. 클럭주파수를 ÷12하니까 결국 클럭 12개를 한묶음으로 쓰겠다는 소리죠. 다시 말해 OSC에서 타이머로 입력되는 클럭신호는 1머신싸이클마다 1회입력된다는 의미가 됩니다.

그 다음 타이머0를 제어하기 위해 TR0 이외에 AND회로로 신호가 몇 개 더 붙어 있네요. 바로 앞서 설명드렸던 GATE=1로 설정할 경우 타이머의 START/STOP을 INT0단자를 통하여 이용할 수 있도록 설계했다는 뜻입니다. 진리표를 함 그려보세요. GATE=0인 경우 INT0에 관계없이 오직 TR0값에 의해서만 ON/OFF됨을 알 수 있습니다.

저 그림을 보고 동작모드0의 원리가 이해가 되면, 나머지 모드 1,2,3은 모드0과 비슷하기 때문에 별 어려움 없이 해결할 수 있습니다.ㅋㅋ

그러면, 다시 화제를 다른 곳으로 잠시 돌려보죠. TF0에 오버플로우비트가 세팅되는 순간은 TH0와 TL0가 모두 1로 채워진 뒤 그 다음에 다시 1이 증가하여 모두 0으로 클리어 되는 순간입니다. 오버플로우가 발생하는 주기는 TH0, TL0에 어떤 값을 초기값으로 해주었는지에 따라 달라집니다. 보드가 12MHz의 클럭신호를 사용한다고 가정하면


TH0, TL0 : 모두 1로 세팅된 경우 ==> 1머신싸이클 뒤 오버플로우 발생 ∴ 1㎲
TH0, TL0 : 모두 0으로 세팅된 경우 ==> 2^13 = 8192 머신싸이클 뒤 오버플로우 발생 ∴ 8192㎲ = 8.192㎳


즉 사용자가 TH0, TL0에 어떤 값을 초기값으로 넣어주는가에 따라서 1㎲ ~ 8.192㎳ 사이의 타이머를 만들어 낼 수있게 되는 것입니다. 그렇다면, 이런 질문을 반드시 받겠군요...

[Q] 제 보드는 클럭주파수가 11.0592MHz입니다. 그렇다면, 최소주기와 최대주기의 시간이 위의 값과는 달라지는 것인가요?

[A] 당연히 바뀝니다. 왜냐면 머신싸이클은 클럭주파수에 의존하는 함수(∵ 머신싸이클 = 12 / 클럭주파수 )이며, 타이머의 클럭신호 또한 1머신싸이클 단위로 동작하기 때문입니다. 따라서, 타이머를 설계할 때는 각 동작모드별로 최대시간과 최소시간값을 계산해 내야 합니다.

동작모드0 에서


최소시간 T_min = 1머신싸이클 = 12 / (클럭주파수)
최대시간 T_max = 2^13 x 머신싸이클 = 2^13 x T_min = 8192 x T_min



위의 계산식을 이용해서 11.0592MHz의 보드에서 최대시간 및 최소시간을 계산해 보면,


T_min = 12 / (11.0592MHz) = 1.085㎲
T_max = 2^13 x T_min = 8192 x 1.085㎲ = 8.89㎳


[Q] TH0, TL0에 어딴 값을 입력하고 TR0=1을 대입하여 타이머를 돌렸습니다. 그런데 TF0을 체크하니 오버플로우가 한 번밖에 발생하지 않습니다. 지속적으로 타이머를 돌릴 방법은 없나요?

[A] 우리가 맨 처음 타이머의 각 동작모드를 설명할 때 모드2에는 auto reload 기능이 있다고 말한 적이 있습니다. 반대해석하면 모드2를 제외한 나머지는 auto reload기능이 없다는 셈이 되는군요. 네, 그렇습니다. 동작모드0는 auto reload 기능이 없어서 오버플로우가 일단 발생하면 더 이상 계수를 하지 않습니다. 따라서, 같은 주기로 타이머를 계속 돌릴고자 할 경우(즉, 오버플로우를 반복적으로 얻고 싶은경우)에는 TH0, TL0에 다시 초기 값과 같은 값을 대입하고 TF0를 다시 클리어 해주어야 합니다. 이는 CPU가 자동으로 해주는 기능이 아니므로 개발자가 처리해야 하는 부분입니다.





[실습 1] 이제 타이머0의 동작모드0를 이용하여 ㎳단위로 조정이 가능한 delay함수를 만들고 1초단위로 P1포트의 LED값을 순차적으로 값을 증가시키는 프로그램을 작성해보겠습니다. 컴파일러는 Keil컴파일러를 기준으로 설명하겠습니다만, SDCC나 다른 툴을 쓰셔도 상관없을 듯 합니다. 타이머 구현은 인터럽트 방식으로 구현한다고 가정하죠.


먼저 Keil컴파일러를 실행하고 프로젝트를 하나 생성하죠. Keil사의 uVsion2는 MS사의 비쥬얼스튜디오와 흡사하여 비교적 손쉽게 적응 할 수 있는 툴입니다. 프로젝트명은 TEST_TIMER로 하도록 하겠습니다.


우선, 메뉴->Project->New Project를 선택하여 새로운 프로젝트명을 입력하고




사용할 보드의 CPU타입을 지정합니다. CPU의 선택은 프로젝트 생성 후라도 변경이 가능합니다. IDE 좌측의 FILE탭에서 Tartget1에 마우스를 갖다대고 오른쪽 클릭하면 첫번째의 "Select Device for Tartget1..." 이란 녀석을 선택하면 동일한 화면이 나옵니다. 우리는 AT89S51을 기준으로 강좌를 진행해왔으므로 AT89S51를 선택하겠습니다. 다른 CPU를 씨고 계시면 거기에 알맞는 CPU를 선택하시면 되구요.




프로젝트 생성 완료 전 startup코드를 프로젝트로 복사할 것인지를 물어보는데 "예(Y)"를 선택합니다. 스타트업코드에 대한 자세한 사항은 나중에 별도의 강좌를 통해서 말씀드리기로 하구요. 일단 예(Y)를 선택해서 프로젝트 폴더로 가져기 오게끔 합니다.




프로젝트가 생성되고 나면 타겟보드에 대한설정을 해주어야 하는데 그림과 같이 "Option for Target 'Target1'"을 선택하면 아래와 같은 프로퍼티 상자가 나옵니다.




위의 그림처럼 Target탭을 선택하면 클럭주파수를 선택하도록 되어 있는데, 타겟보드의 클럭주파수를 입력합니다. 그 다음 AT89S51의 On-chip Flash메모리에 코드를 업로드 할 것이므로 바로 오른쪽의 Use On-chip ROM 박스를 체크합니다. 메모리 모델은 SMALL로 하겠습니다. (타겟보드에 EEPROM과 SRAM이 붙어 있는 경우 거기에 맞게 메모리 모델을 정하시기 바랍니다.




그 다음 Output탭에서 Create HEX File을 체크해줍니다. 이것은 컴파일된 바이너리파일을 HEX파일로 변환해주는 기능인데 통상 ISP프로그램을 통해 코드를 업로드할 경우 HEX파일을 이용하므로 이 옵션을 선택하는 것입니다. (참고로 ISP가 없으신 분들은 자료실에 올려둔 ISP회로드를 참고하셔서 제작하셔도 됩니다.)





자, 이제 기본적인 설정은 끝났구요. 프로그램 작성에 들어가도록 하죠.

새파일->코딩 작성후->timer.c로 저장->프로젝트에 timer.c파일을 ADD하면 끝입니다. 이 부분은 비쥬얼스튜디오랑 과정이 동일하군요.. ㅋㅋ





#include


unsigned long tic;

void port_init()
{
    IE = 0x80;
    IE |= 0x08; // timer 1
    IE |= 0x02; // timer 0
}

void timer0_init()
{
    TMOD = 0x00; // timer 0 : mode 0(13bit)

    TH0 = 0xE3;
    TL0 = 0x07;

    TR0 = 1; // start
}

void timer0_handler() interrupt 1
{
    tic++;
    TH0 = 0xE3;
    TL0 = 0x07;
    TF0 = 0;
}

void delay(int msec)
{
    unsigned long start = tic;
    while(tic!=start+msec);
}

void main()
{
    unsigned char sec = 0;
    port_init();
    timer0_init();

    while(1) {
        P1 = ~sec;
        delay(1000);
        sec++;
    };
}



위의 프로그램은 인터럽트 방식으로 타이머를 설정하고 1ms마다 타이머가 떠서 tic이란 변수를 +1씩 증가시킵니다. RTC(Real Time Clock)가 탑재되지 않은 타겟보드들에서 TIME값을 얻는 방법이 위와 같은 방식으로 이루어집니다. 다른 부분은 설명 안드려도 충분히 이해 하실 겁니다. 저는 여기서 1ms단위로 tic값이 어떻게 증가하는지를 설명드릴께요.

타이머0의 동작모드0에 대한 설명은 앞서 했으므로, 1ms를 계산하기 위해 TH0, TL0의 값을 얼마로 설정해야 하는지가 바로 포인트가 되겠습니다.

11.0592MHz의 클럭을 갖는 타겟보드가 동작모드0에서 갖는 오버플로우 주기의 최대값과 최소값을 계산해 보면,


T_min = 12 / (11.0592MHz) = 1.085㎲
T_max = 2^13 x T_min = 8192 x 1.085㎲ = 8.89㎳


1㎳의 시간동안 과연 얼마의 머신싸이클이 소요되는지를 먼저 계산합니다.


1㎳의 머신싸이클 = 1㎳ / 1.085㎲ = 921 cycles


이제 TH0레지스터는 TL0이 32분주 할 때마다 +1 증가되므로 921 / 32 = 28회 그리고 나머지가 25회, TL0은 최초에 25회만 분주해도 TH0로 자리올림이 발생하니까
결국 TH0는 29회의 카운트가 발생되어야 하는 계산이 나오네요.

따라서,

TH0 = 256 - (28 + 1)= 227 = 0xE3
TL0 = 32 - 25 = 7 = 0x07



(2) 타이머 동작모드 1

자아! 타이머0,1의 동작모드 0에 대해서 차근차근 배우고 나니, 조금 어렵긴 했지만 어느 정도 감이 잡혔습니다. 이제 동작모드1을 공부할 차례인데요. 동작모드1은 모드0보다 보다 더 쉽습니다. 왜냐하면 동작모드1은 동작모드0과 작동 원리는 동일하며, 단지 타이머의 비트수가 16비트 타이머라는 점만 다르기 때문이지요. 아래 그림을 보실까요?



[ 그림 4 : 타이머 동작모드1 의 구성 ]


[그림3]의 동작모드0과 [그림4]의 동작모드1을 비교해 보시면 어디가 다른가요? 그렇습니다. 프리스케일러(prescaler)에 해당하는 TL0/TL1 레지스터의 비트수가 5가 아니고 8이군요. 즉, TH0/TH1의 값을 +1 증가시키기 위해서 타이머는 2^8 = 256 머신싸이클 만큼 분주해야 합니다. 따라서, TH0/TH1의 8비트, TL0/TL1의 8비트를 합치면 16가 되므로 동작모드1에서 총 16비트가 사용되므로 동작모드1을 16비트 타이머라고 부르는 것입니다. 나머지는 동작모드0과 동일하므로 다른 부분만 살짝 언급해 볼까 합니다.

12MHz로 동작하는 보드의 동작모드1에서의 오버플로우비트 발생주기를 계산해 봅시다.


TH0, TL0 : 모두 1로 세팅된 경우 ==> 1머신싸이클 뒤 오버플로우 발생 ∴ 1㎲
TH0, TL0 : 모두 0으로 세팅된 경우 ==> 2^16 = 65,536 머신싸이클 뒤 오버플로우 발생 ∴ 65,536㎲ = 65.536㎳


따라서, 동작모드1을 이용하면 1㎲ ~ 65.536㎳의 타이머를 만들 수가 있겠군요.


[Q] 11.0592MHz로 동작하는 보드에서 타이머 동작모드1을 사용할 때 타이머 주기를 계산하면?

[A] 타이머의 주기는 아래와 같습니다.

T_min = 12 / (11.0592MHz) = 1.085㎲
T_max = 2^16 x T_min = 65,536 x 1.085㎲ = 71,106.56㎲ = 71.10656㎳


[실습 2] [실습1]의 소스를 이용하여 타이머0의 동작모드1을 이용해서 delay()함수를 작성한다고 가정할 때, TH0, TL0의 값을 얼마로 설정해야 할까요?

방법은 동작모드0와 다를 바가 없습니다. 먼저, 1㎳의 시간동안 과연 얼마의 머신싸이클이 소요되는지를 먼저 계산합니다.


1㎳의 머신싸이클 = 1㎳ / 1.085㎲ = 921 cycles


이제 TH0레지스터는 TL0이 256분주 할 때마다 +1 증가되므로 921 / 256 = 3회 그리고 나머지가 153회, TL0은 최초에 153회만 분주해도 TH0로 자리올림이 발생하니까
결국 TH0는 4회의 카운트가 발생되어야 하는 계산이 나오네요.

따라서,

TH0 = 256 - (3 + 1)= 252 = 0xFC
TL0 = 256 - 153 = 103 = 0x67



(3) 타이머 동작모드 2

타이머0,1의 동작모드2는 동작모드0,1과 달리 8비트의 프리스케일러만 존재합니다. 즉, 1~256 머신싸이클의 타이머로서 동작 할 수 있다는 뜻이 됩니다. 프리스케일러는 TL0/TL1이 담당했었는데, 그러면 TH0/TH1은 무슨 역할을 할까요? 앞서 제가 복습 차원에서 동작모드2는 Auto-Reload 기능을 제공한다는 말 기억나시나요? 그렇습니다. 동작모드2는 사용자가 오버플로우비트(TF0/TF1)를 클리어하여 타이머를 반복적으로 사용할 때 계수기의 초기값을 자동으로 재지정하여 일정 시간간격으로 타이머가 동작 할 수 있도록 해주는데요. 바로 계수기의 초기값이 TH0/TH1에 저장된답니다. 다시말해서, 타이머는 TH0/TH1에 저장된 초기값을 TL0/TL1로 로딩하여 그 값부터 계수를 시작합니다. TL0/TL1의 모든 비트가 1이 되어 TF0/TF1에 오버플로우비트가 세팅되면 사용자는 다시 이 값을 클리어 해주어야 하죠. 이것은 모든 동작모드가 동일합니다. 다만, TF0/TF1의 값을 클리어 해줄 때 동작모드0,1의 경우에는 TH/TL에 초기값을 다시 써 넣어주어야 하지만, 동작모드2의 경우에는 TF0/TF1을 클리어해주기만 하면 TH0/TH1에 있던 값을 TL0/TL1로 복사하여 즉시 타이머가 재시동되므로 초기값을 사용자가 재지정할 필요가 없게 되는 것입니다. [그림5]는 동작모드2의 구성을 나타내고 있습니다. Auto-Reload 기능 외의 나머지 기능은 동일합니다.



[ 그림 5 : 타이머 동작모드2 의 구성 ]



그림을 다시 들여다 보면 타이머0과 타이머1의 그림 중 타이머1쪽에만 "Serial Port" 어쩌구 하는 부분이 더 있군요. 그렇습니다. 타이머1의 동작모드2는 시리얼통신과도 관련이 있답니다. 이것은 시리얼통신 강좌에서 자세히 설명 드릴 건데요. 일단 간략히 말씀드리면, 8051에서 비동기방식으로 시리얼통신을 할 경우 basudrate를 타이머1의 동작모드2를 이용하여 설정하게 됩니다. 이 경우 타이머1의 동작모드2는 비동기시리얼통신을 위해 사용되므로 일반 타이머로서 사용할 수 없습니다. 물론, 시리얼통신을 사용하지 않을 경우엔 타이머로 사용하 실 수 있구요. 타이머0는 시리얼통신과 무관하게 타이머로 사용됩니다.

근데, 한가지 생각해 볼 것이 있네요. 동작모드2는 TL0/TL1의 8비트 프리스케일러만 사용하므로 타이머의 오버플로우비트 주기가 1~256 머신싸이클 밖에 되지 않습니다. 즉, 12MHz의 보드에서 타이머의 주기가 기껏해야 1 ~ 256㎲ 밖에 되지 않으므로 타이머 주기가 짧은 경우에만 활용이 가능합니다. 그래서, 동작모드2는 Auto-Reload라는 편리한 기능을 가지고 있으면서도 시리얼통신 용도로 주로 사용이 된답니다.


(4) 타이머 동작모드 3

이제 8051 타이머의 마지막인 동작모드3에 대해서 설명할 차례입니다. 동작모드3의 경우 제가 가지고 있는 책과 Atmel의 Datasheet의 내용과 기술하는 내용이 조금 틀린 부분들이 있어서 일단 공통적인 부분을 중심으로 설명 드리도록 하겠습니다. 일단 동작모드3의 구성을 나타내는 아래 [그림6]을 보도록 하죠.



[ 그림 6 : 타이머0의 동작모드3 의 구성 ]



결론부터 말씀드리면, 8051에서 동작모드3의 경우는 타이머0과 타이머1이 작동하는 방식과 기능이 서로 다르다는 것입니다. [그림6]은 타이머0의 구성을 나타낸 것입니다. 타이머1의 구성은 나타내지 않았습니다. (사실, 타이머1의 경우엔 마땅한 그림이 없드만요. 데이터시트에도 타이머1의 동작모드3은 고작 2줄밖에 나와있지 않습니다요. ㅠ.ㅠ) 우선, 타이머0의 경우 동작모드3으로 설정할 경우 실재로 독립된 타이머 2개를 각각 사용할 수 있습니다.

타이머0의 동작모드3의 경우엔 TH0과 TL0이 각각 별개의 8비트 타이머로서 동작합니다. 따라서, 256분주 프리스케일러로서 동작하는 셈이지요. 만약 각각의 프리스케일러의 모든 비트가 1이 된 후 오버플로우가 발생하면 TL0는 TF0가, TH0는 TF1이 각각 세팅됩니다. 어라??? TF1은 타이머1의 오버플로우비트인데 이상하게도 타이머0에서 이 녀석을 사용하고 있습니다. 게다가, 더욱 신기한 점은 TH0,TL0의 동작을 제어하는 방식도 다르다는 점입니다. 다른 동작모드의 경우 TR 혹은 GATE=1로 세팅하여 외부 INT핀으로부터 동작을 제어할수도 있었죠? 그런데, 동작모드3의 경우엔 TL0는 TR0 또는 INT0를 이용하여 타이머0의 START/STOP이 가능하지만, TH0는 TR1을 이용하여 START/STOP을 할 수 있습니다. 즉, 외부단자를 이용하여 TH0을 제어할 수 없다는 뜻이지요. 뿐만아니라, 타이머에게 공급하는 컬럭신호 역시 TL0는 내부클럭과 외부클럭을 둘다 지원하지만, TH0는 오직 내부 클럭신호만을 사용할 수 있습니다.

정리하면,
타이머0의 동작모드3는 8비트 타이머 TL0, TH0를 지원하며 TL0는 외부에서도 제어가능하나 TH0는 내부제어만 가능하다!

자! 그럼 타이머1은 어떤지 알아볼까요? 타이머1의 동작모드3은 타이머0의 TH0로 인해 동작에 있어서 제약을 받습니다. 무슨 말인고 하면... 아까 TH0의 경우에 제어는 TR1으로 한다고 했고, TH0이 오버플로우가 되면 TF1이 세팅된다고 했습니다. TH0를 TR1으로 제어하면 타이머1은 어떻게 제어할까요? 타이머1의 동작모드3은 사용자가 직접적으로는 제어할 방법이 없습니다. 단지, 타이머0의 동작모드를 3으로 했을 경우에만 간접적으로 제어가 가능합니다. 좀 더 자세히 설명을 하자면, 타이머1이 동작모드3에 있다고 합시다. 이 때 타이머0를 동작모드3으로 두면 타이머0는 TH0를 제어하기 위해 TR1과 TF1를 사용하게 되므로 타이머1은 제어할 방법이 없게 됩니다. 따라서, 이 경우엔 타이머1은 동작을 멈추게 됩니다. 반대로, 타이머0의 동작모드를 3에서 다른 모드로 바꾸면 타이머1은 동작을 계속합니다. 또한, 타이머1에서 발생하는 오버플로우는 시리얼포트로도 전송이 되어 시리얼통신을 위해서도 사용이 가능합니다.(이 부분은 마땅한 예제도 없고 자세히 기술한 자료를 찾아 볼 수도 없어서 더 깊게 설명할 능력이 안되네요. 죄송할 따름입니다. ㅠ.ㅠ)



이상으로, 타이머의 각 동작모드에 대한 설명을 끝냈습니다. 이로써 8051의 타이머와 관련된 내용은 90%이상 설명을 드린 것이나 다름 없습니다. 나머지는 여러분께서 이를 실전에 어떻게 활용하느냐에 달려 있다고 봐야 하겠죠. 오늘 배운 것들을 다시 한번 복습해 보시기 바랍니다. 복습차원에서 모드2,3에 대한 실습은 여러분께 맡기도록 하겠습니다. 본 강좌를 충분히 숙독하셨다면 어렵지 않게 동작모드2,3을 이용한 프로그램도 충분히 가능하실거라 확신합니다. 다음 시간에는 AT89S52 계열에 존재하는 타이머2에 대한 소개 및 제1~3부에서 미처 설명하지 못했던 부분에 대해서 이야기를 해볼까 합니다. 개인사정으로 3부가 조금 늦게 올라오긴 했는데... 죄송하구요. 제4부에서 뵙도록 하겠습니다. 빠~







profile
yahoosm 2007.11.25 17:31
짱!!
profile
오용 2008.01.03 08:50

정말 설명이 잘되 있네요. 많은 도움이 되었습니다. ^^

profile
kayer 2008.04.12 23:51
잘 읽을게요!!!
profile
Zosys 2008.04.21 14:02
오늘 타이머 정복 1부 부터 3부까지 읽었습니다...초보인지라...10%도 이해못한거같네요..ㅜㅜ
profile
울프썬 2008.04.23 14:27
좋은자료 감사합니다^^
profile
부기화띵 2008.04.30 14:33
어떤 책보다도 자세하게 설명되었네요...잘 보고갑니다.
profile
맑은하늘 2008.05.09 14:28

전...폴링방식만 배워서 인지...인트럽들어가니깐...조금부담...응용력이 약해서..ㅡ,.ㅡ좋은강의였습니다..짝짝짝...


profile
뿡뿡이 2008.05.18 19:25

좋은 강의 감사해요~

profile
붉은사월 2008.05.20 23:37
설명 감사요
profile
아이구머쩌라 2008.05.22 11:49
감사합니다.
profile
bug 2008.06.08 22:44

수고하셨어요

profile
A.T.O 2008.07.08 00:10
ra\감사감사
profile
사사사 2008.09.22 14:12
ㄳㄳ
profile
꿀꿀 2008.10.01 22:52
최고최고 ㅋ
profile
외뿔공룡 2008.10.10 21:00
자료 감사합니다.
profile
용가리오빠 2008.10.31 10:47
너무 어렵다ㅜㅜ
profile
용가리오빠 2008.10.31 10:47
99% 는 못알아 듣겠음...
profile
무쌍류 2009.05.01 12:38
정말좋은자료 감사합니다...
profile
por 2009.07.23 16:26
감사합니다.
keil 프로그램에서 interrupt의 설정 방법을 자세히 알고 싶습니다.
위의 예제에서 void timer0_handler() interrupt 1라고 함수를 만들었는데 interrupt1은 너디서 나온 것입니까?
자료를 찾다보니 void timer0_handler() interrupt 1  using1 으로 되어 있던데 using1(2,3,4)의 의미 차이는 무엇입니까?
profile
단단다다 2009.10.16 03:23
감사합니다!
profile
snapshot 2009.11.01 05:49
도움 많이 되네요
profile
물지않아요 2009.11.30 13:55
많은도움이되었어요!!!
profile
피타고라니 2009.12.01 16:00
학교에서 배운것보다 자세하네요
profile
평생동안 2009.12.28 10:56
정보 감사합니다~
profile
오호 2010.01.07 11:58
멋쟁이
profile
라온아비 2010.02.24 09:54
강좌 잘 봤습니다.
그런데 한가지 TF관련 해서 이해가 가지 않습니다.
타이머 강좌 2부에서 폴링 방식의 경우는 TF에 대해 초기화 해줘야 하지만 인터럽트 방식은 초기화 하지 않아도 된다고 본것 같습니다.
그런데 위 모드0에 대한 소스에선 인터럽트 방식 인데도 TF에 대해 0으로 초기화 시키는 루틴이 들어가 있더군요.
어떤게 정확한 건지 아리송 하네요...^^
profile
jyp9125 2010.04.08 17:46
수업시간에 이해가 안되서 같이 봤는데 정말좋은자료네요 ㅎㅎ
profile
흑화향 2010.04.29 11:00
요기에 올라와있는 강의 열심히 보고 타이머 부분 완전히 정복해야겠어요 ㅎ
profile
wotmd 2010.05.07 21:10
감사합니다.
profile
종박 2010.05.25 19:21
감사합니다~
profile
Do 2010.06.11 20:39
어려운 내용을 조금이나마 쉽게 알수 있을 것 같아요!
profile
박진철 2010.06.29 09:42
좋은 정보 감사합니다
profile
devilforce 2010.07.13 09:52
엑박 있어서 이해가 중간중간 안됐지만 잘 봤습니다
profile
대빵자두 2010.07.19 22:16
감사합니다
profile
Hyeon 2010.08.10 16:30

감사

profile
꼬꼬 2010.12.15 15:33

 예전에 아리송님께서 리플다신 것처럼 오버플로우 클리어하는 것이 좀 헷갈리네요

인터럽트로 처리하면 자동으로 TF0 이나 TF1이 '0' 으로 클리어 되는 것이 아닌가요?

아시는 분 답변좀 부탁드립니다.

 

profile
Interrupter 2011.09.30 08:52

좋은 자료 감사합니다.

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

감사합니다

profile
시나브로69 2017.06.24 13:03
감사합니다.
search
List of Articles
번호 분류 제목 평점 포인트 판매자 등록일 구매수 조회 수
공지 공공의 목적으로 공유하고자 하는 소프트웨어는 '소프트웨어 자료실'에 업로드를 요청드립니다.
공지 구매후 평점 댓글을 남겨주시면 구매포인트의 20%를 돌려드립니다.
200 펌웨어 & 코딩언어 AVR 128에 시리얼통신칩 설정 참고 [1] 무료 어부 2015-11-17 0 410
199 펌웨어 & 코딩언어 혼자 연구하는 c/c++ 입니다. [26] 무료 신념짱가 2013-08-23 0 1143
198 펌웨어 & 코딩언어 컴구조 공부중에 질문이요 [1] 무료 왈라c 2011-01-25 0 2982
197 펌웨어 & 코딩언어 The Art of Assembly Language [3] 무료 TreeOfDream 2011-01-16 0 2602
196 펌웨어 & 코딩언어 [펌]C언어의 기본구조 [21] 무료 스마트패넘 2010-12-16 0 3681
195 펌웨어 & 코딩언어 C언어 관련 레퍼런스 자료입니다.(C 라이브러리 사용시 유용함.) [14] 무료 승아 2010-11-06 0 3379
194 펌웨어 & 코딩언어 c언어 성적표 프로그램 [3] 무료 RTEE 2010-10-05 0 2931
193 펌웨어 & 코딩언어 c언어 잘할수있는게 [4] 무료 아기 2010-09-27 0 2436
192 펌웨어 & 코딩언어 C 언어 [3] 무료 연희야 2010-08-12 0 2386
191 펌웨어 & 코딩언어 윈도우 7 새 시스템 파티션을 만들거나 기존 시스템 파티션을 찾을 수 없습니다 무료 아크마 2010-07-22 0 8021
190 펌웨어 & 코딩언어 자바 개발 툴 [2] 무료 TreeOfDream 2010-06-21 0 2878
189 펌웨어 & 코딩언어 제가 사용하는 계산기 프로그램입니다. [7] 무료 타미아 2010-06-04 0 3715
188 펌웨어 & 코딩언어 모바일 프로그래밍 res파일 [2] 무료 니나노올 2010-06-02 0 2161
187 펌웨어 & 코딩언어 모바일 프로그래밍 게임소스 [1] 무료 니나노올 2010-06-02 0 2347
186 펌웨어 & 코딩언어 MFC로 영상이미지 역상처리하는 프로그램 [3] 무료 나얼제자 2010-05-25 0 3467
185 펌웨어 & 코딩언어 아스키 코드표 [3] 무료 siwall 2010-05-24 0 5071
184 펌웨어 & 코딩언어 RTOS 자료 두번째. [4] 무료 워터보이 2010-05-13 0 1923
183 펌웨어 & 코딩언어 RTOS 자료. [4] 무료 워터보이 2010-05-13 0 2238
182 펌웨어 & 코딩언어 InnoSetup 셋업 프로그램 만드는 프리웨어 [2] 무료 전자과조교 2010-05-04 0 2159
181 펌웨어 & 코딩언어 freescale사의 s12 instruction set 요약입니다. [2] 무료 아싸라삐야 2010-05-01 0 2303
  • 사람들로 하여금 당신을 좋아하도록 만드는 것은 당신이 그 사람들을 좋아하는 다른 측면에 불과하다.
    - 필
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.