주기적 타이머
컴퓨터나 임베디드시스템에서 주기적 타이머는 주기적으로 반복되는 동작을 하기 위해 디지털 하드웨어 회로에 의해 신호를 만든다. 이 신호에 따라 컴퓨터의 인터럽트 처리 방식을 사용하여 주기적인 작업을 수행하는 것이 일반적 처리 방법이다.[1][2]
소프트웨어 기계어 실행없이 일정 시간을 만들 수 있기 때문에 중앙 처리 장치(CPU)의 부담을 줄일 수 있다. 클럭과 디지털회로를 사용하므로 정확한 시간을 얻을 수 있다. 컴퓨터 시스템의 필수 요소이며, 현실적으로 소프트웨어로 일정 시간을 얻는 것이 아주 간단한 시스템 아니면 기계어 코드의 복잡성 때문에 힘들어 타이머에 의존한다.[3]
실시간 시계와 다르게 CPU의 클럭 신호를 주로 이용하여 디지털회로에 필요한 클럭을 만든다. 보통 CPU 클럭이 주파수가 높아 빠르기 때문에 프리 스켈일러(prescaler) 회로에 의해 주파수를 낮추어 타이머 모듈에 공급한다.[4] 카운터 회로에 의해 일정 시간이 되면 인터럽트 디지털 신호를 발생하고, CPU가 접수하면 현재 실행하는 기계어 코드를 종료한 후 해당 인터럽트 처리 루틴(ISR)을 자동 호출한다. 인터럽트 발생 여부는 레지스터 설정에 의해 선택적으로 처리할 수 있다. 인터럽트를 발생하는 부분과 인터럽트를 수용하는 CPU가 처리할 것인가는 레지스터 설정에 의해 별도로 동작 시킬 수 있다.[1][2][4]
일정 주기의 듀티를 변경하여 만드는 PWM 신호도 타이머의 카운터와 비교 회로에 의해 쉽게 만들 수 있다. 인터럽트와의 결합여부는 응용에 따라 반복적으로 같은 듀티를 사용할 수도 있고, 실행 중간에 듀티값을 변경할 수도 있다.[1]
마이크로컨트롤러에서 주기적 타이머 활용 예
[편집]컴퓨터 시스템에서 마이크로컨트롤러는 하나의 칩에 여러 가지 기능을 하는 모듈이 결합되어 있고, 이중에 가장 대표적인 모듈이 주기적 타이머이다. 대부분의 마이크로컨트롤러는 타이머를 내장하고 있다. 타이머의 구성은 각 칩에 따라 성능과 기능이 다르다. 칩의 성능에 따라 제조사에서 몇개의 타이머 모듈을 넣을 지를 결정하여 다양한 모델의 마이크로컨트롤러를 만든다.
AVR 타이머
[편집]AVR의 대표적 모델인 ATmega 시리즈는 8비트와 16비트 타이머를 사용한다.[1]
AVR8의 여러 가지 모델 중, 타이머 번호는 일반적으로 다음과 같이 배치되어 있다 :
- 타이머 0, 2: 8비트 카운터 타이머
- 타이머 1, 3: 16비트 카운터 타이머
카운터 비트수가 늘어나면 긴 주기의 시간을 만들 수 있으므로 시스템 사양에 따라 적절히 선택하여 사용하면 된다.
프리스케일러
[편집]AVR8 시리즈에서 사용하는 프리스케일러의 예에서, 시스템 클럭으로 최대 1024분주까지 얻을 수 있다. CS 레지스터의 값에 따라서 분주 값을 설정하여 빠르기를 조절할 수 있다. T0, T1외부 핀에서 입력되는 클럭으로 선택적으로 사용할 수 있다.
타이머 0
[편집]ATmega328P등의 AVR8 시리즈의 타이머0는 8비트 카운터를 사용한다. 프리스케일러로부터 입력되어 선택된 클럭을 사용하여 일정한 주기를 얻을 수 있다. 동작모드를 다양하게 설정할 수 있고, 만약 인터럽트를 사용한다면 타이머의 설정한 최댓값까지 도달하면 TOV0가 설정되고, 인터럽트 가능 레지스터 설정에 따라 인터럽트 신호가 작동한다.
AVR8의 인터럽트를 활용한 타이머0 프로그래밍 예 (avr-gcc 컴파일러를 사용할 경우) :
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
TIMSK |= (1 << TOIE0); // 인터럽트 가능하게 설정
TCCR0 |= (1 << CS01) | (1 << CS00); // 프리스케일러 64분주로 설정
sei(); // CPU가 인터럽트 받아 들여 처리 시작하게 설정
while (1)
{
// 시스템 전체를 제어
}
}
// 타이머0 오버플로워 인터럽트 핸들러
ISR (TIMER0_OVF_vect)
{
// 주기적인 일이 필요할 때, 해당 기능을 프로그래밍
}
8051 타이머
[편집]처음 모델의 8051 타이머는 2개가 장착되었다. 8051이 다양한 회사에서 출시되면서, 성능도 향상과 함께 다양한 모델이 나오면서 타이머 역시 기능과 개수가 다양하다.
타이머의 동작은 다음 두가지를 선택할 수 있다.[5]
- CPU의 동작 클럭을 이용하여 일정한 주기의 신호를 얻기
- 타이머의 클럭은 보통 CPU의 메인 클럭 신호로부터 만들어진다. 이 클럭을 기반으로 우선 프리스케일러를 통해 주파수를 낮춘다. 8051은 간단히 1/12을 사용한다. 즉, 12분주 회로를 사용하여 클럭의 속도를 낮추어 타이머 모듈의 디지털 카운터 회로에 클럭을 공급한다.
- 외부의 어떤 클럭 신호가 몇개의 펄스로 동작했는지를 카운터
- 외부의 클럭 신호를 타이머의 카운터 회로에 클럭으로 넣어 카운터 횟수를 파악할 수 있다. 즉, 어떤 클럭의 신호가 몇번 펄스가 발생했는지를 카운터하여 그 값을 프로그램으로 읽을 수 있다.
모드 설정에서 일정한 주기를 얻을 것인지 외부의 클럭신호의 카운터를 할 것인지는 레지스터 설정을 통해 일어어 진다.
8051 동작모드
[편집]- 모드 0: TH0[7:0]와 TL[4:0] 연결로 13비트 카운터로 0~8191까지 카운터 한다.
- 모드 1: TH0[7:0]와 TL[7:0] 연결로 16비트 카운터로 0~65535까지 카운터 한다.
- 모드 2: TL0[7:0] 8비트 카운터가 완료되면 TH[7:0] 레지스터 값이 TL0에 재 설정되어 카운터가 계속된다.
- 모드 3: TH0[7:0]와 TH[7:0]가 분리되어 8비트 카운터로 동작한다.
타이머 0을 사용한 프로그래밍 (Keil 통합 개발 환경) :[6]
#include <reg52.h>
#include <stdio.h>
/*------------------------------------------------
Timer 0 인터럽트 핸들러
- 65536 클럭 주기
------------------------------------------------*/
static unsigned long overflow_count = 0; // 디버깅 용으로 사용
void timer0_ISR (void) interrupt 1
{
overflow_count++; // 카운터 값 증가
}
void main (void)
{
// 타이머 0 설정 :
// 16비트 카운터 타이머 모드 설정
// 65535 카운터 후, 오버플로워가 발생하여 인터럽트 신호가 발생한다.
TMOD = (TMOD & 0xF0) | 0x01; // T/C0 모드 설정
ET0 = 1; // 타이머 0 인터럽트 가능 설정
TR0 = 1; // 타이머 0 동작 시작
EA = 1; // 8051 코어의 인터럽트 수용하여 동작 설정 - Global Interrupt Enable
while (1)
{
// 메인 루프
}
}
인터럽트 핸들러의 표현은 표준 C/C++가 아니므로 개발환경에 따라 다르다. :
/// IAR E.W. 통합 개발 환경에서 인터럽트 핸들러의 표현 ///
#pragma vector=0x0b
__interrupt void timer0_interrupt_handler(void)
{
// ...
}
/// SDCC 컴파일러에서 인터럽트 핸들러의 표현 ///
#include <mcs51reg.h>
void Timer0_ISR(void) __interrupt (1)
{
// ...
}
같이 보기
[편집]각주
[편집]- ↑ 가 나 다 라 “ATmega Timer0,1,2,3” (PDF). 2015년 7월 24일에 원본 문서 (PDF)에서 보존된 문서. 2015년 6월 18일에 확인함.
- ↑ 가 나 “8051 Timer” (PDF). 2015년 6월 18일에 원본 문서 (PDF)에서 보존된 문서. 2015년 6월 18일에 확인함.
- ↑ “Software Timing Loops”. 2015년 6월 18일에 원본 문서에서 보존된 문서. 2015년6월18일에 확인함.
- ↑ 가 나 “Introduction to Embedded Programming Timer”. 2015년 5월 8일에 원본 문서에서 보존된 문서. 2015년6월18일에 확인함.
- ↑ “Architecture and programming of 8051 MCU's, 2.6 Counters and Timers”. 2015년 8월 14일에 원본 문서에서 보존된 문서. 2015년 8월 12일에 확인함.
- ↑ “8051 타이머 0, 모드 1 예”.