AN502

Domino 1 & Domino 2

Assembly Language Interrupt Handler for Timer1

03/26/01

 

Introduction: This application note will illustrate how to create an interrupt handler for Timer1 on the Domino 1 and 2 microcontrollers.

 

Background: BASIC-52 gives the user the ability to handle interrupts with the ONTIME and ONEX1 instructions, but these instructions are much slower than an assembly language handler. All interrupts are disabled upon power-up. Setting bit 7 and bit 3 in the Interrupt Enable (IE) register enables the Timer1 overflow interrupt. When the Domino is powered up Timer1 is enabled and starts counting.

How it works: In the 80C52, the interrupts are vectored to specified address locations. The Timer1 overflow interrupt’s vector address is 01BH. When an interrupt occurs, a hardware LCALL instruction pushes the contents of the program counter onto the stack, and then loads the appropriate vector address. At the vector address, BASIC-52 checks to see if it should respond to the interrupt. If BASIC-52 isn’t going to handle the interrupt, it pushes the program status word onto the stack and LJMPs to the handler vector. The user needs to place a LJMP in the handler vector that points to the address of the handler routine.

When the jump is made to the Interrupt Service Routine (ISR) a few important register values need to be saved so that when the return is made to BASIC the program can pick up exactly where it was interrupted. If the serial port is being used the first thing that needs to be done is to check and see if there is a transmission in progress. If there is, then the ISR should wait for the transmission to finish. Then the SCON, ACC, DPH and DPL registers should be pushed onto the stack (the ACC, DPH and DPL only need to be saved if the user wants to preserve them, saving isn’t always necessary). BASIC pushed the program counter and the Program Status Word (PSW) onto the stack when the interrupt was generated. Bit 6 in the TCON register (bit 6 is responsible for starting and stopping the counter, a 1 starts and a 0 stops the counter) needs to be cleared while servicing the interrupt to prevent another interrupt. When the ISR is finished the user must pop off all the registers placed on the stack. The last register that was pushed must be the first register popped off. Even though BASIC pushed the PSW onto the stack the user is responsible for popping it off. The Program Counter is popped off when the RETI is executed.

The sample program listed illustrates how to write an ISR. This particular program counts from 0 to 50 and then displays the number. The program is interrupted approximately every 60mS. When the interrupt is generated the words ‘Program Interrupt’ is transmitted out the serial port. The start address (ORG address) of the ISR is 0D000H. The ISR was assembled using the ASEM_51 assembler and was stored using Micromints STOREHEX.BAS routine. The LJMP pointing to the ISR was stored into 041BH using the XBY instruction.

Program Listing:

Interrupt Service Routine

ORG 0D000H









XM:












































SND:



END
  
JNB
PUSH
CLR
CLR
LCALL
POP
POP
RETI

MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL
MOV
LCALL

RET

MOV
JNB
CLR
RET


SCON.1,$
SCON
TR1
SCON.1
XM
SCON
PSW


A,#0DH
SND
A,#0AH
SND
A,#050H
SND
A,#072H
SND
A,#06FH
SND
A,#067H
SND
A,#072H
SND
A,#061H
SND
A,#06DH
SND
A,#020H
SND
A,#049H
SND
A,#06EH
SND
A,#074H
SND
A,#065H
SND
A,#072H
SND
A,#072H
SND
A,#075H
SND
A,#070H
SND
A,#074H
SND
A,#0DH
SND
A,#0AH
SND



SBUF,A
SCON.1,$
SCON.1

; Wait for serial transmission to finish
; Save SCON to stack
; Stop Timer1
; CLR Transmit interrupt flag
; Transmit "Program Interrupted"
; Retrieve SCON pushed by user
; Pop PSW pushed by BASIC
; Return from interrupt

; "CR"

; "LF"

; "P"

; "r"

; "o"

; "g"

; "r"

; "a"

; "m"

; "ASCII FOR SPACE"

; "I"

; "n"

; "t"

; "e"

; "r"

; "r"

; "u"

; "p"

; "t"

; "CR"

; "LF"




; Move contents out Serial Port
; Wait until buffer is empty
; CLR Transmit interrupt flag
; Return

END

BASIC Program:

10 XBY(0401BH)=02H
20 XBY(0401CH)=0D0H
30 XBY(0401DH)=00H
40 IE=088H
41 
50 FOR X=0 TO 50
60 PRINT X
70 TEMP=TCON
71
72
73
74
75
REM*** Moves LJMP HEX value into Handler Vector
REM*** Moves 1st byte of LJMP address into Handler
REM*** Moves 2nd byte of LJMP address into Handler
REM*** Sets bit 7 and bit 3 of the IE register
REM*** enabling the Timer1 overflow interrupt
REM*** Start counting
 REM*** Display count
REM*** Saves value of TCON for comparison
REM*** Check to see if bit 6 in the TCON register
REM*** is set (see if Timer1 has stop counting).
REM*** If bit 6 is cleared then Timer1 stopped
REM*** counting and the interrupted has been ser-
REM*** viced. Timer1 is then restarted.
80 IF (TEMP-03FH)<0 THEN TCON=TCON.OR.40H
90 NEXT X
110 END
REM*** Next count