Anda di halaman 1dari 46

8051

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)()

AFH AEH ADH ACH ABF AAH A9H A8H

A8H EA ET2 ES ET1 EX1 ET0 EX0

() 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)()

BFH BEH BDH BCH BBF BAH B9H B8H

B8H - - PT2 PS PT1 PX1 PT0 PX0

() 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

>

INT 0 > Timer 0 > INT 1


> Timer 1 > UART > Timer 2

() 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

ORG 0030H ;main starts here


Main: MOV TMOD,#12H ;T0 mode 2, T1 mode 1
MOV TH0,#-71 ;7 kHz using T0
SETB TR0 ;START TIMER 0
SETB TF1 ;force T1 interrupt
MOV IE,#8AH ;ENABLE T0,T1 INT
SJMP $ ;DO NOTHING

20
Two 7-KHz & 500-Hz Square Waves
Using Interrupts (cont.)
T0ISR: CPL P1.7 ;7-kHz on P1.7
RETI

T1ISR: CLR TR1 ;stop T1


MOV TH1,#HIGH(-1000) ;500Hz->1000 us high
MOV TL1,#LOW(-1000)
;1 ms for T1
SETB TR1 ;START TIMER 1
CPL P1.6 ;500-Hz on P1.6
RETI

21
Loudspeaker Interface
+5V
8051 440Hz C

P1.7

7404
Loudspeaker

Two timings are required for a musical scale:


1. timing from one note to the next note (time_delay())
2. timing for toggling the port bit at note frequency (T0_int())
e.g., 4 notes/second or quarter note: 250 ms timeout is needed.
22
Playing Music Tones: C example

Tone Frequency Period T T/2


------------------------------------------------------------------
Do 523 1/523=1.912 ms 956 ms
Re 587 1/587= 1.704ms 852 ms
Mi 659 1/659= 1.517ms 758.5 ms
Fa 698 1/698= 1.433ms 716.5 ms
Sol 785 1/785= 1.274ms 637 ms
La 880 1/880= 1.136ms 568 ms
Ti 998 1/998= 1.002ms 501 ms
Do 1047 1/1047= 0.955ms 477.5 ms
We can use 16 bit timer mode to generate music tones
23
#include io51.h /*may be different for different compiler*/
#define s 65536
#define Tt 11059200/12 /* 11.0592MHz/12 */
#define t Tt/2
#define Do s-t/523 /* t/523 = # of clocks to produce half period of Do */
#define Re s-t/587
#define Mi s-t/659
#define Fa s-t/698
#define Sol s-t/785
#define La s-t/880
#define Ti s-t/998
#define Do_h s-t/(523*2)

static const unsigned int ToneTable[ ]={Do,Re,Mi,Fa,Sol,La,Ti,Do_h};


unsigned int Temp;

Void time_delay(int dly_count)


{
while(dly_count>=0)
dly_count--;
}
24
interrupt void T0_int(void){
TH0 = Temp/256; /* load T0 value */
TL0 = Temp%256;
P1_7 = ~P1_7; /* complement P1.7 */
}
main(){
int I;
IE = 0x82; /*enable T0 interrupt */
TMOD = 0x01; /* T0 in 16-bit timer mode */
while (1)
{
for(I=0;I<=7;I++){
Temp = ToneTable[I];
TR0 = 1; /*start T0, interrupt when TF0 */
time_delay(22000); /* play the tone for an interval */
TR0 = 0; /* stop T0, change for next tone*/
}
time_delay(32000); /* pause for a while */
time_delay(32000);
}
}
25
Playing Music Tones: ASM example
A-major musical scale:
A above middle C: 440Hz
Other notes: 440Hz x 2^(n/12)
n: number of steps (semitones)
A, one octave, or 12 steps above A
A: 440 x 2^(12/12) = 880Hz
With ref. To bottom note, the steps
are 2,4,5,7,9,11,12.

Two timings are required for a musical scale:


1. timing from one note to the next note (length of note)
2. timing for toggling the port bit at note frequency (pitch of note)
e.g., 4 notes/second or quarter note: 250 ms timeout is needed

T0: 50 ms timeout for note length of note (5x50 = 250 ms)


T1: variable timeout for different notes pitch of note 26
;****************************************************************
; LOUDSPEAKER INTERFACE EXAMPLE
;
; This program plays an A major musical scale using
; a loudspeaker driven by a inverter through P1.7
;****************************************************************
;
; Note Frequency (Hz) Period (us) Period/2 (us)
; ........................................................................................
; A 440.00 2273 1136
; B 493.88 2025 1012
; C# 554.37 1804 902
; D 587.33 1703 851
; E 659.26 1517 758
; F# 739.99 1351 676
; G# 830.61 1204 602
; A' 880.00 1136 568

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

ORG 0030H ;main entry point


Main: MOV TMOD,#20H ;Timer 1 mode 2
MOV TH1,#-26 ;use 1200 baud
SETB TR1 ;start T1
MOV SCON,#42H ;mode1, set TI to force first
;interrupt; send 1st char.
MOV A,#20H ;send ASCII space first
MOV IE,#90H ;enable SP interrupt
;vector to SPISR right away
SJMP $ ;do nothing
35
Output ACSII Code Set Using
Interrupt (2)
SPISR: CJNE A,#7FH,Skip ;if ASCII code = 7FH
MOV A,#20H ;wrap back to 20H
Skip: MOV SBUF,A ;start to transmit
INC A
CLR TI ;clear TI flag
RETI

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

If the external interrupt is low-level triggered (IT0 or


IT1 =0), the external source must hold the request
active until the requested interrupt is actually
generated.
Then it must deactivate the request before the ISR is
completed, or another interrupt will be generated.
Usually, an action taken in the ISR causes the
requesting source to return the interrupting signal to
the inactive state.

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

P1.7 400Hz (T1)


1.25 ms
2.5 ms
43
Intrusion Warning System
ORG 0
LJMP Main
LJMP EX0ISR
ORG 0BH
LJMP T0ISR ;use T0 and R7=20 to time
;20x50000us = 1 s
ORG 1BH
LJMP T1ISR ;use T1 to sound alarm at
;400 Hz
Main: SETB IT0 ;negative edge trigger
MOV TMOD,#11H ;T0,T1 16-bit timer mode
MOV IE,#81H ;enable EX0 only
Skip: SJMP $ ;relax & wait for intrusion

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

Anda mungkin juga menyukai