8051 강좌 30번을 보시면 인터럽트에 대해 상세히 설명되어 있습니다. 표준 8051에는 아래와 같이 5개의 인터럽트 벡터가 있는데, AT89s52는 타이머2가 추가되었으므로 총 6개의 인터럽트 벡터가 존재합니다.
인터럽트 벡터:
외부 INT0 - 벡터 번지: 0x0003, 우선순위 1
타이머0 - 벡터 번지: 0x000B, 우선순위 2
외부 INT1 - 벡터 번지: 0x0013, 우선순위 3
타이머1 - 벡터 번지: 0x001B, 우선순위 4
직렬통신 - 벡터 번지: 0x0023, 우선순위 5
타이머2 - 벡터 번지: 0x002B, 우선순위 6 (AT89s52에 추가됨)
이 중에서 타이머0 인터럽트를 사용하므로 벡터 번지 0x000B만 기억하고 있으면 됩니다.^^ 아래의 소스를 실행하면 TY52 보드의 첫 번째 LED가 1초마다 깜빡입니다. 어셈블리어로 타이머를 동작시키는 것이 무척 어려웠는데, 마시거북님께서 도움을 주셨습니다.
;=========================================
;
; 타이머0을 이용해 LED 깜빡이기
;
;==========================================
ORG 0000H
JMP START
;==========================================
ORG 000BH ; 인터럽트 벡터
JMP TIMER0_ISR ; 타이머0으로 점프 (인터럽트가 발생하면 이 코드가 실행되고 TIMER0_ISR로 점프)
;==========================================
ORG 0035H
START:
MOV SP, #50 ; 스택포인터를 50 번지로 설정
MOV 30H,#100 ; 램의 30번지에 100을 저장
MOV TMOD,#01H ; 타이머0 설정
MOV TH0,#0B1H ; 10ms 마다 인터럽트 생성
MOV TL0,#0DFH
SETB ET0 ; 타이머0 인터럽트 가능하게 설정
SETB EA ; 전체 인터럽트 가능하게 설정
SETB TR0 ; 타이머0 시작
SETB P1.2 ; 포트1의 2번핀에 논리 1 출력 (LED 꺼짐)
JMP $ ; 제자리에서 무한루프 (인터럽트가 걸리면 작업 수행후 이곳으로 다시 돌아와 대기한다.)
;===============================================
TIMER0_ISR: ; 타이머0 인터럽트 서비스 루틴
MOV TH0,#0B1H ; 타이머 설정값을 재저장
MOV TL0,#0DFH
MOV A,30H ; 램 30번지의 내용을 A 레지스터에 저장
DEC A ; A 레지스터 값 1 감소
MOV 30H, A ; 1 감소한 A 레지스터 값을 램 30번지에 저장
CJNE A, #00H, DOWN ; A 레지스터 값이 0 이 아니면 DOWN으로 점프, 0 이면 아래의 코드 수행
MOV 30H, #100 ; 100을 램의 30번지에 저장
CPL P1.2 ; 포트1의 2번핀을 반전시킴
DOWN:
RETI ; 인터럽트에서 복귀 (RETURN FROM INTERRUPT)
;===============================================
END
------------------------------------------------
소스와 헥사파일을 파일로 첨부하였습니다.