300 likes | 1k Views
8051 인터럽트. 8051 인터럽트. dolicom@naver.com http://blog.naver.com/dolicom. 인터럽트란 ?. CPU 가 정해진 프로그램의 처리 중에 하드웨어적인 요청에 의해 다른 프로그램을 실행하는 것 제어용 장치는 실시간 처리가 요구되는데 하드웨어적인 요청에 바로 응답하여 처리 동시에 여러 개의 프로그램을 처리할 수 없으므로 실행 중인 프로그램은 중지하고 , 인터럽트 처리 후 계속한다 . CPU 는 하드웨어가 언제 요청할 지 모름. 인터럽트를 이해하기 위한 비유.
E N D
8051 인터럽트 8051 인터럽트 dolicom@naver.com http://blog.naver.com/dolicom
인터럽트란? • CPU가 정해진 프로그램의 처리 중에 하드웨어적인 요청에 의해 다른 프로그램을 실행하는 것 • 제어용 장치는 실시간 처리가 요구되는데 하드웨어적인 요청에 바로 응답하여 처리 • 동시에 여러 개의 프로그램을 처리할 수 없으므로 실행 중인 프로그램은 중지하고, 인터럽트 처리 후 계속한다. • CPU는 하드웨어가 언제 요청할 지 모름
인터럽트를 이해하기 위한 비유 책을 읽는다. 전화벨 수화기를 든다. 읽던 곳을 접어둔다. 전화 용건을 처리한다. 접어 두었던 곳을 편다. 수화기를 놓는다. 책을 다시 읽는다.
인터럽트 처리 프로그램 실행 중 인터럽트 요청 인터럽트 처리 루틴 PC 값 스택에 저장 인터럽트가 요청한 일을 처리 PC 값을 스택에서 꺼냄 인터럽트 리턴 프로그램 계속 실행
인터럽트 프로그램 방식 Interrupts vs. Polling • 인터럽트 방식 : 하드웨어에서 전자적인 신호를 통해 CPU에게 알려 현재 진행 중인 프로그램 중지하고 인터럽트 처리 루틴을 실행 • 폴링 (polling) : 하드웨어적으로 CPU에게 알리는 방법이 없이 CPU가 계속 해당 하드웨어를 감시하여 처리하는 방식 • 복잡한 인터럽트를 사용하지 않아 단순 • 실시간 처리에서 문제가 될 수 있다.
마스커블 인터럽트 • 마스커블 인터럽트 : 인터럽트를 요인이 발생 했을 때 처리를 할 것 인지를 설정할 수 있는 인터럽트 • Maskable Interrupt • 8051에서 사용 (IE 레지스터 사용) • 논마스커블 인터럽트 : 인터럽트 요인이 발생하면 CPU는 무조건 처리 해야 하는 인터럽트 • 예) 전원 이상 시 긴급 상황 대처 • 8051에서는 사용 하지 않음
ISR 인터럽트 처리 루틴 • Interrupt Service Routine • 인터럽트 소스에 따라 정해진 기능을 수행하기 위한 처리 루틴이 필요 –함수와 다름 • 인터럽트 처리 함수 찾는 방식 • 특정 번지로 점프하여 실행 • 8051사용, Z80, 8080 • 점프할 주소 값이 있는 곳을 설정하고 각 인터럽트 소스에 따라 주소를 정하여 주소값을 저장 한다. 이것을 읽어 점프 한다. • 인터럽트 벡터 테이블 (Interrupt Vector Table) • 80x86, 68000
마스커블 인터럽트 처리 환경 • PC을 저장할 스택이 준비 되어야 한다. • MOV SP,#60H – 8051의 내부 RAM 0x61부터 사용 • C에서는 startup.obj에서 결정 • 인터럽트 처리 루틴이 미리 준비 되어 있어야 한다. (ISR) • 인터럽트 요인 발생 시 요청이 가능 하도록 설정 되어야 한다.
인터럽트 처리 시 고려 사항 • 실행 중인 프로그램은 CPU의 레지스터 값이 인터럽트 루틴에 의해 변경 되면 안된다. • 인터럽트가 발생하는 시점이 정해지지 않아 어느 명령이 끝나고 ISR로 점프 했는지 복귀 주소 저장이 필요하다. 실행 위치로 복귀가 가능하도록 • ISR도 레지스터 사용이 필요 하다.
인터럽트 처리 과정 • 현재 실행 중인 프로그램 동작 시키기 위해 대피 해야 할 레지스터 • A, B, PSW 레지스터 • 일반 레지스터 R0~R7 • 복귀를 위한 PC • 스택은 데이터 저장 방식 상 SP값을 저장 필요 없다. • 대피 레지스터는 스택에 저장
인터럽트 실행과 레지스터 인터럽트 처리 요청 A, B, PSW, Rn을 스택에 저장 현재 진행 중인 명령이 끝나기를 기다린다. 인터럽트 처리 루틴을 실행 한다. 복귀를 위해 PC을 스택에 저장 Rn,PSW,B,A를 복귀 ISR 주소 값을 찾아 PC 넣어 점프 RETI에 의해 PC값을 복귀
인터럽트 처리과정 I • 인터럽트가 발생하면 현재 진행 중인 명령이 끝나면 인터럽트 처리에 들어간다. • CPU는 PC 값을 스택에 저장 한다. – 16비트 • 정해진 인터럽트 소스에 맞는 주소로 PC을 설정하여 점프 한다. • ISR에서는 필요한 레지스터 값을 스택을 이용 대피한다. ISR안에서 사용하는 레지스터만 필요에 따라 대피 한다. • 일반레지스터는 뱅크를 사용한다면 PSW의 뱅크를 변경하여 보존할 수 있다. • 인터럽트에 맞는 기능을 수행한다.
인터럽트로 부터 복귀 과정 II • ISR이 끝나면 이제는 복귀 과정에 들어간다. • 일반레지스터는 대피 방법에 따라 복귀한다. • 스택을 사용 했다면 POP으로 • 다른 뱅크를 사용 했다면 원래 대로 복귀(POP PSW) • 기타 PUSH에 의해 저장된 레지스터를 반대 순서로 POP 복귀 한다. • PUSH 순서에 저장된 레지스터만 복귀 • RETI에 의해 ISR 시작 전으로 복귀 • PC값을 스택으로 부터 복귀 한다. (RETI에 의해 자동으로)
C의 인터럽트 처리 예 • ; FUNCTION SerialEcho (BEGIN) • PUSH PSW • MOV PSW,#00H • PUSH AR7 • JNB RI,?C0002 • CLR RI • ; Variable 'ch' assigned to Register 'R7' • MOV R7,SBUF • MOV SBUF,R7 • SJMP ?C0004 • ?C0002: • CLR TI • ?C0004: • POP AR7 • POP PSW • RETI void SerialEcho(void) interrupt 0 { char ch; if (RI == 1) { RI = 0; ch = SBUF; SBUF = ch; } else { TI = 0; } }
인터럽트 생성 출처 외부에서 인터럽트가 필요해서 입력 했을 때 외부 인터럽트 Timer/Counter 타이머에서 설정 시간이 흘렀을 때 Interrupt Control Timer 1 ROM 프로그램 RAM Timer 0 CPU 송수신 할 데이터가 있을 때 Serial Port Bus Control 4 I/O 포트 OSC P0 P1 P2 P3 TxD RxD
인터럽트 구조 • 인터럽트 소스는 5개 인터럽트 원인 인터럽트처리 시작번지 외부 인터럽트 0 0x03 타이머/카운터 0 0x0B 외부 인터럽트 1 0x13 타이머/카운터 1 0x1B 시리얼 포트 0x23
인터럽트에 필요한 레지스터 • IE(Interrupt Enable) – mask • 인터럽트 소스에서 인터럽트 요인이 발생 했을 때 처리를 할 것인가 무시를 할 것인가를 결정 • IP(Interrupt Priority) • 여러 개의 인터럽트 소스에서 여러 개의 인터럽트가 발생할 경우 처리 우선 순위를 결정 • TCON과 SCON • 인터럽트 요인이 발생하면 플래그에 세트하고 하드웨어적인 논리에 의해 CPU에 전달
인터럽트 설정 및 처리 • 우선 인터럽트를 처리할 인에이블 레지스터(IE)를 설정한다. • 인터럽트 우선 순위 레지스터(IP)을 조사해서 자기보다 높은 순위를 처리하면 무시 한다. • 인터럽트 처리루틴에 들어가면, 자동으로 해당 인터럽트 플래그(IE0, IE1, TF0, TF1)을 클리어 되고 인터럽트 루틴을 시작한다. 단 RI,TI는 클리어 되지 않는다.
인터럽트 소스의 요청 상황 I • 인터럽트 발생 상황은 TCON과 SCON 레지스터로 판단 한다. • 1을 설정되어 있으면 인터럽트 요인 발생 7 6 5 4 3 2 1 0 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 Timer 1 Timer0 Interrupt IE0 : 외부 인터럽트 요청 발생 External Interrupt 0 edge flag TF0 : 타이머 0 overflow Timer 0 Overflow flag IE1 : 외부 인터럽트 요청 발생 External Interrupt 1 edge flag TF0 : 타이머 1 overflow Timer 1 Overflow flag
인터럽트 소스의 요청 상황 II • SCON –시리얼 통신 제어 레지스터 7 6 5 4 3 2 1 0 SM0 SM1 SM2 REN TB8 RB8 TI RI TI : 전송 준비가 되면 발생 Transmit Interrupt flag RI : 수신 데이터 준비 시 발생 Receive Interrupt flag
IE(Interrupt Enable) Mask 7 6 5 4 3 2 1 0 • Mask Bit : 각 비트는 인터럽트 발생 상황 시 인터럽트를 처리할 것인가를 결정 한다. ‘1’로 설정하면 인에이블 • EA는 CPU가 인터럽트를 처리할 것인가를 결정 한다. 따라서 ‘0’이면 CPU는 모든 인터럽트 거절 • EA=1에서 각 인에이블 플래그(ES,ET1,EX1,ET0,EX0)의 설정에 따라 인터럽트 처리를 설정 한다. EA - - ES ET1 EX1 ET0 EX0 EA (Enable All Interrupt) : ‘1’ = 모든 인터럽트 가능 ES (Enable Serial Interrupt) : ‘1’ = RI & TI인터럽트 가능 ET1 (Enable Timer1 Interrupt) : ‘1’ = 타이머1 인터럽트 가능 EX1 (Enable eXternal1 Interrupt) : ‘1’ = 외부 인터럽트1 인터럽트 가능 ET0 (Enable Timer0Interrupt) : ‘1’ = 타이머0 인터럽트 가능 EX0 (Enable eXternal0 Interrupt) : ‘1’ = 외부 인터럽트0 인터럽트 가능
IP(Interrupt Priority) 7 6 5 4 3 2 1 0 • 현재 낮은 레벌 인터럽트 처리 중 높은 레벌 인터럽트가 발생 하면 • 낮은 레벌 ISR을 중지하고 • 높은 레벨의 인터럽트 서비스 시작 • 현재 인터럽트 보다 낮은 레벌 인터럽트가 오면 요청을 무시 한다. - - - PS PT1 PX1 PT0 PX0 PS (Serial port priority control) : ‘1’ = 시리얼 인터럽트을 높은 레벌로 PT1 (Timer1 priority control) : ‘1’ = 타이머1 인터럽트을 높은 레벌로 PX1 (external interrupt1 priority control) : ‘1’ = 외부인터럽트1을 높은 레벌로 PT0 (Timer0 priority control) : ‘1’ = 타이머0인터럽트을 높은 레벌로 PX0 (external interrupt0 priority control) : ‘1’ = 외부인터럽트0을 높은 레벌로
외부 인터럽트 • 외부 인터럽트 입력 핀 /INT0, /INT1의 2가지 입력 상황에 의해 발생 • 입력 신호가 하강 모서리 이면 발생 • 레벨(0 입력)이면 발생 7 6 5 4 3 2 1 0 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 • IT0 (Interrupt 0 Type control) • IT0=1 : /INT0(P3.2) 핀의 하강 모서리(↓)에서 인터럽트 요청 • IT0=0 : /INT0(P3.2) 핀의 L 레벨에서 인터럽트 요청 • IT1 (Interrupt 1 Type control) • IT1=1 : /INT1(P3.3) 핀의 하강 모서리(↓)에서 인터럽트 요청 • IT1=0 : /INT1(P3.3) 핀의 L 레벨에서 인터럽트 요청
C에서 인터럽트 처리 루틴 만들기 • 인터럽트 처리 루틴(ISR)을 사용자가 직접 정의 할 수 있다. • 인수 전달 할 수 없다. 인수 리턴 불가능 • ISR는 C51 라이브러리가 제공하는 함수 사용할 수 없다. • ISR에서 사용하는 레지스터들은 루틴 시작전에 자동으로 저장 된다. • 인터럽트 함수는 직접 콜 할 수 없다.
인터럽트 종류 및 인터럽트 벡터 인터럽트 원인 벡터번호 ISR 시작번지 외부 인터럽트 0 0 0x03 타이머/카운터 0 1 0x0B 외부 인터럽트 1 2 0x13 타이머/카운터 1 3 0x1B 시리얼 포트 4 0x23
인터럽트 함수 형태 • void ISR_Name(void) interrupt 3 using 2 • ISR_Name : 사용자에 의해 정의 되는 함수 이름 • interrupt 3 : 인터럽트 벡터 번호 (반드시 필요) – 0 ~4 (표4-2) • using 2 : 인터럽트에서 사용하는 뱅크번호(없어도 됨) - 0~7
ISR의 함수 예 • 외부 인터럽트 0 예 #include <win51.h> void Ex_KeyUp(void) interrupt 0 using 1 { . . . // 기능 루틴 } • 타이머 0 #include <win51.h> void Tm0_Clock(void) interrupt 1 { . . . // 기능 루틴 }
ISR의 함수 예 II • 시리얼 포트 인터럽트 함수 #include <win51.h> void SerialEcho(void) interrupt 0 using 1 { char ch; if (RI == 1) { RI = 0; ch = SBUF; // 수신 문자 읽기 SBUF = ch; // 다시 보내기 } else { TI = 0; } }