The software trap is a programming feature used to capture an abnormal program running status. The general principle is to setup a trap for software, and redirect from the code out of control to a specified address, and get back to its normal running mode. The software traps can be placed between the user codes or after the jump instructions, or be placed in the unused space by a consecutive trap codes. The most popular trap code for 80C51 is 5 byte instruction, which is :
0x200000: LJMP SWRST, SWRST is 0x0000
The purpose is quite clear. When the code is running out of order, the code will jump to this trap area sooner or later. If the code runs to the LJMP SWRST, it will jumps to the very beginning of the whole system to perform a software triggered reset, and the system can be restored to a normal working mode. The leading two NOPs are used to synchronize the code to the LJMP code.
PS, actually it is not a 5 byte trap, it is a 3 byte trap, but the first trap code must be 5 byte, because the consecutive trap is 0x00 0x00 0x20 0x00 0x00 0x20 0x00 0x00 ..., instead of 0x00 0x00 0x20 0x00 0x00 0x00 0x00 0x20 0x00 0x00.
There is another trap method with 4 byte instruction. It is:
0x200020: LJMP 0x0020
At the address of 0x0020, which stands for trap vector, we can put AJMP trap hander here. The 0x0020 of 80C51 is a spare code between T1 interrupt vector (0x001B) and SCON interrupt vector (0x0023). It is enough to put both T1 handler and trap code here. Actually 4 bytes are used. This approach is a little complex than the first one with additional code placed at 0x0020. But the initial requirement for this approach is one byte less and in some critical application one byte can save a system.
The code might run out of order any time, especially in an interrupt service routine. The 80C51 has two registers, a software emulated reset can not clear the hardware interrupt flag in software emulated reset. This is a solution :
SWRST: ; The real software reset address
CLR EA ; To clear EA
SETB F0 ; To setup a software reset flag in the general bit
MOV P0, #0FFH ; To setup GP0 as High impedence input mode
MOV PSW, #00H ; Clear PSW
MOV DPTR, #SWR0 ; A small trick here!
RETI ; clear high level registers, but the code is actually running to next byte
SWR0: CLR A
RETI ; Clear low level interrupt register and jump to 0x0000
- The EA should be disabled to make sure the whole process is done
- The RETI is the only instruction to clear interrupt enable register
- The PUSHACC and RETI is an alternative code for LJMP 0000H.
- Even the code has not triggered both interrupt registers, it is working as well.
- F0 or any other general purpose RAM can be used for software reset judgment for further software processing.
- No extra state change, no hardware is required.