Introduction
8051
() 1
Introduction
An interrupt is the occurrence of a condition--an event --
that cause a temporary suspension of a program while the
event is serviced by another program (Interrupt Service
Routine ISR or Interrupt Handler).
Interrupt-Driven System-- gives the illusion of doing
many things simultaneously, quick response to events,
suitable for real-time control application.
Base level--interrupted program, foreground.
Interrupt level--ISR, background.
() 2
Interrupt
Program execution without interrupts
Main program (base level, foreground)
time
Interrupt ISR
level execution ISR ISR
Base-level
Main Main Main Main
execution
Interrupt (occurs asynchronously)
Return from interrupt instruction
() 3
8051 Interrupt
5 (interrupt sources) :
2 external (/INT0, /INT1)
2 timer (TF0, TF1)
a serial port (TI, RI)
2 programmable interrupt priority levels (IP)
0: low
1: high
Fixed interrupt polling sequence
Can be enabled or disabled (IE)
8051 SFRs for controlling interrupts:
IE (A8H)
IP (B8H)
() 4
SFR
INT 0 IE0 TCON.1 0003H
Timer 0 TF0 TCON.5 000BH
INT 1 IE1 TCON.3 0013H
Timer 1 TF1 TCON.7 001BH
RI SCON.0
UART 0023H
TI SCON.1
TF2 T2CON.7 (8052)
(8052) Timer 2 002BH
EXF2 T2CON.6 (8052)
() 5
Processing Interrupts
When an interrupt occurs and is accepted by the CPU,
the main program is interrupted. The following actions
occur:
The current instruction completes execution.
The PC is saved on the stack.
The current interrupt status is saved internally.
Interrupts are blocked at the level of the interrupt.
The PC is loaded with the vector address of the ISR
The ISR executes.
The ISR finishes with an RETI instruction, which
retrieves the old value of PC from the stack and
restores the old interrupt status. Execution of the main
program continues where it left off.
6
Interrupt Vectors
Interrupt vector = the address of the start of the ISR.
When vectoring to an interrupt, the flag causing the interrupt is
automatically cleared by hardware. The exception is RI/TI and
TF2/EXF2 which should be determined and cleared by software.
Interrupt Interrupt flag Vector address
RST 0000H (LJMP 0030H)
External INT 0 IE0 0003H
Timer 0 TF0 000BH
External INT 1 IE1 0013H
Timer 1 TF1 001BH
Serial port RI or TI 0023H
Timer 2 TF2 or EXF2 002BH 7
(IE)
MCS-51
IE (A8H)()
() 8
EA EA = 0
EA = 1
ET2
Timer 2 (ET2 = 1 )
ES
(ES = 1 )
() 9
ET1
Timer 1 (ET1 = 1 )
EX1
1 (EX1 = 1 )
ET0
Timer 0 (ET0 = 1 )
EX0
0 (EX0 = 1 )
() 10
IP (B8H)()
() 11
PT2
Timer 2 (PT2 = 1 )
PS
( PS = 1 )
PT1
Timer 1 (PT1 = 1 )
() 12
PX1
INT 1 (PX1 = 1 )
PT0
Timer 0 ( PT0 = 1 )
PX0
INT 0 (PT1 = 1 )
() 13
MCS-51
>
() 14
IE register IP register High priority
interrupt
1
INT0 IT0 IE0
0 Low
priority
TF0 interrupt
1
IT1 IE1
INT1 Interrupt
0
polling
sequence
TF1
RI
TI
TF2
EXF2
Interrupt
enables Accent
() 15
Global Enable interrupt
8051 Program Design Using Interrupt
Mem addr.
ORG 0000H ;reset entry point
0000 LJMP Main ;takes up 3 bytes
0003 ORG 0003H ;/INT0 ISR entry point
;8 bytes for IE0 ISR or
. ;jump out to larger IE0 ISR
ORG 000BH ;Timer 0 ISR entry point
000B .
.
ORG 0030H ;main program entry point
0030 Main: .
.
.
16
Small Interrupt Service Routine
8 bytes for each interrupt vector. Small ISR utilizes the space.
For example: (assume only T0ISR is needed in the case)
ORG 0000H
LJMP MAIN
ORG 000BH
T0ISR: .
.
RETI
MAIN: . ;only T0ISR
17
Large Interrupt Service Routine
8 bytes not enough. Use LJMP to large ISR
ORG 0000H
LJMP MAIN
ORG 000BH ; T0 ISR entry point
LJMP T0ISR
ORG 0030H ;above int vectors
MAIN: .
.
T0ISR: . ; Timer 0 ISR
.
RETI ;return to main
18
A 10-KHz Square Wave on P1.0
Using Timer Interrupts
ORG 0 ;reset entry point
LJMP Main
ORG 000BH ;T0 interrupt vector
T0ISR: CPL P1.0 ;toggle port bit
RETI
ORG 0030H
Main: MOV TMOD,#02H ;T0 MODE 2
MOV TH0,#-50 ;50 mS DELAY
SETB TR0 ;START TIMER 0
MOV IE,#82H ;ENABLE T0 INT
SJMP $ ;DO NOTHING, wait for
;T0 interrupt to occur
19
Two 7-KHz & 500-Hz Square Waves
Using Interrupts
ORG 0 ;reset entry point
LJMP Main
ORG 000BH ;T0 interrupt vector
LJMP T0ISR
ORG 001BH ;T1 vector
LJMP T1ISR
20
Two 7-KHz & 500-Hz Square Waves
Using Interrupts (cont.)
T0ISR: CPL P1.7 ;7-kHz on P1.7
RETI
21
Loudspeaker Interface
+5V
8051 440Hz C
P1.7
7404
Loudspeaker
27
;****************************************************************
MONITOR CODE 00BCH ;MON51 (V12) entry point
COUNT EQU -50000 ;0.05 seconds per timeout
REPEAT EQU 5 ;5 x 0.05 = 0.25 seconds/note
;****************************************************************
; Note: X3 not installed on SBC-51, therefore
; interrupts directed to the following jump table
; beginning at 8000H
;****************************************************************
ORG 8000H ;RAM entry points for...
LJMP MAIN ;main program
LJMP EXT0ISR ;External 0 interrupt
LJMP T0ISR ;Timer 0 interrupt
LJMP EXT1ISR ;External 1 interrupt
LJMP T1ISR ;Timer 1 interrupt
LJMP SPISR ;Serial Port interrupt
LJMP T2ISR ;Timer 2 interrupt
28
;****************************************************************
; MAIN PROGRAM BEGINS
;****************************************************************
MAIN: MOV TMOD,#11H ;both timers 16-bit mode
MOV R7,#0 ;use R7 as note counter
MOV R6,#REPEAT ;use R6 as timeout counter
MOV IE,#8AH ;Timer 0 & 1 interrupts on
SETB TF1 ;force Timer 1 interrupt
SETB TF0 ;force Timer 0 interrupt
SJMP $ ;ZzZzZzZz time for a nap
29
;****************************************************************
; TIMER 0 INTERRUPT SERVICE ROUTINE (EVERY 0.05 SEC.)
;****************************************************************
T0ISR: CLR TR0 ;stop timer
MOV TH0,#HIGH (COUNT) ;reload
MOV TL0,#LOW (COUNT)
DJNZ R6,EXIT ;if not 5th int, exit
MOV R6,#REPEAT ;if 5th, reset
INC R7 ;increment note
CJNE R7,#LENGTH,EXIT ;beyond last note?
MOV R7,#0 ;yes: reset, A=440 Hz
EXIT: SETB TR0 ;no: start timer, go
RETI ;back to ZzZzZzZ
30
;****************************************************************
; TIMER 1 INTERRUPT SERVICE ROUTINE (PITCH OF NOTES)
;
; Note: The output frequencies are slightly off due
; to the length of this ISR. Timer reload values
; need adjusting.
;****************************************************************
T1ISR: CPL P1.7 ;music maestro!
CLR TR1 ;stop timer
MOV A,R7 ;get note counter
RL A ;multiply (2 bytes/note)
CALL GETBYTE ;get high-byte of count
MOV TH1,A ;put in timer high register
MOV A,R7 ;get note counter again
RL A ;align on word boundary
INC A ;past high-byte (whew!)
CALL GETBYTE ;get low-byte of count
MOV TL1,A ;put in timer low register
SETB TR1 ;start timer
RETI ;time for a rest
31
;****************************************************************
; GET A BYTE FROM LOOK-UP OF NOTES IN A MAJOR SCALE
;****************************************************************
GETBYTE: INC A ;table look-up subroutine
MOVC A,@A+PC
RET
TABLE: DW -1136 ;A
DW -1136 ;A (play again; half note)
DW -1012 ;B (quarter note, etc.)
DW -902 ;C# - major third
DW -851 ;D
DW -758 ;E - perfect fifth
DW -676 ;F#
DW -602 ;G#
DW -568 ;A'
DW -568 ;A' (play 4 times; whole note)
DW -568
DW -568
LENGTH EQU ($ - TABLE) / 2 ;LENGTH = # of notes
32
;****************************************************************
; UNUSED INTERRUPTS - BACK TO MONITOR PROG (ERROR)
;****************************************************************
EXT0ISR:
SPISR:
T2ISR: CLR EA ;shut off interrupts and
LJMP MONITOR ; return to MON51
END
33
Serial Port Interrupts
SPISR must check RI or TI and clears it.
TI occurs at the end of the 8th bit time in mode 0 or at
the beginning of stop bit in the other modes. Must be
cleared by software.
RI occurs at the end of the 8th bit time in mode 0 or half
way through the stop bit in other modes when SM2 =0.
If SM2 = 1, RI = RB8 in mode 2,3 and RI = 1 only if
valid stop bit is received in mode 1.
34
Output ACSII Code Set Using
Interrupt (1)
;dump ASCII codes to serial port
ORG 0
LJMP Main
ORG 0023H ;serial port vector
LJMP SPISR
The CPU speed is much higher than 1200 baud serial transmission.
Therefore, SJMP $ executes a very large percentage of the time.
Time for one char = (1/1200 baud)(8+1+1) = 8333.3 mS compared
to 1 mS machine cycle!
We could replace SJMP instruction with other useful instructions
doing other things.
36
#include io51.h
char *ptr;
void InitialUART(int BaudRate) /*Max baudrate = 9600*/
{
SCON = 0x52; /*mode 1 and REN, TI = 1 */
TMOD = 0x21; /*T1 mode 2, T0 mode 1 */
TH1 = 256-(28800/BaudRate); /*11.059M/384=28800*/
TR1 = 1;
}
static const char msg1[]=UART interrupt message!!;
void main(void)
{
InitialUART(9600);
EA = 1; /*enable all interrupt */
ptr = msg1;
ES = 1; /*enable SP interrupt */
while(1); /*wait for SP interrupt*/
}
37
interrupt [0x23] void SCON_int(void) /*Serial port ISR*/
{
if(RI==1)RI=0; /* we did nothing in this program for RxD */
if(TI==1)
{
TI=0;
if(*ptr!=\0) /*string ends with \0 character*/
{
SBUF=*ptr;
++ptr;
}
else
{
ES=0; /*complete a string tx, clear ES and let*/
TI=1; /*main program decide next move */
}
}
}
38
External Interrupts
/INT0 (P3.2 or pin12) and /INT1 (P3.3 or pin 13) produce
external interrupt in flag IE0 and IE1 (in TCON) in S5P2.
/INT0 and /INT1 are sampled once each machine cycle (S5P2)
and polled in the next machine cycle. An input should be held
for at least 12 clock cycles to ensure proper sampling.
Low-level trigger (IT0 or IT1 =0): interrupt when /INT0 or
/INT1 = 0
Negative edge trigger (IT0 or IT1 = 1): interrupt if sense high
on /INT0 or /INT1 in one machine cycle and low in next
machine cycle.
IE0 and IE1 are automatically cleared when CPU is vectored
to the ISR.
39
External Interrupts
40
Furnace Controller
8051
HOT = 0 if T > 21C INT0 1 = solenoid engaged (furnace on)
if T < 19C
P1.7
0 = solenoid disengaged (furnace
COLD = 0 if T < 19C INT1 off) if T > 21C
T = 21C
T = 20C
T = 19C
HOT
COLD
P1.7
41
Furnace Controller
ORG 0
LJMP Main
EX0ISR: CLR P1.7 ;hot, turn furnace off
RETI
ORG 13H
EX1ISR: SETB P1.7 ;cold, turn furnace on
RETI
ORG 0030H
Main: MOV IE,#85H ;enable ext int
SETB IT0 ;negative edge trigger
SETB IT1
SETB P1.7 ;turn furnace on first
JB P3.2,Skip ;chk /INT0 if T>21?
CLR P1.7 ;yes, turn furnace off
Skip: SJMP $ ;do nothing
42
Intrusion Warning System
8051
74LS04
INT0 P1.7
Door opens
1 sec (T0)
P1.7
44
Intrusion Warning System
EX0ISR: MOV R7,#20 ;20x50000 ms = 1 s
SETB TF0 ;force T0 ISR
SETB TF1 ;force T1 ISR
SETB ET0 ;enable T0 int
SETB ET1 ;enable T1 int
RETI
T0ISR: CLR TR0 ;stop T0
DJNZ R7,SKIP ;if not 20th time, exit
CLR ET0 ;if 20th, disable itself
CLR ET1 ;and tone
LJMP EXIT
SKIP: MOV TH0,#HIGH(-50000) ;reload 0.05 s
MOV TL0,#LOW(-50000) ;delay
SETB TR0 ;turn on T0 again
EXIT: RETI
45
Intrusion Warning System
;
T1ISR: CLR TR1 ;stop T1
MOV TH1,#HIGH(-1250) ;count for 400 Hz
MOV TL1,#LOW(-1250) ;tone
CPL P1.7 ;music maestro
SETB TR1 ;
RETI
46