Ec522 8051 09
Ec522 8051 09
INTERRUPTS
8051 Interrupts
An interrupt is some event which interrupts normal program execution. Normal program flow is sequential, being altered only by those instructions which expressly cause program flow to deviate in some way. Interrupts give us a mechanism to "put on hold" the normal program flow, execute a subroutine, and then resume normal program flow as if we had never left it. This subroutine, called an interrupt handler, is only executed when a certain event (interrupt) occurs. The event may be one of the timers "overflowing," receiving a character via the serial port, transmitting a character via the serial port, or one of two "external events." The 8051 may be configured so that when any of these events occur the main program is temporarily suspended and control passed to a special section of code which presumably would execute some function related to the event that occured. Once complete, control would be returned to the original program. The main program never even knows it was interrupted.
Assume a 16k program is executing many subroutines. Program is required to automatically toggle the P3.0 port every time timer 0 overflows.
Assume a 16k program is executing many subroutines. Program is required to automatically toggle the P3.0 port every time timer 0 overflows. The code to do this isnt too difficult: JNB TF0,SKIP_TOGGLE CPL P3.0 CLR TF0 SKIP_TOGGLE: ... Since the TF0 flag is set whenever timer 0 overflows, the above code will toggle P3.0 every time timer 0 overflows. This accomplishes what is reqd., but is inefficient. The JNB instruction consumes 2 instruction cycles to determine that the flag is not set and jump over the unnecessary code. In the event that timer 0 overflows, the CPL and CLR instruction require 2 instruction cycles to execute.
Let the rest of the code in the program requires 98 instruction cycles.
Thus, in total, the code consumes 100 instruction cycles (98 instruction cycles plus the 2 that are executed every iteration to determine whether or not timer 0 has overflowed). If timer was in 16-bit timer mode, timer 0 will overflow every 65,536 machine cycles. In that time the program will perform 655 JNB tests and consume 1310 instruction cycles, plus another 2 instruction cycles to perform the action. To achieve the goal 1312 instruction cycles are consumed. So 2.002% of time is being spent just checking when to toggle P3.0. Thus the code is ugly because as it has to make that check every iteration of our main program loop.
Every 65536 instruction cycles program executes the CPL instruction and the RETI instruction. These two instructions together require 3 instruction cycles, and program has accomplished the same goal as the first program, that required 1312 instruction cycles. As far as the toggling of P3.0 goes, this code is 437 times more efficient!
What Events Can Trigger Interrupts, and where do they go? We can configure the 8051 so that any of the following events will cause an interrupt: Timer 0, Timer 1 Overflow. Reception/Transmission of Serial Character. External Event 0, 1. In other words, we can configure the 8051 so that when Timer 0 Overflows or when a character is sent/received, the appropriate interrupt handler routines are called.
Interrupt Handler Address (ROM Location) 0003h 000Bh 0013h 001Bh 0023h
Setting Up Interrupts
By default at powerup, all interrupts are disabled. This means that even if, for example, the TF0 bit is set, the 8051 will not execute the interrupt. The program must specifically tell the 8051 that it wishes to enable interrupts and specifically which interrupts it wishes to enable. The program may enable and disable interrupts by modifying the IE SFR (A8h)
Bit 7 6 5 4 3 2 1 0
Bit Address
AFh AEh ADh ACh ABh AAh A9h A8h
Explanation of Function Global Interrupt Enable/Disable Undefined Undefined Enable Serial Interrupt Enable Timer 1 Interrupt Enable External 1 Interrupt Enable Timer 0 Interrupt Enable External 0 Interrupt
TF Interrupt
Each of the 8051s interrupts has its own bit in the IE SFR. You enable a given interrupt by setting the corresponding bit. To enable Timer 1 Interrupt, use: MOV IE,#08h or SETB ET1 Both of the above instructions set bit 3 of IE, thus enabling Timer 1 Interrupt. Once Timer 1 Interrupt is enabled, whenever the TF1 bit is set, the 8051 will automatically put "on hold" the main program and execute the Timer 1 Interrupt Handler at address 001Bh.
Before Timer 1 Interrupt (or any other interrupt) is truly enabled, bit 7 of IE has to be set. Bit 7, the Global Interupt Enable/Disable, enables or disables all interrupts simultaneously. That is to say, if bit 7 is cleared then no interrupts will occur, even if all the other bits of IE are set. Setting bit 7 will enable all the interrupts that have been selected by setting other bits in IE.
SETB ET1 SETB EA After this Timer 1 Interrupt Handler at 01Bh will automatically be called whenever the TF1 bit is set (upon Timer 1 overflow).
Type of Interrupt
Level-Triggered Interrupt
In this mode, INT0 and INT1 are normally high and if the low level signal is applied to them ,It triggers the Interrupt. Then the microcontroller stops and jumps to the interrupt vector table to service that interrupt .This is all the Level Triggered or Level -Activated interrupt and is the default mode/reset of 8051.
Polling Sequence
The 8051 automatically evaluates whether an interrupt should occur after every instruction. When checking for interrupt conditions, it checks them in the following order: External 0 Interrupt Timer 0 Interrupt External 1 Interrupt Timer 1 Interrupt Serial Interrupt This means that if a Serial Interrupt occurs at the exact same instant that an External 0 Interrupt occurs, the External 0 Interrupt will be executed first and the Serial Interrupt will be executed once the External 0 Interrupt has completed.
Interrupt Priorities
The 8051 offers two levels of interrupt priority: high and low. By using interrupt priorities, higher priority can be assigned to certain interrupt conditions. Timer 1 Interrupt which is automatically called every time Timer 1 overflows. Serial Interrupt which is called every time a character is received via the serial port. Assume that receiving a character is much more important than the timer interrupt. In this case, if Timer 1 Interrupt is already executing, the serial interrupt itself interrupts the Timer 1 Interrupt. When the serial interrupt is complete, control passes back to Timer 1 Interrupt and finally back to the main program. This accomplished by assigning a high priority to the Serial Interrupt and a low priority to the Timer 1 Interrupt.
Interrupt priorities are controlled by the IP SFR (B8h). The IP SFR has the following format:
Bit 7 6 5 Name Bit Address Explanation of Function Undefined Undefined Undefined
4
3 2
PS
PT1 PX1
BCh
BBh BAh
1
0
PT0
PX0
B9h
B8h
When considering interrupt priorities, the following rules apply: Nothing can interrupt a high-priority interrupt--not even another high priority interrupt. A high-priority interrupt may interrupt a low-priority interrupt. A low-priority interrupt may only occur if no other interrupt is already executing. If two interrupts occur at the same time, the interrupt with higher priority will execute first. If both interrupts are of the same priority the interrupt which is serviced first by polling sequence will be executed first.
1) The current Program Counter is saved on the stack, low-byte first. 2) Interrupts of the same and lower priority are blocked. 3) In the case of Timer and External interrupts, the corresponding interrupt flag is cleared. 4) Program execution transfers to the corresponding interrupt handler vector address. 5) The Interrupt Handler Routine executes.
Take special note of the third step: If the interrupt being handled is a Timer or External interrupt, the microcontroller automatically clears the interrupt flag before passing control to interrupt handler routine. This means it is not necessary clear the bit in code.
Serial Interrupts
Serial Interrupts are slightly different than the rest of the interrupts. This is due to the fact that there are two interrupt flags: RI and TI.
INT_SERIAL:
CHECK_TI:
EXIT_INT:
RETI
The code checks the status of both interrupts flags. If both flags were set, both sections of code will be executed. Each section of code clears its corresponding interrupt flag.
If the interrupt bits are not cleared, the serial interrupt will be executed over and over until it is cleared.
Thus it is very important to always clear the interrupt flags in a serial interrupt
Important Interrupt Consideration: Register Protection One very important rule applies to all interrupt handlers: Interrupts must leave the processor in the same state as it was in when the interrupt initiated.
A system is to read an external sensor continuously, and if its reading exceeds the 7-bit value more than 20D times, then reading should be terminated. Assume INT0 input is connected with the external circuit in such a way that it generates a high-to-low signal as an indication to read input port P1 and store it in data memory location 30H. If input at P1.7 is high, then memory location 31H should be decremented by 1. If location 31H becomes 0, then INT0 must be disabled. Initialize 31H with 20D before allowing first INT0 interrupt. Write the ISR and initialization routine for this INT0 interrupt.
;ISR for INT0. First two instructions save EXTI0: PUSH PSW PUSH ACC ;Read port P1 and store at 30H MOV A, P1 MOV 30H, A ;Check bit 7 (MSB) of input data. RLC A JC HIGHIN LOWIN: POP ACC POP PSW INTX0: RETI ;If bit 7 is not 0 HIGHIN: MOV A, 31H DEC A MOV 31H, A JNZ OVER ;Content of location 31H is 0 CLR IE.0 OVER: POP ACC POP PSW RETI
processor status.
;ALTERNATE ROUTINE EXTI0: PUSH PSW PUSH ACC MOV MOV JNC HIGHIN: 30H, P1 C, P1.7 OVER
OVER:
POP
POP
RETI
PSW
In a system, INT1 is connected with a hardware circuit, which generates a low-level signal as an interrupt. The signal is active (remain low) for 10 microseconds. The INT1 is to be used to read port 2and to store it in data memory location from 30H onwards. Whenever this port input becomes 00H, INT1 should be disabled. Develop initialization routine and also ISR.
;INITIALIZATION INITX1: MOV CLR 2FH, #30H TCON.2 ;INTIALIZE POINTER AT 2FH ;FOR 30H TO START ;SELECT LEVEL TRIGGERED ;INT1 ;ENABLE EXTERNAL ;INTERRUPT INT1 ;ENABLE ALL INTERRUPTS
;ISR
ORG 0013H
EXTI1: PUSH PSW PUSH ACC MOV MOV MOV R0, 2FH A, P2 @R0, A
INC
JNZ CLR
R0
OVER IE.2
OVER: POP
POP RETI
ACC
PSW
WRITE AN ASSEMBLEY LANGUAGE PROGRAM TO START A/D CONVERSION AND STORE THE RESULT IN ACCUMULATOR.
5V IN0 GND IN7 CLOCK ADC 0808/0809 Vcc D0
Vref(+)
SC
ALE
C B A
OE
EOC
D7
Vref(-)
SC-START CONVERSION, ALE-ADD. LATCH ENSBLE, OE-O/P ENABLE, EOC-END OF CONVESION, CBA-INPUT SELECT