• 검색 결과가 없습니다.

타이머 카운터

N/A
N/A
Protected

Academic year: 2022

Share "타이머 카운터"

Copied!
42
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

CHAPTER 8, 9

타이머 카운터

가. 레지스터 구조 이해하기

나. 기초 Timer/Counter 제어하기

다. 16비트 Timer/Counter1과 Timer/Counter3 라. 기초 타이머 제어하기

마. 부저 제어하기 바. 모터 제어하기

(2)

타이머 카운터 (Timer/Counter)

3장에서 Led를 켜고 끄는 프로그램, 포트에 출력을 0과 1을 번갈아 가면서 출력 을 변경하는 프로그램을 작성해 보았다. 이때 정확한 켜고 끄는 시간을 감각적으로 60000이라는 숫자를 이용하여 지연시간을 이용하여 출력 시점을 조절하였다. 하지 만 정확한 시간 1초 3초 5초 짧게는 100ms 길게는 수분, 수 시간에 해당되는 시간 을 정확하게 컨트롤 한다는 것은 프로그램 지연방식을 이용하여 프로그래밍으로 구 현이 어려울 것이다. 이러한 마이크로 컨트롤러들은 이러한 문제를 해결하기 위해 서 내부에 타이머 서비스라는 기능을 가지고 있다.

간단하게 설명하면 타이머/카운터는 입력으로 들어오는 펄스를 셈하는 장치이며, 입력으로 들어오는 펄스가 어디에 존재하느냐에 따라서 타이머와 카운터로 나눈다.

즉, 클록의 소스가 마이크로컨트롤러의 크리스탈에 의존하면 타이머가 되소, 마이크 로컨트롤러의 외부 핀(카운터 전용 핀)에 들어오는 펄스를 셈하면 카운터가 되는 것 이다.

타이머 서비스는 일반적으로 마이크로 컨트롤러를 사용하는 과정에서 가장 많이 들어 보지만 처음 접하는 초보자들에게는 정확하게 이해하기 어려운 과정 중에 하 나라고 생각된다. 그 이유는 내부에서 동작하고 프로그램에서 정확하게 확인 하지 않으면 결과를 확인하기 어렵고 확인이 안 돼 몇 번 실패하게 되면 포기하게 되기 때문이라고 생각한다. 하지만 저자도 프로그램을 작성할 때 가장 먼저 타이머 서비 스를 이용하여 전체 시스템이 어떠한 시간에 동기 되어 동작하게 될지를 가장 먼저 설계한다. 그만큼 가장 중요한 요소 이며, 상급 이상 대단위 소프트웨어를 구성하는 과정에서도 가장 중요한 요소이다. 3장에서는 타이머 서비스에 대해서 알아보도록 한다.

Timer/Counter0은 범용적인 싱글 채널, 8 bit Timer/Counter 모듈이다. 주요 특징 아래와 같다.

w 싱글 채널 카운터

w Clear Timer on Compare Match 기능 (자동 새로 고침)

w 글리치 (노이즈 발생으로 인한 오류)가 없는 Phase Correct PWM 기능 w 주파수 발생 기능

w 10비트 프리스케일러 기능

w Timer0 Overflow Interrupt와 Timer0 Compare Match Interrupt (TOV0, OCF0)

w I/O 클록과는 독립된 외부의 32kHz를 인가 가능

(3)

가. 레지스터 구조 이해하기

Timer/Counter(TCNT0) 및 Output Compare 레지스터(OCR0)는 8비트 레지스터이 다. 인터럽트 요청신호는 모두 타이머 인터럽트 플래그 레지스터에서(TIFR)에서 확 인할 수 있다. 모든 인터럽트는 개별적인 마스크와 타이머 인터럽트 마스크 레지스 터(TIMSK)이다. 이러한 레지스터는 다른 타이머 단위로 공유되기 때문에 TIFR과 TIMSK는 표현을 할 수 없다.

이번 파트에서 나중에 자세한 내용과 같이 Timer/Counter는 프리스케일러를 통해 내부클록 또는 비동기 TOSC1/2핀에서 클록을 줄 수 있다. 비동기 작업은 비동기 상 태 레지스터(ASSR)에 의해 제어된다. Timer/Counter의 값을 증가(또는 감소)하는데 사용하는 클록소스를 클록선택 로직 블록으로 제어한다. 클록소스를 선택하지 않은 경우 Timer/Counter를 비활성화 되며, 클록을 선택하면 로직의 타이머 클록(clkT0) 으로 출력된다.

이중 버퍼 Output Compare 레지스터(OCR0)의 비교는 항상 Timer/Counter 값과 비교된다. 이 비교의 결과는 파형 발생기인 PWM 또는 가변 주파수 출력 핀(OC0)에 생성하기 위해 사용할 수 있으며, 비교하여 일치하는 이벤트는 인터럽트 요청을 발 생하기 위해 사용할 수 있는 비교 플래그(OCF0)을 설정한다.

1) Timer/Counter0 프리스케일러

Timer/Counter0을 위한 클록소스는 clkT0라 한다. clkT0는 기본적으로 메인 시스 템 클록에 연결된 clkI/O다. ASSR에 AS0비트를 설정함으로써, Timer/Counter0은 TOSC1 핀에서 비동기로 기록한다. 그래서 Timer/Counter0를 Real Timer Counter(RTC)처럼 사용이 가능하다. AS0가 설정되면, 핀 TOSC1과 TOSC2은 크리스 탈의 다음 Timer/Counter0을 위한 독립적인 클록소스의 역할을 하려고 TOSC1과 TOSC2 핀 사이에 연결을 하면 된다. 발진기는 32.768kHz의 크리스탈과 함께 사용 하기 위해 최적화 되어있어 TOSC1에 외부 클록소스를 적용하는 것을 권장하지 않 는다.

Timer/Counter0를 위하여 가능한 프리스케일의 선택은 clkT0S/8, clkT0S/32, clkT0S/64, clkT0S/128, clkT0S/256과 clkT0S/1024이다. 그리고 clkT0S 및 0(stop)을 선 택할 수 있다. PSR0 비트는 SFIOR Reset 프리스케일러에서 설정하며 사용자가 예 측한 프리스케일러로 작업한 것이 가능 하다. 프리스케일러는 자유 증가 형 (Free-Running)으로 다른 Timer/Counter와는 별개로 독립적으로 동작한다. 프리스케 일러는 다른 Timer/Counter의 클록 설정과 상관없으므로, 프리스케일러를 한번 설 정하면 재설정하기까지는 그 값을 계속해서 유지한다.

ASSR 레지스터의 AS0 비트를 “1”로 설정함으로써 Timer/Counter0을 TOSC1 핀 으로 입력되는 비동기 카운터를 사용할 수 있다. 즉, Timer/Counter0을 Real Time

(4)

Counter(RTC)로 설정하는 것이다. 이때 TOSC1과 TOSC2는 Timer/Counter0의 클록 소스가 된다. 그림 6.1에 나타나듯이 SFIOR 레지스터의 PSR0 비트를 “1”로 설정 하면 프리스케일러는 리셋 된다.

[그림 6.1] Timer/Counter0의 프리스케일

그림 6.2와 같이 SFIOR 레지스터의 기능 중 TSM, PSR0는 Timer/Counter와 관련 되어 있다.

[그림 6.2] SFIOR 레지스터

- BIT 7 : TSM(Timer/Counter Synchronization Mode)

이 비트에 “1”을 쓰면 Timer/Counter0의 동기 모드가 되며, 이 모드에서는 PSR0과 PSR321에 쓴 값은 유지된다. 그리고 “0”을 쓰면 PSR0과 PSR321에 쓴 값 은 하드웨어에 의해서 클리어 된다.

- BIT 1 : PSR0(Prescaler Reset Timer/Counter0)

이 비트에 “1”을 쓰면 Timer/Counter0의 프리스케일러가 리셋 되며, “0”을 쓰 면 영향을 미치지 않는다.

(5)

2) Timer/Counter0의 클록 소스

Timer/Counter0는 내부 동기 또는 외부 비동기 클록소스를 사용하여 클록을 사용 할 수 있다. 클록소스 clkT0는 기본적으로 MCU클록과 동일하다. ASSR 레지스터에 있는 AS0 비트에 “1”을 쓰면 클록소스는 TOSC1와 TOSC2에 연결된 Timer/Counter 발진기에서 가져온다. 또한 이 클록소스는 TCCR0 레지스터의 클록 소스 선택 비트(CS02:0)를 설정하여 사용할 수 있으며, 8비트 Timer/Counter0은 양 방향 카운터로 그림 6.3과 같이 나타낸다.

[그림 6.3] Timer/Counter0의 카운터 장

모드의 동작에 따라서, 각 타이머 클록(clkT0)에서 카운터가 클리어 되거나, 증가 또는 감소가 된다. AS0을 이용하여 외부 또는 내부 클록소스를 설정할 수 있고, 클 록 선택 비트(CS02:0)를 설정하여 사용 주파수를 분주할 수 있다.

카운터 순서는 Timer/Counter0 Control Register(TCCR0) 레지스터의 WGM01과 WGM00을 설정하여 결정할 수 있다. 그림 6.4는 8비트 Timer/Counter0의 구조를 나 타냈으며, 실제 I/O 핀은 Timer/Counter0의 핀으로 대체되었다. Timer/Counter0의 타이머 값(TCNT0)과 Output Compare Register(OCR0)는 8비트로 되어 있으며, Timer/Counter0은 내부적으로 프리스케일러를 통하여 사용할 수 있고, 외부적으로 는 TOSC1, TOSC2 핀으로 클록을 사용할 수 있다.

BOTTOM 0x00 값인 경우에 카운터는 BOTTOM에 도달한다.

MAX 0xFF 값인 경우에 카운터는 Maximum에 도달한다.

TOP

카운터의 순서에서 최대 값이 되면 카운터는 TOP에 도달하고, 이 때 TOP 값은 0xFF(MAX) 또는 OCR0 값에 정해진 값이 된다. 물론 이 값은 모드의 동작에 따라 다르다.

(6)

[그림 6.4] 8비트 Timer/Counter0의 구조

3) Timer/Counter0의 Output Compare 장치

8비트 비교기는(comparator) TCNT0와 Output Compare Register(OCR0)를 연속적 으로 비교한다. 언제나 TCNT0 값과 OCR0 값이 동일하면 비교기는 match 신호를 보낸다. 이 신호는 다음 타이머 클록 사이클에서 비교하여 Output Compare Flag(OCF0)를 Set한다.

OCIE0 비트가 “1”로 Set(OCIE0 = 1)되어 있으면, Output Compare Flag(OCF0)는 Output Compare Interrupt를 발생시킨다. OCF0 플래그는 Interrupt가 실행될 때 자 동으로 클리어 된다. 그렇지 않으면 OCF0의 I/O 비트 위치에 “1”을 쓰면 OCF0 플래그를 소프트웨어로 클리어 할 수 있다.

WGM01:0 동작 모드 비트와 COM01:0 Compare Output mode 비트의 설정에 따라 출력을 만들어 내기 위하여 파형 발생장치(waveform generator)는 match 신호를 발 생시킨다. 그림 6.5와 같이 Compare Output 장치의 구조를 나타낸다.

(7)

[그림 6.5] Timer/Counter0의 Compare Output 장치의 구조

OCR0 레지스터는 normal mode와 CTC mode인 경우를 제외하고, PWM 모드로 동 작할 경우에는 더블 버퍼로 동작한다. 더블버퍼는 카운터 순서의 TOP 또는 BOTTOM에서 OCR0 Output Compare Register에 새로운 값을 업데이트할 수 있게 해준다. non-PWM waveform generation mode에서 비교기의 match output은 Force Output Compare(FOC0) 비트에 “1”을 써서 사용할 수 있다.

4) Timer/Counter0의 Compare Match Output 장치

Compare Output mode(COM01:0) 비트는 다음과 같은 두 가지 기능으로 나뉜다.

Waveform Generator는 COM01:0 비트를 다음 Compare Match에서 Output Compare(OC0)의 상태를 정의하기 위해서 사용하고, COM01:0 비트는 OC0 핀을 출 력으로 사용한다. 그림 6.5에 COM01:0 비트를 설정하는 방법을 나타내었다.

[그림 6.6] Compare Match Output 장치

(8)

일반적인 I/O 기능은 COM01:0 비트를 어떻게 설정하느냐에 따라서 Output Compare(OC0)에 의해서 기능이 달라지기는 하나, OC0 핀의 입출력 방향은 포트의 DDRxn의 설정에 따라 변경 가능하다. 물론 이 DDR의 방향을 출력으로 설정해야 한다. Wave form Generator는 COM01:0 비트를 설정함에 따라서 normal, CTC, PWM 모드의 지정이 가능하다. COM01:0 = 0으로 설정하면, Waveform Generator는 OCR0에 어떤 값도 사용할 수 없게 된다.

5) Timer/Counter0의 동작모드

Timer/Counter와 Output Compare 핀의 동작은 Waveform Generation mode(WGM01:0) 비트와 Compare Output mode(COM01:0) 비트를 어떻게 설정하느냐 에 따라서 동작 모드를 지정할 수 있다. Waveform Generation mode는 카운터 순서 에 영향을 주지만, Compare Output mode는 카운터 순서에 영향을 주지 않는다.

Compare Output mode(COM01:0) 비트는 PWM 모드에서 non-inverting mode인지 inverting mode인지를 결정하고, non-PWM 모드에서는 compare match 시점에서 출 력이 “1”로 Set 되는지, “0”으로 클리어 되는지, 아니면 토글일지를 결정한다.

* Normal Mode

동작모드 중에서 가장 간단한 모드로 WGM01:0 = 0으로 설정하면 Normal mode가 된다. 이 모드에서 카운터 방향은 언제나 증가 모드이고, 카운터가 클리어 되지는 않는다. 카운터는 8비트 값인 TOP이 0xFF가 되면 다시 BOTTOM(0x00)에서 시작한 다. Timer/Counter Overflow Flag(TOV0)는 TCNT0 값이 “0”이 되는 시점에서

“1”로 Set 된다. 이런 경우에는 마치 9비트처럼 보일지는 모르나, Timer/Counter Overflow Interrupt가 실행되면 자동으로 “0”으로 클리어 된다.

* CTC(Clear Timer on Compare Match) Mode

그림 6.7에 CTC 모드를 나타내며, TCNT0의 값은 Compare match가 TCNT0과 OCR0 사이에서 발생할 때까지 계속 증가하다가 TCNT0 값이 클리어 된다.

[그림 6.7] CTC 모드

(9)

CTC mode(Clear Timer on Compare Mode)는 WGM01:00 = 2로 설정하여, Timer/Counter 레지스터 TCNT0의 값이 Output Compare Register(OCR0)의 값과 일 치하면 그 다음 클록 사이클에서 0으로 클리어 된다. OCR0은 카운터의 TOP 값을 지정하며, 분해능을 나타낸다.

OCF0 플래그에 의해서 카운터가 TOP 값과 일치할 때마다 인터럽트는 발생된다.

인터럽트가 enable되어 있다면, 인터럽트 서비스 루틴은 TOP 값에서 업데이트된다.

그러나 CTC 모드는 더블 버퍼로 되어 있지 않기 때문에, TOP 값을 BOTTOM 값에 가까운 곳에서 변경하면 원하지 않은 결과를 가져올 수도 있다. 만약 새로운 값이 TCNT0의 현재 값보다 낮은 값을 쓰면, 카운터는 compare match를 놓치게 된다.

CTC 모드에서 파형 출력을 만들기 위해서는, OC0 출력은 compare Output mode 비트(COM01:0 = 1)를 설정하여 토글 함으로써 만들 수 있다. OC0 값은 반드시 핀 의 DDR레지스터 값을 설정하여야만 결과를 얻을 수 있고, OCR0의 레지스터 값이

“0”으로 설정되면      주파수 값을 가지게 된다. 계산식은 아래와 같 다.

  ·· 

 

단, 여기서 N은 프리스케일러의 분주비로서 1, 8, 32, 64, 128, 256, 1024 중의 하 나에 해당한다.

* Fast PWM Mode

Fast PWM mode(WGM01:0 = 3)는 고주파의 PWM 펄스 파형을 만들어내며, 싱글 슬로프 동작을 하기 때문에 다른 PWM과는 약간 차이가 있다. 카운터는 BOTTOM에 서 MAX로 출발하여, 다시 BOTTOM에서 출발한다.

non-inverting Compare Output mode에서는, Output Compare(OC0)는 TCNT0과 OCR0의 값에서 compare match가 클리어 되고, BOTTOM에서 Set 되나 inverting Compare Output mode에서, 출력은 compare match에서 Set 되고 BOTTOM에서 클 리어 된다. 싱글 슬로프 동작이기 때문에, Fast PWM의 동작 주파수는 dual-slope operation을 이용하는 phase correct PWM mode보다 2배의 주파수가 되며 레귤레이 터, 정류 및 DAC에 적합하다.

즉, 고주파는 외부에 코일, 콘덴서와 외부 소자 등이 필요하지 않기 때문에 전체 시스템 비용이 절감된다. 이 모드에서 카운터는 카운터 값이 MAX 값에 도달하지 않는 한 계속 증가한다. 그림 6.8에 Fast PWM mode를 나타내며, Timer/Counter Over flow Flag(TOV0)는 카운터가 MAX 값에 도달할 때마다 Set 된다. 만약에 인터 럽트가 설정되어 있으면, 인터럽트 서비스 루틴에서 비교 값을 업데이트할 수 있다.

(10)

[그림 6.8] Fast PWM 모드

이 모드에서 비교 장치는 OC0 핀에 PWM 파형을 만들어 낸다. COM01:0 = 2 이 면 non-inverting PWM mode를 만들어내고, COM01:0 = 3으로 설정하면 inverting PWM mode가 된다. 실제 OC0 값은 그 핀의 DDR 값을 출력으로 설정하여야만 하 며 OCR0과 TCNT0 사이에서 OC0을 Set(또는 클리어)하여 만들어지고, 카운터가 클 리어 되는 타이머 클록 사이클에서 OC0 레지스터를 클리어(또는 Set)하여 만들어낸 다. PWM의 출력 주파수는 다음과 같다.

 ·

 

단, 여기서 N은 프리스케일러의 분주비로서 1, 8, 32, 64, 128, 256, 1024 중의 하 나에 해당한다. Fast PWM 모드에서 50%의 주기를 갖는 주파수 파형은 OCM01:0 = 1로 설정하여, OC0을 토글 하여 만들어 낼 수 있다. OCR0 값이 “0”으로 설정되 어 있는 경우에    의 최고 주파수가 된다. 이것은 CTC 모드에서 OC0이 토글 되는 것과 비슷하나, Fast PWM 모드에서는 출력 비교 장치에 더블 버퍼가 있 는 것이 다르다.

* Phase Correct PWM Mode

Phase Correct PWM 모드는 WGM01:0 = 1로 설정하면 되고, dual-slope로 동작한 다. 그래서 카운터는 BOTTOM에서 MAX로, 다시 MAX에서 BOTTOM으로 반복한다.

non-inverting Compare Output mode에서 up-counting 하는 동안에 Output Compare(OC0)은 TCNT0와 OCR0 사이에서 클리어 되고, down-counting할 때 Set 된다. inverting Compare Output mode에서는 동작이 반대로 된다. dual-slope로 동 작을 하기 때문에 single-slope 동작보다는 낮은 주파수로 동작한다. 그러나 dual-slope PWM 모드의 대칭적인 구조로 인해서 모터 제어에 적합하다. phase correct PWM 모드의 분해능은 8비트로 고정되어 있고, 카운터의 값이 MAX에 도달

(11)

할 때까지 계속 증가하고, MAX에 도달하면 카운트 방향을 바꾸게 된다. TCNT0 값 은 MAX 값과 같게 되며, 그림 6.9와 같다.

[그림 6.9] Phase Correct PWM 모드

Timer/Counter Overflow Flag(TOV0)는 카운터가 BOTTOM에 도달할 때마다 Set 되어 인터럽트를 발생시킨다. 이 모드에서 출력 비교 장치는 OC0 핀에 PWM 파형 을 출력하게 된다. COM01:0 = 2로 설정하면 non-inverting PWM이 되고, COM01:0

= 3으로 설정하면 inverting PWM이 된다. 실제 OC0 값은 핀의 DDR 레지스터를 출 력으로 설정하여 얻을 수 있으며, PWM 파형은 카운터가 증가할 때 OCR0과 TCNT0 사이에서 클리어(또는 Set)하고 down-counter일 때, OCR0과 TCNT0 사이에 서 OC0을 Set(또는 클리어)하여 만들어진다. Phase correct PWM의 출력 주파수는 다음과 같은 계산식이 된다.

 ·

 

단, 여기서 N은 프리스케일러의 분주비로서 1, 8, 32, 64, 128, 256, 1024 중의 하 나에 해당한다. 위의 그림 74의 주기 2의 시작 부분에서 Compare Match가 발생하 지 않는데도 OC0 핀이 상승에서 하강으로 변한다. 이 변화가 BOTTOM 부근에서 대칭으로 나타난다. 다음과 같은 두 경우에 Compare Match가 없이도 발생한다.

1.

위의 그림 74와 같이 OCR0 레지스터는 MAX에서 값이 변한다. OCR0 값이 MAX가 될 때, OC0 핀은 down-counting Compare Match가 일어나는 시점이 된다. BOTTOM 부근에서 대칭을 만들어 내기 위해서는 MAX에서의 OCR0 값은 up-counting Compare Match 결과 값과 동일해야 한다.

(12)

2. 타이머는 OCR00 값보다 큰 값에서 카운트하기 때문에Compare Match가 이 루어지지 않으며, 발생하려고 하는 OC0 값은 변하게 된다.

* Timer/Counter0 타이밍

Timer/Counter는 동기 회로로 이루어져 있고, 타이머 클록은 아래 그림과 같다.

그림 6.10에 Timer/Counter의 기본 동작을 나타낸다.

[그림 6.10] Timer/Counter0 타이밍(no prescaler)

[그림 6.10.1] Timer/Counter0 타이밍( prescaler)

[그림 6.10.2] Timer/Counter0 타이밍( prescaler), PWM 모드

(13)

[그림 6.10.3] Timer/Counter0 타이밍( prescaler), CTC 모드

타이머 서비스는 메인 클록 fc라고 표현하는 클록의 입력에 따른 동작 타이밍을 기준으로 카운터의 증가 값과 비교하여 동작하는 특성을 가지고 있다. 주기(T) = 1/

주파수(fc) 라는 물리적 특성을 바탕으로 ATmega128의 입력 주파수의 속도에 따른 주기를 계산하고 계산된 주기는 신호적으로 On(1), Off(0)의 신호의 형태로 마이크 로 컨트롤러에 인가되면 마이크로 컨트롤러는 0과 1의 연속적인 변화에 동기 되어 동작하게 된다.

블록 다이어그램을 보면 TOSC1 ,TOSC2에 연결되어 있는 크리스탈, 오실레이터, 레조네이터 등에서 발진되는 주파수가 입력되면 1차적으로 프리스케일러라는 분주 기로 입력되게 된다. 분주기는 입력신호가 사용될 신호가 보다 빠르게 되면 신호를 저속으로 감속 시켜주는 역할을 한다. 이러한 역할이 필요한 이유는 일반적으로 사 용하는 16Mhz의 주파수를 인가할 경우 주기를 계산하면 1/16000000=0.00000000635 초하는 시간이 계산된다. 이때 0.00000000635는 인간이 생활 하는 1초 단위 작게는 100밀리 초에 비해서 상대적으로 작은 수치임을 알 수 있을 것이다. 그러면 1초가 되기 위해서는 16백만 번 일어나야 비로소 1초가 됨을 확인 할 수 있다.

필요에 따라서 다르지만 일반적인 제어적인 마이크로 컨트롤러 사용 시 이와 같 은 속도의 제어는 실제 이루어 지지 않고 있으며 특별한 경우와 많은 데이터를 처 리해야 하는 시스템에서 사용된다. 그 이유는 로봇에서 가장 필요한 동력원인 모터 를 구동 시 모터의 기계적인 응답특성이 마이크로 컨트롤러의 동작속도 보다 느리 기 때문이다. 이러한 빠른 속도를 줄여주는 역할을 하는 것이 프리스케일러이다. 만 약 2개의 신호가 입력되면 1개의 신호 출력을 내보내 주거나, 많게는 1024개의 신 호가 입력되면 1개의 신호를 출력으로 내보내 준다. 이럴 땐 0.00000000625 시간 곱 하기 1024 만큼의 신호가 지연이 생긴다. 이것은 3장에서 배웠던 소프트웨어적인 딜레이가 아니라 내부에서 하드웨어 적으로 분주회로가 내장되어 소프트웨어의 도 움 없이 설정된 값으로 동작하게 된다. 이 같은 기능은 ATmega128이나 다른 모든 종류의 마이크로 컨트롤러에서도 기능상 조금씩의 차이는 발생할 뿐 위와 같이 동 작 한다.

(14)

이와 반대 되는 기능으로 채배 기능을 들 수 있다. 채배란 1개의 입력이 들어오 면 2개의 또는 4개 8개 등으로 부풀려 출력을 내보내 준다. 이러한 채배의 기능은 일반적인 PC에서와 같이 메인 동작 주파수가 3GHz, 2GHz등과 같이 높고 고사양의 시스템에서 입력 자체를 GHz로 입력을 받기 힘들기 때문에 외부에서 낮은 수백 MHz의 입력을 받아 내부에서 채배회로를 통하여 주파수를 풍부하게 만들고, 프로 세서 내부에서는 외부 간섭의 영향이 적기 때문에 빠른 속도로 동작할 수 있도록 만들어 준다.

타이머를 사용하기 위한 관련 레지스터를 살펴보도록 하자 본장에서 설명할 타이 머 카운터는 0번 을 사용하고 8bit의 카운터이고 최대 255까지 카운터를 할 수 있 다.

TCCR0 타이머/카운터 컨트롤 레지스터로 타이머/카운터의 여러 기능을 사용할 수 있도록 설정 하는 레지스터 이다.

TCNT0 타이머/카운터 레지스터로 계산될 값이 쓰이는 레지스터 이다.

TIMSK 타이머/카운터 인터럽트 마스크 레지스터로 타이머 사용 시 인터럽트가 발생되면 TIFR과 and연산하여 둘 다 1일 때 인터럽트가 발생한다.

TIFR

타이머/카운터 이벤트 발생 시 발생 이벤트에 해당되는 비트가 1로 설 정된다. 발생된 이벤트는 인터럽트 벡터를 처리하게 되면 자동으로 0으 로 초기화 된다.

그림 6.11을 보고 우선 TCCR0을 설정해 보도록 하자 TCCR0의 8bit 안에 4가지의 설정을 할 수 있다.

[그림 6.11] TCCR0 레지스터

force output compare, waveform generation mode, compare match output mode, clock select 이중 waveform generation mode는 Normal, PWM, Phase Correct, CTC, Fast PWM 으로 구분하게 되며, 본장에서 사용하게 될 기능은 Normal기능을 사용할 것이고 그림 6.12와 같이 기능 구분 표에서 0번의 동작을 수행할 것이다.

(15)

[그림 6.12] Waveform Generation Mode

왜 이렇게 많은 기능이 존재 하는 것일까? 라는 의문이 발생할 것이다.

Timer/Counter는 시간과 관련된 기능을 수행하는 장치라고 볼 수 있다. 주파수를 발생시키기 위해서는 시간과 관련을 갖는 프로그램을 작성해주어야 한다.

하지만 시간과 관련된 프로그램을 작성 시 단순히 주파수를 발생시켜주기만 하면 되지만 소프트웨어의 리소스가 필요하게 된다. 이럴 경우 프로그램의 크기가 커지 거나 복잡해지면 소프트웨어가 지연되는 현상 등 예상치 못한 문제점 및 프로그램 작성 시 불편한 사항이 발생 된다.

이러한 현상을 없애기 위해서 소프트웨어에서 레지스터를 설정해 놓으면 자동적 으로 주파수를 발생시키는 장치를 하드웨어 적으로 구현해 놓았고 이러한 기능을 사용하면 된다. 특히 모터 구동 등과 같은 빠른 속도에서 정밀한 제어를 위해서는 PWM과 같은 기능을 사용해야 하며, 이와 반대로 빠르게 입력되는 신호의 주기 및 주파수를 정확하게 읽어 내기 위해서는 CTC와 같은 캡처 기능을 이용하여 소프트 웨어 적으로 인터럽트가 적게 발생되어 리소스의 낭비를 줄일 수 있다. 다음으로 그림 6.13과 같이 compare match output mode를 살펴보도록 하자.

[그림 6.13] Compare Output Mode, non-PWM Mode

[그림 6.13.1] Compare Output Mode, Fast PWM Mode

(16)

[그림 6.13.2] Compare Output Mode, Phase Correct PWM Mode

이 기능은 waveform generation mode의 설정 상태에 따라서 동작이 달라진다. 일 종의 세부적은 설정으로 볼 수 있으며, waveform generation mode의 설정에 따라 세부적으로 설정하면 된다. Timer/Counter의 기능 중 가장 강력한 기능이라고 할 수 있지만 처음 배우는 입장에서 이해가 쉽지 않은 부분이다. 현재 사용할 기능은 그림 88에서 non-PWM mode의 COM00이 “0”, COM01도 “0”으로 설정하는 Normal port operation을 기능을 사용할 것이다. 다음으로 force output compare을 살펴보자 위에서 자주 언급하였던 기능 중 PWM에 대해서 설명하였다. 현재는 Timer/Counter를 PWM출력이나 CTC를 사용하지 않지만 PWM을 사용하거나 다른 기능을 사용 시 설정을 해주어야 하는 부분이다. 현재는 “0”으로 설정한다.

Timer/Counter의 기능 중 가장 중요한 요소로 clock select 기능이다. Timer/Counter 는 클록 속도에 동기화되어 수행되기 때문에 중요하다. 이때 입력된 주파수는 분주 기를 통해 분주되며 clock select 기능을 통해 분주비가 정해진다. ATmega128의 분 주 비는 clk클록을 1:1, 1:8, 1:32, 1:64, 1:128, 1:256, 및 1:1024으로 설정할 수 있으 며, 분주의 의미는 위에서 설명한 바와 같이 입력 클록을 저속으로 바꿔주는 역할 을 한다. 분주 비는 사용자가 원하는 시간을 계산하여, 계산된 시간에서 그림 6.14 에서 비율을 선택해야 한다.

[그림 6.14] Clock Select Bit

타이머/카운터 시간 계산 및 방법은 아래와 같은 식을 이용하면 된다.

(17)

  

T 주기 fc 메인클럭주파수

P prescaler C counter값

현재 CRX10에서는 fc(메인클럽주파수)가 14.7456MHz로 장착되어 있으며, 타이머 시간 계산 시 14.7456MHz의 주파수로 계산하여야 한다. 그럼 1ms의 타이머를 계산 해 보도록 하겠다. 위식에서 시간이 1ms로 정해져있고, P 값은 상수로 7가지 분주 비를 사용자가 설정 할 수 있다. 이때 C값을 결정해야 한다. 식을 다시 정리 하면 아래와 같다.

 

이때 발생되는 경우의 수는 총 7가지로 분주 비를 전부 계산해 보아야 한다. 아 래 표와 같이 첫 번째 분주비가 1일 때는 C = 0.001/(1/14745600*1)의 수식이 되며, 이때 C는 14745.6이 된다.

분주 비 수식 C 값

8 C = 0.001 / ( 1 / 14745600 * 8) 1843.2 32 C = 0.001 / (1 / 14745600 * 32) 460.8 64 C = 0.001 / (1 / 14745600 * 64) 230.4 128 C = 0.001 / (1 / 14745600 * 128) 115.2 256 C = 0.001 / (1 / 14745600 * 256) 57.6 1024 C = 0.001 / (1 / 14745600 * 1024) 14.4

0.001초를 만들기 위한 기본 계산을 끝냈다. 하지만 계산된 값들이 정확하게 떨어 지지 않고 소수점 자리를 포함한 나머지를 포함 하고 있다. 이들 중 어떤 값을 선 택해야 할지를 결정해야 하는데 Timer/Counter0은 8bit카운터로 255이상의 값을 받 아들이지 못한다. 그렇기 때문에 8bit 이상의 값이 요구 될 때는 Timer/Counter1 이 나 Timer/Counter3의 16bit카운터를 사용해야한다. 위 계산과정에서 255안에 포함되 는 계산은 분주 비 64, 128, 256, 1024일 때 8bit 255안에 포함이 되며 해당 분주 비 를 선택하고 clock select 비트에 설정하면 된다. 이때 8bit는 소수점 자리를 계산하 지 못하기 때문에 소수점 자리 나머지는 오차로 발생되게 되며, 오차를 줄이기 위 해서는 메인 클록을 1ms에 대해서 오차가 발생되지 않도록 변경해 주어야한다. 메

(18)

인 클록이 16Mhz로 계산 시

분주 비 수식 C 값

8 C = 0.001/(1/16000000 * 8) 16000 32 C = 0.001/(1/160000000 * 32) 500 64 C = 0.001/(1/16000000 * 64) 250 128 C = 0.001/(1/16000000 * 128) 125 256 C = 0.001/(1/16000000 * 256) 62.5 1024 C = 0.001/(1/16000000 * 1024) 15.625

메인 클록이 16MHz일 때는 소수점 자리의 나머지 발생되지 않고 255이내에 값을 설정할 수 있는 64, 128 분주일 때 250과 125로 설정하면 된다. 그러면 CRX10의 메 인 클록 14.7456MHz의 클록으로 계산된 시간을 기준으로 프로그램을 작성하기 위 해서 분주비가 128이고 카운터 값을 115.2로 설정하여 프로그램 작성하겠다. 오차를 최소화하기 위하여 소수점 자리의 나머지 값이 가장 작은 값으로 선택한다.

정리하면 TCCR0에 force output compare는 “0”으로 설정하였고, waveform generation mode에서 normal mode는 “0”으로 설정하고, compare match output mode에서는 “0”으로 설정하며, clock select의 분주 비는 128로 설정한다. 최종적 으로 TCCR0에는 아래 표와 같이 설정되고 10진수 5, 16진수 0x05, 2진수 0b00000101로 설정해 주고 TCNT0에는 8bit의 최대 값인 “0xff – 115”를 해줌으 로서 기본적인 설정과 카운터 값을 설정할 수 있다.

bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

0 0 0 0 0 1 0 1

나. 기초 Timer/Counter 제어하기

실제 프로그램에서 확인 해 보도록 하겠다. 그림 6.15와 같이 AVR Studio 4 프로 젝트를 생성한다.

Project name CRX10_TEX Initial file CRX10_TEX

(Create initial file과 Create folder에 체크하면 자동 생성)

(19)

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

20.

21.

#include <avr/io.h>

#include <avr/iom128.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

SIGNAL(SIG_OVERFLOW0) {

TCNT0 = 0xff - 115;

PORTB = ~PORTB;

}

int main(void) {

cli();

DDRB = 0xFF;

TCCR0 = 0x05;

TCNT0 = 0xff - 115;

sei();

TIMSK = 0x01;

while(1) {

} }

1, 2. : ATmega128 프로그램을 사용하기 위한 헤더 파일 참조 [그림 6.15] 프로젝트 생성 화면

프로젝트를 생성 하면 빈 소스코딩 창이 나타나며, 아래와 같이 프로그램을 입력 한다.

(20)

설 명

3, 4. : 새롭게 등장하는 인터럽트라는 매개체를 쓰기 위한 헤더 파일로 인터럽 트 사용에 관련된 함수를 사용할 수 있게 해준다. cli() 함수와 sei() 함수 등 과 같은 내장 함수를 사용할 수 있다.

5. : SIGNAL(SIG_OVERFLOW0)는 Timer/Counter 기능 동작 시 인터럽트가 발생 되면 점프하여 수행하는 함수로 메인함수에서 수행 중인 동작을 멈추고 이 곳으로 점프하여 { }안의 구문을 수행한다.

6. : SIGNAL()함수 시작.

7. : Timer/Counter 인터럽트가 발생하여 수행 중일 때에는 반드시 TCNT0 값을 재설정 해주어야 한다. 이미 카운터 값의 증가가 완료된 상태에서 TCNT0 값을 재설정 하지 않을 경우 카운터 값 증가가 완료된 상태에서 지속적으로 증가 할 때 원치 않는 동작을 수행할 수 있으므로 반드시 Timer/Counter 서 비스를 지속적으로 사용하고자 할 때는 반드시 초기 값을 다시 설정 해주어 야 하며, 지속적으로 서비스를 이용하지 않을 때에는 필요에 따라서 설정해 주면 된다.

8. : 포트의 신호를 C언어 연산자인 NOT을 이용하여 만약 현재 0xff 출력일 때 0x00으로 반대 신호를 출력한다.

9. : SIGNAL()함수 종료.

10. : 리턴 값 int형 main() 함수를 생성하며, 전달 값없다.

11. : 메인함수 시작.

12. : 이 함수는 내장 매크로라는 기능을 이용해서 모든 인터럽트를 사용할 수 없도록 설정하는 내장함수이다. ATmega128에는 여러 가지의 인터럽트가 존 재 한다. 최초 전원 인가 시 마이크로컨트롤러는 오실레이터 즉 메인클록이 발진하는 과정을 가지고 있다. 이 과정이 완료되기 전에 인터럽트가 발생하 면 비정상적인 동작을 가질 수 있다. 이러한 비정상적인 현상은 모든 컨트롤 러가 가지고 있는 문제로 전원 인가 시 모든 인터럽트를 사용하지 않겠다고 선언하는 구문이다.

13. : PORTB의 모든 포트를 출력으로 선언한다.

14. : Timer/Counter0의 기능을 normal mode 분주 비를 128로 설정한다.

15. : 초기 카운터 TCNT0에 0xff-115라는 값으로 설정한다.

16. : 12번의 과정에서 cli() 함수와 반대되는 개념으로 cli() 함수는 모든 인터럽 트를 사용하지 않겠다고 선언하였다고 하면 이 함수는 모든 인터럽트를 사 용할 수 있도록 설정하는 함수이다.

17. : Timer/Counter 설정과 카운터 값을 설정하였고, 이제 실제로 사용할 것인 가 사용하지 않을 것인가의 문제이다. TIMSK는 여러 가지 인터럽트의 사용 여부를 관여하는 레지스터로 Timer/Counter0에 해당되는 비트는 0번 비트이 다. 0번 비트를 “1”로 설정하게 되면, Timer/Counter0의 서비스를 사용하 겠다는 의미이다.

(21)

18. while의 ()안에 “1”이라는 참 값을 입력 시켜 무한 반복시키도록 설정한 다.

19. : while()문의 시작.

20. : 메인함수 루프 루틴 아무런 동작도 수행하지 않는다.

21. : 메인함수 종료.

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

15.

16.

17.

18.

19.

#include <avr/io.h>

#include <avr/iom128.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

unsigned char led_interval;

SIGNAL(SIG_OVERFLOW0) {

TCNT0 = 0xff - 115;

PORTB = ~PORTB;

if(led_interval >= 50) {

if((PINB & 0x80) > 0) {

PORTB = PORTB & 0x7f;

} else {

PORTB = PORTB | 0x80;

}

위 프로그램은 Timer/Counter 서비스를 이용하여 1ms에 인터럽트가 발생하면 인 터럽트 수행중인 동작을 멈추고 서비스루틴 SIGNAL(SIG_OVERFLOW0)으로 점프하 여 기능을 수행한다. 이러한 인터럽트 구조를 마이크로 컨트롤러에서 무한한 가능 성을 재고하는 기능 중의 하나이다. Timer/Counter 서비스를 이용하여 1ms로 타이 머 서비스 루틴을 구성하였다. 메인함수에는 아무런 기능도 없으며 1ms가 되면 SIGNAL(SIG_OVERFLOW0)로 이동하여 함수 안에 내용을 수행한다. 이때의 동작은 내부적으로 동작하기 때문에 사용자는 눈으로 확인하기 힘들다. 이 때문에 많은 사 용자들이 포기를 하게 되는 주요한 부분이다.

다른 예제로 14.7456MHz를 메인 클록으로 동작하는 ATmega128이 있다. 이때 2ms타이머를 설계하고 100ms에 PORTB7의 LED가 깜빡이는 프로그램을 전 프로젝 트의 소스를 주석 처리한 후에 작성한다.

(22)

20.

21.

22.

23.

24.

25.

26.

27.

28.

29.

30.

31.

32.

33.

34.

35.

36.

37.

38.

led_interval = 0;

} else {

led_interval++;

} }

int main(void) {

cli();

DDRB = 0x80;

TCCR0 = 0x06;

TCNT0 = 0xff - 115;

sei();

TIMSK = 0x01;

while(1) {

} }

설 명

1, 2. : ATmega128 프로그램을 사용하기 위한 헤더 파일 참조.

3, 4. : 인터럽트 사용에 관련된 함수를 사용할 수 있게 한다.

5. : LED를 켜기 위한 타이밍을 만들기 위해서 led_interval이라는 char형 변수 를 선언한다.

6. : SIGNAL(SIG_OVERFLOW0)는 Timer/Counter 기능 동작 시 인터럽트가 발생 되면 점프하여 수행하는 함수로 메인함수에서 수행중인 동작을 멈추고 이곳 으로 점프하여 { }안의 구문을 수행한다.

7. : SIGNAL() 함수 시작.

8. : Timer/Counter 값을 재설정 한다.

9. : 포트의 신호를 C언어 연산자인 NOT을 이용하여 만약 현재 0xff 출력일 때 0x00으로 반대 신호를 출력한다.

10. : led_interval변수의 값이 50보다 크거나 같은지 검사한다. 만약 크거나 같 으면 { }안의 내용을 수행한다.

11. : if문 시작.

12. : PORTB의 현재 출력 값을 PINB에서 읽어 온다. 이때 0x80과 AND 연산하 여 최상위 7번 비트의 결과 값만 1인지 0인지 검사 한다. 이때 결과 값은 6~0번 비트 까지는 엔드 연산결과 0으로 바뀌게 되고 7번 비트의 출력 값에 만 해당되는 결과 값에 따라서 0보다 크게 될지 같게 될지 결정된다. 만약

(23)

크다면 { }안의 구문을 실행하고, 다르면 else의 구문을 수행하게 된다.

13. : 두 번째 if문 시작.

14. : PINB값과 0x80의 연산결과 최상위 비트가 “1”일 때 127이고 0보다 크다 는 의미는 현재 PORTB7에 “1”로 출력이 발생되고 있다는 의미이다. 그러 므로 “1”에서 “0”으로 출력을 바꿔주어야 하는데 이때 다른 포트에 영 향을 주지 않도록 PORTB에 “0x7f”로 엔드 연산하여 최상위 비트를 “0”

으로 설정하고 나머지 포트들은 “0x7f”의 “1”과 엔드 연산 되는 이전 값에 따라서 “1”이 될지 “0”으로 출력이 될지 결정되게 된다.

15. : if문 종료.

16, 17. : else문 시작.

18. : PINB와 “0x80”의 연산결과가 “0”이 될 때 { }안의 구문이 실행된다.

19. : else문 종료.

20. : PINB와 “0x80”의 연산결과가 “0”이라는 의미는 현재 PORTB의 출력이

“0”으로 출력되고 있다는 의미이다. 반대로 출력을 “1”로 설정하기 위하 여 다른 포트에 영향을 주지 않도록 OR 연산하여 “0x80” 최상위 7번 비 트를 “1”로 무조건 설정하게 되고 다른 포트 들은 영향을 주지 않도록 출 력을 변경한다. led_interval 변수의 값을 “0”으로 변경하여 100ms를 만들 기 위한 변수를 초기화 한다.

21. : else문 종료.

22, 23. : else문 시작.

24. : 만약 led_interval 변수의 값이 50보다 작으면 led_interval 변수의 값에 ++

값을 더해 준다. led_interval = led_interval + 1; 과 같은 의미이다.

25. : else문 종료.

26. : SIGNAL() 함수 종료.

27. : 리턴 값 int형 main() 함수를 생성하며, 전달 값없다.

28. : 메인함수 시작.

29. : 모든 인터럽트 사용안함.

30. : DDRB포트 중 최상위 7번 비트만 “1”로 설정하여 출력으로 설정한다.

31. : TCCR0에 0x06으로 분주 비를 256으로 설정한다.

32. : TCNT0에 115의 값을 카운터 값을 설정한다.

33. : 모든 인터럽트를 사용가능하게 한다.

34. : TIMSK의 0번 비트를 “1”로 설정하여 Timer/Counter 서비스 인터럽트를 사용가능하게 설정한다.

35. : while의 ()안에 “1”이라는 참 값을 입력 시켜 무한 반복시키도록 설정한 다. 기능유지를 위하여 메인함수 무한루프로 고정.

36. : while()문의 시작.

37. : 메인함수 루프 루틴 아무런 동작도 수행하지 않는다.

(24)

38. : 메인함수 종료.

1.

2.

3.

4.

5.

6.

7.

8.

9.

10.

11.

12.

13.

14.

#include <avr/io.h>

#include <avr/iom128.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

unsigned char led_interval;

SIGNAL(SIG_OVERFLOW0) {

TCNT0 = 0xff - 147;

if(led_interval < 30) {

PORTB = PORTB & 0x7f;

} else {

분주 비 수식 C 값

8 C = 0.002/(1/14745600*8) 29491.2 32 C = 0.002/(1/14745600*32) 921.6 64 C = 0.002/(1/14745600*64) 460.8 128 C = 0.002/(1/14745600*128) 230.4 256 C = 0.002/(1/14745600*256) 115.2 1024 C = 0.002/(1/14745600*1024) 28.8

계산결과 분주 비는 256 카운터 값은 115로 결정된다. 1ms와 비교하여 두 배이기 때문에 분주 비를 2배로 변경하면 2ms로 시간이 증가 하게 된다. TCCR0 = 0x06이 고 TCNT0 = 115로 설정한다. 위 프로그램에서는 일정한 시간동안 LED가 On, Off 를 반복하는 형태의 프로그램을 2ms타이머를 설계하고, 50번의 시간을 곱해서 100ms의 시간이 되도록 설계하였다. 이처럼 타이머를 빠르게 움직이도록 하더라도 내부에서 변수를 할당하여 새롭게 계산하면 100ms뿐 아니라 수분에서 수 시간까지 시간설계가 가능하다.

Timer/Counter0의 서비스를 이용해서 메인 클록 14.7456MHz일 때 10us타이머를 설계 하고 이를 100개의 1ms로 설정한 뒤 300us는 PORTB의 7번 포트에 연결된 LED는 ON상태이고, 700us는 LED Off상태의 프로그램을 전 프로젝트의 소스를 주 석 처리한 후에 작성한다.

(25)

15.

16.

17.

18.

19.

20.

21.

22.

23.

24.

25.

26.

27.

28.

29.

30.

31.

32.

33.

34.

35.

36.

37.

38.

39.

PORTB = PORTB | 0x80;

}

led_interval = 0;

}

if(led_interval >= 100) {

led_interval = 0;

} else {

led_interval++;

} }

int main(void) {

cli();

DDRB = 0x80;

TCCR0 = 0x00;

TCNT0 = 0xff - 147;

sei();

TIMSK = 0x01;

while(1) {

} }

설 명

1, 2. : ATmega128 프로그램을 사용하기 위한 헤더 파일 참조.

3, 4. : 인터럽트 사용에 관련된 함수를 사용할 수 있게 한다.

5. : LED를 켜기 위한 타이밍을 만들기 위해서 캐릭터 형 변수를 선언해 준다.

6. : SIGNAL(SIG_OVERFLOW0)는 Timer/Counter 기능 동작 시 인터럽트가 발생 되면 점프하여 수행하는 함수로 메인함수에서 수행중인 동작을 멈추고 이곳 으로 점프하여 { }안의 구문을 수행한다.

8. : 타이머카운터 값을 재설정 한다.

9. : led_interval 값이 30 이하 인지 확인한다. 만약 30 이하 이면 { }안의 루틴 을 처리하고, 30이상일 때 else문을 처리 한다.

11. : led_interval이 30 이하일 때 PORTB7의 출력을 “0”으로 설정한다. 이때 CRX10의 LED는 low active 방식으로 0일 때 점등 된다.

13. : 만약 30이 넘으면 { }의 함수를 실행한다.

(26)

15. : PORTB7의 출력을 “1”로 설정한다. 이때 CRX10의 LED는 소등 된다.

19. : led_interval이 100과 크거나 같은지 확인 한다. 만약 크거나 같다면 { }안 의 루틴을 수행한다.

21. : 크거나 같을 때 led_interval을 “0”으로 초기화 한다.

23. : led_interval이 100보다 작을 때 { }안의 루틴을 수행한다.

25. : led_interval을 증가 시킨다.

28~38. : 이전 예제와 동일.

분주 비 수식 C 값

1 C = 0.00001/(1/14745600*1) 147.456 8 C = 0.00001/(1/14745600*8) 18.432 32 C = 0.00001/(1/14745600*32) 4.608 64 C = 0.00001/(1/14745600*64) 2.304 128 C = 0.00001/(1/14745600*128) 1.152 256 C = 0.00001/(1/14745600*256) 0.576 1024 C = 0.00001/(1/14745600*1024) 0.144

계산결과 분주 비는 1로 선택되며, 카운터 값은 147으로 결정된다. TCCR0 = 0x00 이고 TCNT0 = 147로 설정한다. 위 프로그램은 두 가지 조건을 검사하여 수행한다.

led_interval의 값의 증가를 확인하여 30이상 커졌을 경우 10us * 30은 300us가 된 다. 이때 LED는 ON되어 있고, 30이상부터 100과 같거나 작을 때까지 LED가 Off된 다. 한 사이클로 보았을 때 총 수행 시간은 1ms정도 되고 수행 주파수는 1KHz가 된다. 이와 같은 프로그램은 중요한 의미를 갖는다. On과 Off를 가지는 형태의 디 지털 시스템에서 1KHz의 주기를 가지는 신호가 On과 Off의 시간을 조절함에 따라 서 일이라는 물리적인 특성을 파악 할 수 있다. 일 = 한일/단위시간당 이다. 이때 단위 시간은 1KHz라는 주파수에서 찾을 수 있고, 한일은 단위 시간당 On과 Off의 평균값을 의미한다. 현재는 현재 약 1ms를 기준으로 300us라는 점유율 30%정도의 일을 수행 하였으므로 총 일의 양은 30%라고 볼 수 있다. 이를 이용하여 점유율을 조정하게 되면 LED의 밝기가 변하는 모습을 볼 수 있다.

응용 예제로 Timer/Counter0의 서비스를 이용해서 메인 클록 14.7456MHz일 때 10us타이머를 설계 하고 이를 100개의 1ms로 설정한 뒤 PORTB의 7번 포트에 연결 된 LED는 On과 Off를 시간을 조절 하여 밝기가 바뀌는 프로그램을 전 프로젝트의 소스를 주석 처리한 후에 작성한다.

Timer/Counter0의 레지스터 외에도 Timer/Counter2가 ATmega128에 내장되어있으 며, 사용방법은 Timer/Counter0의 사용방법과 비슷하다. 각 레지스터의 뒤에 “0”

(27)

대신 “2”가 붙는다. 다만, 채널이 부족하여 사용할 경우에만 사용하는 레지스터이 다. 자세한 설명은 Datasheet를 참조하도록 하며, 두 번째로 자주 사용하는 16비트 Timer/Counter1과 Timer/Counter3을 설명한다.

다. 16비트 Timer/Counter1과 Timer/Counter3

Timer/Counter1과 Timer/Counter3은 범용 타이머로서 16비트로 구성되어 있으며 다음과 같은 특징이 있다.

w 16비트 타이머로 PWM 16비트까지 지원 w 3개의 독립된 Output Compare 기능

w 더블 버퍼로 구성된 Output Compare Register w 1개의 Input Capture 기능

w Compare Match에서의 Clear Timer 기능(Auto Reload) w 글리치가 없는 Phase Correct PWM 기능

w 가변 PWM 기능 w 주파수 발생 장치 w 외부 이벤트 카운터

w 10개의 족립된 인터럽트 소스(TOV1, OCF1A, OCF1B, OCF1C, ICF1, TOV3, OCF3A, OCF3B, OCF3C, ICF3)

1) Timer/Counter1, 3의 프리스케일러

Timer/Counter1과 Timer/Counter2, Timer/Counter3은 동일한 프리스케일러를 사용 하지만 프리스케일러를 설정하는 방법이 다르다. Timer/Counter는 시스템 클록을 CSn2:0 = 1로 설정하여 직접 받아서 사용할 수도 있으나, 이것은 시스템 클록 주파

수( )의 최고 속도를 그대로 사용하므로 상당히 빠른 주파수가 된다. 그래서

프리스케일러를 클록의 입력으로 사용하는데,  ,  ,  ,

 로 각각 사용할 수 있다. 프리스케일러는 자유 증가 형으로

Timer/Counter와는 별개로 독립적으로 동작하나, Timer/Counter1과 Timer/Counter2, Timer/Counter3은 함께 사용한다. 프리스케일러는 Timer/Counter의 클록 설정과 상 관없으므로, 프리스케일러를 한번 설정하면 재설정하기까지는 그 값을 계속해서 유

(28)

지한다.

PD6/PD7/PE6 (T1/T2/T3) 핀에 입력되는 외부 클록 소스는 Timer/Counter의 클록 (, , )으로 사용될 수 있다. PD6/PD7/PE6 (T1/T2/T3) 핀의 클록은 시스 템 클록의 매 사이클에서 핀 동기가 이루어진다. 그림 6.16은 PD6/PD7/PE6 (T1/T2/T3) 핀의 동기 로직과 에지 검출 장치를 나타내었다. 이 에지 검출 장치는 CSn2:0 = 7이면 상승 에지로, CSn2:0 = 6이면 하강 에지로 검출한다.

[그림 6.16] 동기장치와 에지 검출 장치

동기 장치와 에지 검출 장치는 PD6/PD7/PE6(T1/T2/T3) 핀에 클록이 입력되고 나 서 2.5~3.5 시스템 클록만큼의 지연시간이 걸린다. 에지 검출 장치는 샘플링을 사용 하기 때문에 외부 최대 주파수는 샘플 주파수의 절반 이상을 넘기면 안 된다. 그림 6.17에 Timer/Counter0과 Timer/Counter1의 프리스케일러를 나타내었다.

[그림 6.17] 프리스케일러

그림 6.18과 같이 Special Function IO Register(SFIOR)의 기능을 나타내었다.

[그림 6.18] SFIOR 레지스터

(29)

- BIT 7 : TSM(Timer/Counter Synchronization Mode)

“1”을 쓰면 Timer/Counter0의 동기 모드가 된다. 이 모드에서는 PSR0과 PSR123 에 쓴 값은 유지된다. 반대로 “0”을 쓰면 PSR0과 PSR123에 쓴 값은 하드웨어에 의해서 클리어 된다.

- BIT 0 : PSR123(Prescaler Reset Timer/Counter1, 2, 3)

“1”을 쓰면 Timer/Counter1, 2, 3의 Prescaler가 리셋 된다. 반대로 “0”을 쓰 면 아무 영향을 미치지 않는다. 만약에 Timer/Counter1, 2, 3이 비동기 모드로 동작 할 경우에 이 비트에 특정 값을 쓰면 프리스케일러가 리셋 될 때까지“1”의 값을 유지하게 된다.

2) Timer/Counter1, 3의 클록 소스

Timer/Counter1, 3은 내부 및 외부의 클록 소스를 사용하여 클록으로 사용할 수 있다. 이 클록 소스는 TCCRnB 레지스터의 클록 소스 선택 비트(CSn2:0)를 설정하여 사용할 수 있으며, 16비트 Timer/Counter1, 3은 양방향 카운터로 아래 그림 6.19와 같이 나타내었다.

[그림 6.19] 양방향 카운터

count Increment or decrement TCNT1 by 1 direction Selects between increment and decrement

clear Clear TCNTn(set all bits to zero)

 Timer/Counter clock

top Signalizes that TCNTn has reached maximum value bottom Signalizes that TCNTn has reached minimum value(zero)

(30)

모드 동작에 따라서, 각 타이머 클록()에서 카운터가 클리어 되거나, 증가하 거나, 감소한다. 는 외부 또는 내부 클록 소스를 발생할 수 있고, 클록 선택 비 트 CSn2:0을 설정하여 사용 가능하다. 카운터 순서는 Timer/Counter1 Control Register TCCRn 레지스터의 WGMn1과 WGM0을 설정하여 결정할 수 있다. 아래 그 림은 16비트 Timer/Counter1, 3의 구조를 나타내었으며, 실제 IO 핀은 Timer/COunter1, 3의 핀으로 대체되었다. Timer/Counter1, 3의 타이머 값(TCNTn)과 Output Compare Register(OCRn)는 16비트로 되어 있으며, Timer/Counter1, 3은 내 부적으로는 프리스케일러를 통하여 사용할 수 있고, 외부적으로는 T1 또는 T3 핀으 로 클록을 사용할 수 있다. 그림 6.20은 타이머 카운터 블록도를 나타낸다.

BOTTOM 0x0000 값인 경우에 카운터는 BOTTOM에 도달한다.

MAX 0xFFFF 값인 경우에 카운터는 Maximum에 도달한다.

TOP

카운터의 순서에서 최대 값이 되면 카운터는 TOP에 도달하고, 이때 TOP 값은 0x00FF 또는 0x01FF, 0x03FF 또는 OCRnA, ICRn 값에 정 해진 값이 된다.

[그림 6.20] 타이머 카운트 블록도

(31)

3) Timer/Counter1, 3의 Input Capture 장치

Timer/Counter1, 3에는 Input Capture 장치가 내장되어 있어서 외부 이벤트를 검 출하여 사건이 발생한 시간을 저장할 수 있다. 하나의 신호 및 다양한 신호로 발생 되는 외부 신호는 ICPn 핀 또는 Analog Comparator를 통하여 접근 가능하다. 이 기 능을 이용하여 신호의 주파수 및 듀티비를 계산할 수 있다. 입력 캡처 핀(ICPn) 또 는 아날로그 비교기의 출력(AC0)에서 발생된 신호 변화를 신호 검출기에서 검출하 여 캡처가 이루러진다. 캡처가 발생되면 16비트 카운터 값(TCNTn)은 입력 캡처 레 지스터(ICRn)에 저장되고, 이와 동시에 입력 캡처 플래그(ICFn)는 “1”j로 세서된 다. 만약 SREG의 I비트가 “1”로 설정되어 있고, TICIEn = 1로 설정되어 있으면 입력 캡처 인터럽트가 발생된다. 이 인터럽트가 실행이 되면 ICFn은 자동으로

“0”으로 클리어 된다. 아니면 ICFn에 직접 “1”을 쓰면 클리어 시킬 수도 있다.

입력 캡처 레지스터(ICRn)를 읽을 경우에는 하위 바이트(ICRnL)를 먼저 읽고 난 후 에 상위 바이트(ICRnH)를 읽어야 하고, 하위 바이트를 읽을 때 상위 바이트는 임시 저장 레지스터에 저장된다.

ICRn 레지스터는 카운터의 TOP 값을 설정할 때 사용되는 Waveform Generation mode에서만 적용된다. 이 경우에 Waveform Generation mode(WGMn3:0) 비트는 TOP 값이 ICRn 레지스터에 쓰기 전에 설정해야만 한다. ICRn 레지스터에 값을 쓸 경우에는 읽을 때와는 반대로 상위 바이트(ICRnH)를 먼저 쓰고 하위 바이트(ICRnL) 를 써야만 한다. 아래 그림과 같이 Input Capture 장치의 주요 트리거 소스는 입력 캡처 핌(ICPn)에 의해서 이루어지며, Timer/Counter1은 Input Capture 장치를 아날로 그 비교기의 출력(AC0)을 대신 이용할 수도 있다. 그림 6.21은 타이머/카운터의 Input Capture 장치를 나타낸다.

[그림 6.21] 타이머/카운터의 Input Capture 장치

(32)

ACSR 레지스터의 Analog Comparator Input Capture(ACIC) 비트를 설정하여 선택 할 수 있다. 트리거 소스를 변경하려면 Input Capture flag를 “0”으로 클리어한 후에 바꾸어야하고, ICPn과 AC0 입력은 Tn 핀의 동일한 시점에서 샘플링 되며, 에 지 검출기도 마찬가지이다. 그러나 노이즈 제거기가 설정되면, 에지 검출기 앞에 추 가 로직이 삽입되는데 이로 인해서 4개의 사이클이 늘어난다. 노이즈 제거기는 간 단한 디지털 필터를 통하여 입력해 들어오는 펄스의 노이즈를 제거한다. 이 때 4개 를 샘플링 하여 동일한 경우에만 그 값을 인정하게 된다. 노이즈 제거기를 설정하 기 위해서는 TCCRnB 레지스터의 Input Capture Noise Canceler(ICNC) 비트를 “1”

로 설정함으로써 가능하다.

4) Timer/Counter1, 3의 Output Compare 장치

16비트 비교기는 연속해서 TCNTn 값과 OCRnx 값을 비교해 나간다. TCNTn 값과 OCRnx 값이 같을 때마다 비교기는 match 신호를 발생한다. match신호는 타이머 클록의 다음 사이클에서 Output Compare Flag(OCFnx)를 셋하고, OCIEnx비트와 SREG 레지스터의 I비트가 “1”로 셋 되어 있으면, OCFnx는 Output Compare Interrupt를 발생한다. OCFnx 플래그는 인터럽트가 실행이 되고 나면 자동으로 클리 어 된다. 아니면, OCFnx 비트에 “1”을 써 소프트웨어적으로 클리어 하여도 된다.

WGMn3:0 동작 모드 비트와 COMnx1:0 Compare Output mode 비트의 설정에 따라 서 출력을 만들어 내기 위하여 파형 발생장치(wavwform generator)는 match 신호 를 발생시킨다. 아래 그림 6.22는 Compare Output 장치의 구조를 나타낸다.

[그림 6.22] Compare Output 장치의 구조

(33)

OCRnx 레지스터는 normal mode와 CTC mode인 경우를 제외하고, PWM 모드로 동작할 경우에는 더블버퍼로 동작한다. 더블버퍼는 카운터 순서의 TOP 또는 BOTTOM에서 OCR1x에 새로운 값의 업데이트를 가능하게 한다. non-PWM waveform generation mode에서, 비교기의 match output은 Force Output Compare(FOCnx) 비트에 “1”을 써서 사용할 수 있다.

5) Timer/Counter1, 3의 Compare Match Output 장치

Compare Output mode(COMnx1:0) 비트는 다음과 같은 두 가지 기능으로 나뉜다.

Waveform Generation은 COMnx1:0 비트를 다음 compare match에서 Output Compare(OCnx)의 상태를 정의하기 위해서 사용하고, COMnx1:0 비트는 OCnx 핀을 출력으로 사용한다. 아래 그림에 COMnx1:0 비트를 설정하는 방법을 나타내었다. 일 반적인 I/O 기능은 COMnx1:0 비트를 어떻게 설정하느냐에 따라서 OCnx에 의해서 기능이 달라지기는 하나, OCnx 핀의 입출력 방향은 포트의 DDR의 설정에 따라 변 경 가능하다. 물론 이 DDR의 방향을 출력으로 설정하여야만 한다. Waveform Generation은 COMnx1:0 비트를 설정함에 따라서 normal, CTC, PWM 모드의 지정이 가능하다. COMnx1:0 = 0으로 설정하면, Waveform Generation은 OCRnx에 어떤 값 을 사용할 수 없게 된다. 그림 6.23은 Compare Match Output 장치의 구조를 나타 낸다.

[그림 6.23] Compare Match Output 장치의 구조

6) Timer/Counter1, 3의 동작 모드

동작 모드, 즉 Timer/Counter와 Output Compare 핀의 동작은 Waveform Generation mode(WGMn3:0) 비트와 Compare Output mode(COMnx1:0) 비트를 어떻

(34)

게 설정하느냐에 따라서 동작 모드를 지정할 수 있다. Waveform Generation mode 는 카운터 순서에 영향을 주지만, Compare Output mode는 카운터 순서에 영향을 주지 않는다. COMnx1:0 비트는 PWM 모드에서 non-inverting mode인지 inverting mode인지를 결정하고, non-PWM 모드에서는 compare match 시점에서 출력이

“1”로 셋 되는지, “0”으로 클리어 되는지, 아니면 토글일지를 결정한다.

* Normal Mode

동작 모드 중에서 가장 간단한 모드로 WGMn3:0 = 0으로 설정하면 Normal mode 가 된다. 이 모드에서는 카운터 방향은 언제나 증가 모드이고, 카운터가 클리어 되 지는 않는다. 카운터는 16비트 값인 TOP가 0xFFFF으로 되면 다시 BOTTOM(0x0000)에서 시작한다. Timer/Counter Overflow Flag(TOVn)는 TCNTn 값이

“0”이 되는 시점에서 “1”로 셋 된다. 이런 경우에는 마치 17비트처럼 보일지는 모르나, Timer/Counter Overflow Interrupt가 실행되면 자동으로 “0”으로 클리어 된다.

* CTC(Clear Timer on Compare Match) Mode

CTC mode는 WGMn3:0 = 4 또는 12로 설정하여, Timer/Counter 레지스터 TCNTn 의 값이 OCRnA(WGM13:0 = 4) 또는 ICRn(WGM13:0 = 12)의 값과 일치하면 그 다음 클록 사이클에서 0으로 클리어 된다. OCRnA 또는 ICRn은 카운터의 TOP 값을 지정 하며, 분해능을 나타낸다. 아래 그림 6.24는 CTC 모드를 나타내었다. TCNTn의 값은 Compare match가 TCNTn과 OCRnA 또는 ICRn 사이에서 발생할 때까지 계속 증가 하다가 TCNTn 값이 클리어 된다.

[그림 6.24] CTC 모드

OCFnx 플래그에 의해서 카운터가 TOP 값과 일치할 때마다 인터럽트는 발생된다.

인터럽트가 enable되어 있다면, 인터럽트 서비스 루틴은 TOP 값에서 업데이트된다.

그러나 CTC 모드는 더블 버퍼로 되어 있지 않기 때문에, TOP 값을 BOTTOM 값에 가까운 곳에서 변경하면 원하지 않은 영향을 가져올 수도 있다. 만약 새로운 값이

(35)

TCNTn의 현재 값보다 낮은 값을 쓰면, 카운터는 compare match를 놓치게 된다.

CTC 모드에서 파형 출력을 만들기 위해서는, OCnA 출력은 Compare mode 비트 (COMnA1:0 = 1)를 설정하여 토글 함으로써 만들 수 있다. OCRnA 값은 반드시 핀 의 DDR 레지스터 값을 설정하여야만 결과를 얻을 수 있고, OCRnA의 레지스터 값 이 “0”으로 설정되면     주파수 값을 가지게 된다. 계산식은 다음과 같다.

   ·· 



(36)

A :

#include<avr/io.h>

#include<avr/signal.h>

unsigned char count, data;

void main(void) {

DDRA=0xFF;

DDRC=0xFF;

TCCR0=0x07;

TCNT0=0xFF-157;

TIMSK=0x01;

TIFR|=0x01;

sei();

while(1) {

PORTA=0xFF;

PORTC=data;

} }

SIGNAL(TIMER0_OVF_vect) {

cli();

라. 기초 타이머 제어하기 1) 활용 실습

Q : 6.1_ 도트매트릭스의 전체를 1초에 한 번씩 깜박이게 하기

(37)

TCNT0=0xFF-157;

count++;

if(count==100) {

data=0xFF;

count=0;

}else {

data=0x00;

} sei();

}

A :

#include<avr/io.h>

#include<avr/signal.h>

unsigned char count, cnt, data;

void main(void) {

DDRA=0xFF;

DDRC=0xFF;

DDRE=0xFB;

TCCR0=0x07;

TCNT0=0xFF-157;

TIMSK=0x01;

Q : 6.2_ 도트매트릭스의 세로열 전체(한줄)가 좌로부터 우로 0.5초에 한번씩 깜박이며, 한칸씩 줄어들면서 이동하게 하기

(38)

A :

#include<avr/io.h>

#include<avr/signal.h>

unsigned char count;

TIFR|=0x01;

sei();

while(1);

}

SIGNAL(TIMER0_OVF_vect) {

cli();

TCNT0=0xFF-157;

if(count==50) {

count=0;

cnt=-1;

}else {

PORTA=0xFF<<cnt;

PORTC=0xFF;

data=0x00;

} cnt++;

count++;

sei();

} 참고 :

그동안 학습 한 내용을 기반으로 프로그램을 작성하시오.

Q : 6.3_ 도트매트릭스에 자기이름의 이니셜이 1초에 한번 씩 깜박이며 출력되 게 하기

(39)

unsigned int data=0;

void m_delay(unsigned int k) {

unsigned int i, j;

for(i=0; i<2000; i++) for(j=0; j<k; j++);

}

void name(unsigned int s) {

if(s==1) {

PORTA=0x02;

PORTC=0x70;

m_delay(1);

PORTA=0x04;

PORTC=0xF0;

m_delay(1);

PORTA=0x08;

PORTC=0xC0;

m_delay(1);

PORTA=0x10;

PORTC=0xC0;

m_delay(1);

PORTA=0x20;

PORTC=0xFF;

m_delay(1);

PORTA=0x40;

PORTC=0x7E;

m_delay(1);

PORTA=0xFF;

PORTC=0x00;

m_delay(1);

}else if(s==2) {

PORTA=0x02;

(40)

PORTC=0xFF;

m_delay(1);

PORTA=0x04;

PORTC=0xFE;

m_delay(1);

PORTA=0x08;

PORTC=0x18;

m_delay(1);

PORTA=0x10;

PORTC=0x18;

m_delay(1);

PORTA=0x20;

PORTC=0xFF;

m_delay(1);

PORTA=0x40;

PORTC=0xFE;

m_delay(1);

PORTA=0xFF;

PORTC=0x00;

m_delay(1);

}else if(s==3) {

PORTA=0x02;

PORTC=0x0F;

m_delay(1);

PORTA=0x04;

PORTC=0x1E;

m_delay(1);

PORTA=0x08;

PORTC=0xF8;

m_delay(1);

PORTA=0x10;

PORTC=0xF8;

m_delay(1);

PORTA=0x20;

PORTC=0x1F;

m_delay(1);

(41)

PORTA=0x40;

PORTC=0x0E;

m_delay(1);

PORTA=0xFF;

PORTC=0x00;

m_delay(1);

} }

void main(void) {

DDRA=0xFF;

DDRC=0xFF;

DDRE=0xFB;

TCCR0=0x07;

TCNT0=0xFF-145;

TIMSK=0x01;

TIFR|=0x01;

sei();

while(1){}

}

SIGNAL(TIMER0_OVF_vect) {

cli();

TCNT0=0xFF-145;

count++;

if(count==100) {

data++;

name(data);

count=0;

if(data==3)

(42)

{

data=0;

} }

sei();

}

참조

관련 문서

To create a smooth path with continuous position and velocity, we start with the linear function but add a parabolic blend region at each path point.. During the blend portion

The PWM waveform is generated by setting (or clearing) the OC2x Register at the compare match between OCR2x and TCNT2, and clearing (or setting) the OC2x Register at the

모드 단일 노드 인스턴스로 되어있는 standalone mode 다수의 노드 인스턴스들을 관리할 수 있는 domain mode...

PWM mode implements current limiting using an internal comparator that trips at 2 A for both bucks (typical). If the output is shorted to ground the device enters a timed

The paper examines the incentives of power generating companies (GENCOs) for efficient fuel procurement for power generation under the Cost-Based Generation

Population (toe/mil.. Generating Facilities Unite: MW.. Electric Power Generation by Facilities Unit: GWh.. Electric Power Generation by Energy Source Unit: GWh..

Changes of lactic acid bacteria numbers and photodiode during fermentation mode and storage mode in S kimchi · · ·40..

Through the superposition modeling of single hole waveform, I obtained the vibration waveform on the blasting condition changes and conducted dynamic