일반적으로 MCU에서 입력을 받아들이는 방법에는 두 가지가 있습니다. 하나는 사용자가 명령어를 사용하여 입력 핀의 값을 계속 읽어서 변화를 알아내는 것(폴링 : polling)이고, 다른 하나는 MCU 자체가 하드웨어적으로 그 변화를 체크하여, 변화 시에만 일정한 동작을 하는 것(인터럽트 : interrupt)이 있습니다. 인터럽트가 발생했을 때 MCU는 지금까지 실행하던 프로그램을 일단 중단하고 사용자에 의해 정해진 인터럽트 서비스 루틴을 실행하게 되며, 그 루틴의 실행이 끝나면 다시 원래 실행하던 프로그램으로 돌아가서 하던 일을 계속하게 됩니다. 폴링은 모든 경우의 입력 또는 값의 변화에 대응하여 처리가 가능하지만 인터럽트는 하드웨어적으로 지원되는 몇 개의 입력 또는 값의 변화에만 대응 처리가 가능하며, 처리 속도는 일반적인 경우에 인터럽트가 더 빠르다고 할 수 있습니다.
• 인터럽트 우선순위
인터럽트 우선순위는 일단 리셋 신호가 가장 높고 그다음에는 외부 인터럽트가 높습니다.
• 내부 인터럽트 사용
내부 인터럽트는 밑의 SREG(상태 레지스터)에 인터럽트 비트만 셋 시키면 내부 인터럽트를 사용할 수 있습니다.
Bit 7(Global Interrupt Enable bit)
전체 인터럽트 인에이블 비트가 1 로 셋되어 있어야 인터럽트가 가능
(enable)해 집니다. 인터럽트가 발생하면 I-비트는 클리어되고, RETI 명령
으로 1 로 셋됩니다.
• 외부 인터럽트 사용
일단 외부 인터럽트는 사용은 안하지만 간단하게 나마 설명을 하겠습니다.
외부 인터럽트는 하강에지 또는 상승에지 또는 로(Low)레벨에서 트리거 될 수 있습니다. 트리거 되는 상태는 외부 인터럽트 제어 레지스터 (EICRA - INT3:0, EICRB - INT7:4) 로 설정합니다.
EICRA (External Interrupt Control Register A) 레지스터(외부 인터럽트 제어 레지스터 A)
외부 인터럽트 3 - 0 은 3 가지 상태로 트리거 될 수 있습니다. (아래 표 참조)
EICRB (External Interrupt Control Register B) 레지스터(외부 인터럽트 제어 레지스터 B) 외부 인터럽트 7 - 4 은 4 가지 상태로 트리거 될 수 있습니다. (아래 표 참조)
EIMSK (External Interrupt Mask Register) 레지스터(외부 인터럽트 마스크 레지스터)
상태 레지스터(SREG) 의 I-비트가 1 이고 EIMSK 레지스터의 INT7 - INT0 비트가 1 이면 인터럽트는 인에이블 됩니다.
EIFR (External Interrupt Flag Register) 레지스터(외부 인터럽트 플래그 레지스터)
에지트리거나 논리 값 변화 인터럽트가 발생하면 INT7:0 비트가 1 로 셋됩니다.
인터럽트 루틴이 실행되면 플래그는 클리어되고, 또는 플래그에 1 을 라이트하면 클리어 됩니다.
- 타이머 카운터의 오버플로우 인터럽트
타이머/카운터 0 의 오버플로우 인터럽트에 대해서 알아보겠습니다.
타이머/카운터 0 는 8 비트 카운터이고, 10 비트 프리스케일러 기능이 있습니다.
오버플로우 인터럽트(일반모드 - Normal Mode) 는 타이머/카운터 레지스터(TCNT0) 가 업 카운트하다가 오버플로우(0xFF -> 0x00) 가 되면 발생합니다.
타이머/카운터 제어 레지스터 (TCCR0) 로 모드를 선택합니다.
WGM01:00 = 00 으로 설정하면 일반모드(Normal) 가 됩니다.
타이머/카운트 0 는 10 비트 프리스케일러가 있어서 시스템 클럭을 분주해서 사용할 수 있습니다. (프리스케일러란 시스템 클럭을 분주해서 타이머/카운터 클럭 소스로 입력되는 것을 말합니다.)
프리스케일러의 선택은 CS02:00 비트로 선택합니다. CS02:00 비트가 000 일 경우는 클럭 소스를 선택하지 않은 상태로 타이머/카운터가 정지됩니다. 001 - 111 의 경우는 프리스케일러를 설정하는 값을 나타냅니다.
타이머/카운터 레지스터 (TCNT0)
bit 7 - FOC0 (Force Output Compare)
bit 6:3 - WGM01:00 (Waveform Generation Mode)
bit 5:4 - COM01:00 (Compare Match Output Mode)
bit 2:0 - CS02:00 (Clock Select)
타이머/카운터 0 의 오버플로우 인터럽트를 사용하려면 타이머/카운터 인터럽트 마스크 레지스터(TIMSK) 의 TOIE0 비트를 1 로 셋 시켜주어야 합니다.
(SREG 의 전체 인터럽트 비트(I-비트) 도 1 로 셋 되어 있어야 합니다.)
오버플로우 인터럽트가 발생하면 타이머/카운터 인터럽트 플래그 레지스터(TIFR) 의 TOV0 비트가 1 로 셋됩니다.
오버플로우 인터럽트 벡터를 실행하면 TOV0 플래그는 하드웨어적으로 제로가 됩니다.
타이머/카운터 인터럽트 플래그 레지스터(TIFR)
■ 내부 인터럽트 예제
================================================================================================
타이머/카운터0 의 오버플로우 인터럽트를 사용 LED를 점등하는 프로그램
-----------------------------------------------------------------------------
이 프로그램은 오버플로우가 발생이 될 때마다 LED를 점등하는 식으로 만들어진 프로그램입니다.
================================================================================================
#include <mega128.h>
typedef unsigned char byte;
byte cnt; //초기값 0이 지정됨
byte led = 0xEF;
interrupt [TIM0_OVF] void timer0_ovf_int(void)
{
TCNT0 = 0x00;
if(++cnt >= 10)
// 오버플로우가 되어 들어 올 때마다 cnt 1씩 증가 하여 10이 되면 들어감
{
cnt = 0;
led = (led << 1);
if(led == 0xf0) led = 0xef;
PORTD = led;
} // 들어가서 LED 점등
}
void main()
{
TIMSK = 0x01; // TOIE0 = 1(오버플로우 인터럽트 인에이블 비트 셋)
TCCR0 = 0x07; // 일반모드, 프리스케일 = CK/1024
TCNT0 = 0x00; //타이머/카운터0 레지스터 초기값
SREG |= 0x80; // 인터럽트 인에이블 비트 셋
DDRD = 0xf0;
PORTD = led;
while(1);
}
================================================================================================
'My Project > 교통정리로봇' 카테고리의 다른 글
[교통정리로봇] 프로젝트 문서 2. 관련연구(다섯번째) (0) | 2009.05.01 |
---|---|
[교통정리로봇] 프로젝트 문서 2. 관련연구(여섯번째) (0) | 2009.05.01 |
[교통정리로봇] 프로젝트 문서 2. 관련연구(여덟번째) (0) | 2009.05.01 |
[교통정리로봇] 프로젝트 문서 2. 관련연구(아홉번째) (0) | 2009.05.01 |
[교통정리로봇] 프로젝트 문서 3. 설계(첫번째) (0) | 2009.04.29 |