BASIC4MCU | 8051/PIC | DT-516 강좌 | 인터럽트 사용 LED 켜기
페이지 정보
작성자 키트 작성일2017-09-12 09:59 조회2,406회 댓글0건본문
void EXT0_int(void) interrupt 0{ //외부 인터럽트0 벡터번호=0EA=0; //전체인터럽트 디스에이블led=(led<<1) | 0x01; //led 상태 변경if (led==0xff) led=0xfe; //마지막인지 검사, 마지막이면 재설정P1=led; //포트 1로 출력delay(200); //스위치 디바운싱을위해 지연EA=1; //전체 인터럽트 디스에이블return;}//--------------------------인터럽트 함수입니다.몇가지만 체크 해보죠void EXT0_int(void) interrupt 0{ //외부 인터럽트0 벡터번호=0EA=0; //전체인터럽트 디스에이블led=(led<<1) | 0x01; //led 상태 변경if (led==0xff) led=0xfe; //마지막인지 검사, 마지막이면 재설정P1=led; //포트 1로 출력delay(200); //스위치 디바운싱을위해 지연EA=1; //전체 인터럽트 디스에이블return;}리턴은 함수의 문장 중간에서 함수를 빠져나갈 일이 있을 때 사용 합니다.지금처럼 제일 마지막에서는 없어도 아랫줄에서 리턴 됩니다.또 한가지일반 함수는 어셈으로 보면 RET이고인터럽트 함수는 RETI입니다.두개의 기능은 차이가 있습니다.컴파일 후 어셈 창을 열어서 명령어가 어떻게 쓰이고 있는지 체크 하세요//-------void EXT0_int(void) interrupt 0{ //외부 인터럽트0 벡터번호=0EA=0; //전체인터럽트 디스에이블led=(led<<1) | 0x01; //led 상태 변경if (led==0xff) led=0xfe; //마지막인지 검사, 마지막이면 재설정P1=led; //포트 1로 출력delay(200); //스위치 디바운싱을위해 지연EA=1; //전체 인터럽트 디스에이블}많은 책에서 인터럽트 디저블 이네이블 시키는 것을 종종 봅니다.(책을 직접 본게 아니고..학생들의 질문을 통한 간접 경험으로 추측...)디저블 시키는 이유는 몇가지가 있을 수 있는데첫번째는 현재의 인터럽트 함수 안에서 다른 인터럽트의 간섭을 받지 않고 싶을 때또 다른 이유는 위 코드처럼 여러번 발생 하는 채터링을 막기 위해서도 사용 합니다.다른 인터럽트를 사용 하고 있지 않다고 하면 없어도 되는 문장이고자기 자신의 채터링을 막기 위한 것이라면void EXT0_int(void) interrupt 0{ //외부 인터럽트0 벡터번호=0EA=0; //전체인터럽트 디스에이블led=(led<<1) | 0x01; //led 상태 변경if (led==0xff) led=0xfe; //마지막인지 검사, 마지막이면 재설정P1=led; //포트 1로 출력delay(200); //스위치 디바운싱을위해 지연인터럽트 플래그 크리어;EA=1; //전체 인터럽트 디스에이블}인터럽트 플래그를 크리어 시킨 후에 이네이블 시키는 것이 맞으며void EXT0_int(void) interrupt 0{ //외부 인터럽트0 벡터번호=0led=(led<<1) | 0x01; //led 상태 변경if (led==0xff) led=0xfe; //마지막인지 검사, 마지막이면 재설정P1=led; //포트 1로 출력delay(200); //스위치 디바운싱을위해 지연인터럽트 플래그 크리어;}어차피 자기 자신의 인터럽트는 함수를 마치기 전에는 실행 하지 않으므로플래그만 크리어 시켜도 마찬가지가 되겠습니다.//-------------------
#include <REG_MPC82G516.H>
//
void Timer_0_Interrupt(void) interrupt 1{ // 7200Hz=138.89us 주기
P4=1;
return; // 1번
P4=2;
return; // 2번
P4=3;
return; // 3번
}//
void main(void){
TMOD=2; ET0=1; TR0=1; EA=1;
while(1){
}
}위 소스코드를 컴파일 한 후 어셈창의 내용입니다.리턴을 3개 넣었습니다.5: void Timer_0_Interrupt(void) interrupt 1{ // 7200Hz=138.89us 주기
6: P4=1;
7: return; // 1번
C:0x002F 75E801 MOV P4(0xE8),#0x01
C:0x0032 8008 SJMP C:003C
8: P4=2;
9: return; // 2번C:0x0034 75E802 MOV P4(0xE8),#0x02
C:0x0037 8003 SJMP C:003C
10: P4=3;
11: return; // 3번 코드는 생략 되었습니다.
C:0x0039 75E803 MOV P4(0xE8),#0x03
12: }
13:
14: //
C:0x003C 32 RETI
15: void main(void){
16: TMOD=2; ET0=1; TR0=1; EA=1;
C:0x003D 758902 MOV TMOD(0x89),#0x02
C:0x0040 D2A9 SETB ET0(0xA8.1)
C:0x0042 D28C SETB TR0(0x88.4)
C:0x0044 D2AF SETB EA(0xA8.7)
17: while(1){
18: }
C:0x0046 80FE SJMP C:0046
19: }
C:0x0048 22 RET위 코드에서 return은 그 함수의 마지막으로 점프 합니다.
댓글 0
조회수 2,406등록된 댓글이 없습니다.