3. --33--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-1 인터럽트의 개요
⊙ embedded program은 interrupt-driven (event-driven)방식
⊙ 외부의 하드웨어적인 요구에 의해서 정상적인 프로그램의 실행 순서를 변경하여 보다
시급한 작업을 먼저 수행한 후에 다시 원래의 프로그램으로 복귀하는 것
⊙ Interrupt 와 polling 방식의 비교
- 집에 손님이 왔는지 알아내는 방법
-> polling : 1분에 한번씩 대문에 나가 봄
-> interrupt : 손님이 초인종을 사용
⊙ 주변장치의 서비스 요청에 CPU가 가장 빠르게 대응할 수 있는 방법
⊙ 인터럽트 발생시 나중에 되돌아 올 복귀주소(return address)가 자동적으로 스택에
저장되었다가 인터럽트 서비스 루틴의 마지막에서 복귀(return) 명령을 만나면 다시
자동적으로 이 복귀주소가 찾아져서 인터럽트 발생전의 위치로 정확하게 되돌아감.
4. --44--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 인터럽트의 종류
⊙ 인터럽트 발생 원인에 따른 분류
- 하드웨어 인터럽트
-> 내부 인터럽트 : 나눗셈 에러, 보호된 메모리 영역에의 접근 등의 원인
-> 외부 인터럽트 : 타이머, 직렬포트, A/D변환 완료, DMA 동작의 종료
- 소프트웨어 인터럽트
⊙ 인터럽트 발생시 마이크로프로세서의 반응 방식에 따른 분류
- 차단 가능 인터럽트(INT; maskable interrupt) : EIMSK, SEI, CLI
- 차단 불가능 인터럽트(NMI; non-maskable interrupt) : ATmega128에는 사용 안함
⊙ 인터럽트를 요구한 입출력 기기를 확인하는 방법에 따른 분류
- 벡터형 인터럽트(vectored interrupt)
- 조사형 인터럽트(polled interrupt)
5. --55--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-3 폴링 방식의 실습 1
☞ 포트 C로 외부 신호를 입력 받아 포트 B로 LED를 연결 후 카운터 값을 출력하는 프로그램
⊙ Counter의 제작
- Port B: LED에 연결
- Port C.0 : switch를 연결
- switch를 누를 때마다, 변수 count값이 1씩 증가, 그 값을 Port 의 LED를 통해 표시
⊙ Counter Program (Polling 방식)
int count = 0;
DDRC = ______;
DDRB = ______;
while ( 1 ) {
/* 어떤 작업 A를 수행함 */
if ( switch가 눌러 지면 ) {
++count;
PORTC = ~count;
/* LED는 해당 bit가 0이면 켜짐 */
delay_ms(100); // 1초딜레이
}
6. --66--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-3 폴링 방식의 실습 1
☞ 포트 C로 외부 신호를 입력 받아 포트 B로 LED를 연결 후 카운터 값을 출력하는 프로그램
#include <mega128.h>
#include <delay.h>
void main(void)
{
unsigned char count=0; // count 변수 선언
DDRB = 0xff; // 포트 B를 출력으로 설정
DDRB = 0xff; // 포트 B에 연결된 LED를 OFF
DDRC = 0x00; // 포트 C를 입력으로 설정
PORTC = 0xff; // 내부 풀업저항 사용
while (1)
{
if(PINC.1 == 0) // SW2가 눌러졌는지를 체크
{
++count; // count를 1 증가
}
PORTB = ~count; // count값을 포트 B에 LED출력
delay_ms(100);
};
}
7. --77--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-3 폴링 방식의 실습 1
⊙ Counter Program (polling)의 문제점
- 스위치가 눌려 졌는지를 확인하는 것이 쉽지 않음
- 쓸데 없이 스위치가 눌려 졌는지를 확인하는데 많은 시간을 소모하고 있음
while ( 1) {
작업 A
if ( switch 눌려짐 ) {
++count;
PORTB = ~count;
}
작업 B
}
AVR
switch
계속해서
check
8. --88--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 1
⊙ Interrupt의 사용: register (MCUCR, GIMSK)
- Interrupt의 사용 여부 결정
(reset시 설정: interrupt 사용하지 않음)
- 어떤 Interrupt Source를 사용할 지를 결정
(interrupt source: 외부 신호, timer, ... )
- Interrupt Service Routine의 작성
(interrupt가 걸렸을 때, 어떤 일을 할 것인가?)
⊙ External Interrupt
- AVR 외부의 입력을 interrupt의 source로 사용
- INT1 (PD1)
⊙ External Interrupt을 사용하기 위해서는?
(1) DDRD의 setting
- INT1 사용시 PD1를 입력으로 지정
(2) External Interrupt의 mode를 설정
(3) External Interrupt의 mask를 설정
(4) 전체적인 Interrupt를 enable 시킴
9. --99--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 2
⊙ 외부 인터럽트는 8개의 외부핀 INT7~0을 통해 입력되는 신호에 의하여 발생되는 인터럽트
⊙ 외부 인터럽트는 L의 논리레벨, 하강에지, 상승에지 등에 의하여 트리거 될 수 있음
⊙ 외부 인터럽트 제어 레지스터 EICRA(INT3~0) 및 EICRB(INT7~4)로 모드 설정
10. --1010--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 3-1
⊙ 외부 인터럽트 제어 레지스터A : EICRA (INT3~0)
INTn 핀의 상승에지가 인터럽트를 트리거한다11
INTn 핀의 하강에지가 인터럽트를 트리거한다01
(reserved)10
INTn 핀의 로우레벨 신호 입력이 인터럽트를 트리거한다00
인터럽트 트리거 방식ISCn0ISCn1
외부 인터럽트 제어 레지스터A : EICRA (INT3~0)
Value
EICRA
BIT
00000000
ISC00ISC01ISC10ISC11ISC20ISC21ISC30ISC31
01234567
11. --1111--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 3-2
⊙ 외부 인터럽트 제어 레지스터 B : EICRB (INT7~4)
외부 인터럽트 제어 레지스터 B : EICRB (INT7~4)
Value
EICRB
BIT
00000000
ISC40ISC41ISC50ISC51ISC60ISC61ISC70ISC71
01234567
INTn 핀의 상승에지가 인터럽트를 트리거한다11
INTn 핀의 하강에지가 인터럽트를 트리거한다01
INTn 핀의 하강에지 또는 상승에지가 인터럽트를 트리거한다10
INTn 핀의 로우레벨 신호 입력이 인터럽트를 트리거한다00
인터럽트 트리거 방식ISCn0ISCn1
12. --1212--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 4
⊙ 외부 인터럽트 마스크 레지스터 : EIMSK
각 비트를 1로 설정하면 인터럽트 허용, 허용된 인터럽트는 다사 SREG 레지스터의 글로벌 인터럽트
허용비트 I 가 1로 설정되어야만 실제 허용상태가 된다
⊙ 외부 인터럽트 플래그 레지스터 : EIFR
EIFR 레지스터는 INT7~0 핀에 인터럽트 신호가 입력되어 해당 인터럽트가 트리거 되었음을 표시하는데 사용
이 비트들은 인터럽트 처리가 시작되고 MCU 인터럽트 벡터를 인출하여 인터럽트 서비스 루틴으로 점프하게
되면 다시 0으로 클리어 된다.
Value
EIMSK
BIT
00000000
INT0INT1INT2INT3INT4INT5INT6INT7
01234567
Value
EIFR
BIT
00000000
INTF0INTF1INTF2INTF3INTF4INTF5INTF6INTF7
01234567
13. --1313--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-4 외부 인터럽트 5
⊙ 전체적인 Interrupt를 enable 시킴
- I (Global Interrupt Enable)
- SREG (Status Register), bit 7
- 내용: global interrupt enable을 결정.
interupt service시 clear, RETI후 set
1 : global interrupt enable
C 프로그램에서 -> #asm(“sei”)
0 : global interrupt disable
C 프로그램에서 -> #asm(“cli”)
14. --1414--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-5 인터럽트 방식의 실습 1
☞ INT1(외부인터럽트)을 통해 입력 받아 포트 B로 LED를 연결 후 카운터 값을 출력하는 프로그램
⊙ Counter의 제작
- Port B: LED에 연결
- Port D.1 : switch를 연결
- switch를 누를 때마다, 변수 count값이 1씩 증가, 그 값을 Port 의 LED를 통해 표시
}
while ( 1) {
작업 A
작업 B
AVR
switch
++count;
PORTB = ~count;
Main Routine
Interrupt Service Routine
interrupt
처리부분
INT1
(PD1)
15. --1515--20062006--0303--3131
Embedded AVR ProgrammingEmbedded AVR Programming
1-5 인터럽트 방식의 실습 1
☞ INT1(외부인터럽트)을 통해 입력 받아 포트 B로 LED를 연결 후 카운터 값을 출력하는 프로그램
// External Interrupt(s) initialization
EICRA=0x08; // INT1 Mode: Falling Edge
EICRB=0x00; // INT7..4 Low level
EIMSK=0x02; // INT1: On
EIFR=0x02;
#asm("sei"); //전체 인터럽트 인에이블
while (1)
{};
}
#include <mega128.h>
#include <delay.h>
unsigned char count=0; // count 변수 선언
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
++count; // 카운터값 증가
PORTB = ~count; // count값을 포트 B에 LED출력
}
void main(void)
{
DDRB = 0xff; // 포트 B를 출력으로 설정
DDRB = 0xff; // 포트 B에 연결된 LED를 OFF
DDRD = 0x00; // 포트 D를 입력으로 설정
PORTD = 0xff; // 내부 풀업저항 사용