|
用PIC12C509单片机控制LED
|
|
|
PIC12C509 - Getting Around the Stack Limitation ;PIC单片机 www.pic16.com The 12C5 series PIC has only a two level stack which limits the number of nested subroutine calls to two. This may be a very serious limitation. (The 16C84 has an eight level stack which permits nested subroutines to eight deep. I can't imagine a program where this will not be sufficient). In the following programs an alternative user stack is presented which provides the programmer with alternative "call" and "return" capability. Note that a user stack is implemented using the highest data address. The idea is that the user stack grows down from 1FH, while user variables are assigned from 07H and up. Thus, the degree of nesting permitted using this approach is the full variable space (25) less the number of bytes which are used as variables in the program. There are two other limitations to this approach; 1. Only the low byte of the program counter is saved on the user stack. Thus, this limits the calling of all functions and the implementation of the functions to the same page. However, this does not preclude one from splitting a program over several pages and implementing each called function on each page. Of course, the same implementation of functions on different pages must have different names. That is, one must be careful and think. But with the price of the 12C5XX declining to a mere $1.00 it pays to think! This approach of splitting a program is shown in another discussion dealing with the I2C bus. 2. The FSR is used as the user defined stack pointer. Thus, if the FSR register is used elsewhere, one must be careful to save the user stack pointer in a temporary variable when using the FSR for other applications and of course, restoring it to the FSR when calls and returns are made using this approach. Please refer to program STACK_1.ASM which continually flashes an LED on and off. Note that the main calls routines SUB1, DELAY, SUB2 and DELAY and then loops back to repeat the process. The FSR register is intialized to the highest data location, 01FH. Each "call" consists of the following instructions.
RET_POINT1: In the above, note that the current content of the low byte of the program counter is fetched. The address to return to (RET_POINT1) is calculated by adding 4 and this is saved to the location pointed to by the user stack pointer. The stack pointer is then decremented to accommodate the next return address. Finally, a jump to the function is executed. In the subroutine, the task is first performed. The "return" is then implemented using the following code.
In the above, the user stack pointer is incremented so as to point to the location containing the value of the program counter which was stored in the calling routine. This is fetched and placed in the low byte of the program counter. Thus, execution continues at the return point in the calling routine.
LOOP1 EQU 07H ; for timing loops ORG 000H MOVLW 1FH ; intitialize FSR to point to top of "stack" MOVLW .4 MOVLW 1EH ; least sign bit is an output MOVF PCL, W MOVF PCL, W MOVF PCL, W GOTO TOP SUB1: ; these three lines are the equiv of a return SUB2: DELAY: ; when running set LOOP1 to .250 and LOOP2 to .110. INCF FSR, F ; return END In program STACK_2.ASM, the "calls" and "returns" are implemented using macros which have been labelled as GOSUB and RET. Note that macros make the program considerably more understandable.
LIST p=12c509 ; Macros defined ENDM RET MACRO ; fetches return address from stack ENDM LOOP1 EQU 0CH ; for timing loops ORG 000H MOVLW 1FH ; intitialize FSR to point to top of "stack" MOVLW .4 SUB1: RET END -------------PIC单片机www.pic16.com----------- |
|