Program Flow Instructions
This is the first set of instructions to learn. Each one will have an affect to the normal program flow. Usually, the program flow is line by line. This means that when for example a code on line 10 is executed, the next code to be executed will be on line 11. But this set of instructions may not work as usual. A GOTO for example may send the program flow from line 10 directly to line 100. Let's see the whole set of those instructions and then we will analyze them further.
If you are not familiar with the interrupt services, then you should not bother about the RETFIE instruction. Now, let's see the instructions one by one:
This is a very common way of changing the normal program flow of a program. The GOTO comes along with a program line or label. When the program flow reaches a GOTO instruction, then it directly goes to the program line or label placed in the k field. The k field can be from 0 to 2047, a 11-bit number.
We will distinguish two situations of GOTO, the near and the far GOTO. A near GOTO is a GOTO that the destination is within the same memory page with the GOTO instruction position. The far GOTO is when the destination belongs to different memory page than the GOTO instruction position. In this case, the PCLATH register must contain the correct page otherwise the GOTO will not be correct.Example
The most simple example is when we do a near GOTO:
. . . GOTO Label_1 . . . Label_1 . . .
In this case, when the program flow reaches the GOTO instruction, it will NOT run the following instructions, but instead, it will jump to the Label_1 position and it will continue running normally from this point and under.
Far GOTOs are a little bit more complicated. The bits of PCLATH needs to be set to the correct page position. There are two ways of doing this: Either by setting or clearing (bsf or bcf) the bits 4 and 3 of PCLATH manually, or using the MASM commang pagesel, that i find most easy.
Here is an example of manual setting the PCLATH bits for implementing a far GOTO instruction:
ORG 0x00h ;This is the position 0 in the program memory. This belongs to page 0 (0x00 - 0x7FF) BCF PCLATH, 4 ; BSF PCLATH, 3 ;These two instructions will select page 1 (0x800 - 0xFFF) GOTO Label_1_Far ;This is a far GOTO to another page than original position of this instruction . . . ORG 0xA00h ;This is the position 0xA00 in the program memory. This belongs to page 1 (0x800 - 0xFFF) Label_1_Far . .
And now another way. We will do exactly the same far GOTO as before, but now the pagesel command will be used:
ORG 0x00h ;This is the position 0 in the program memory. This belongs to page 0 (0x00 - 0x7FF) Pagesel Label_1_Far ;This command will select the appropriate page that Label_1_Far belongs to GOTO Label_1_Far ;This is a far GOTO to another page than original position of this instruction . . . ORG 0xA00h ;This is the position 0xA00 in the program memory. This belongs to page 1 (0x800 - 0xFFF) Label_1_Far . .
I think that you too will find this way easier to use. You must keep in mind though, that if you are using another compiler than MPASM, this command may not operate correctly or may have a different name.
This is a similar instruction to the GOTO. Everything described above applies to this instruction as well. There is though one great difference. This instruction will push the current position of the program flow to the stack. The stack, is a position where during a CALL instruction, the position where this instruction is will be written into the stack. On the other hand, during RETURN, RETFIE and RETLW instructions, the last position that was placed in the stack will be popped out and the program will continue from this point. The stack for the P16F88 is 8 levels deep, meaning that it can hold up to 8 CALLS with no return. The stack is LIFO (Last In First Out). This means that last position pushed into the stack, will be popped first on a return.
Let's understand the stack a little bit more. Suppose that the program flow is at line 0x100. Then you make a CALL to line 0x200. The last position that will be pushed into the stack will be the number 0x100. Then, after some instructions, you make a RETURN. The position that will be pushed out of the stack will be the 0x100, therefore, the program will continue running from the 0x100 position and under.
A more complicated example is with multiple CALLs with no return. Suppose that you are in line 0x100. you make a CALL to line 0x200. The last byte in the stack will be the position 0x100. Then, after some instructions, at line 0x210, you make another call to line 0x300. The position 0x210 will be pushed inside the stack. Then, at line 0x330 you make another CALL to line 0x482. The position 0x330 will also be pushed inside the stack. At this point, the stack would look like this:
On the first RETURN, RETRLW or RETFIE instruction, the last stack position shall be popped out and the program will continue from this point and under. This means that on the first RETURN, the program will continue from line 0x330 and under. The stack will change as follows:
The same will happen on the next RETURN. The last position (8) of the stack will be popped out and the program will continue from this point and under, in our case this would be the number 0x210. The stack will change to:
So, a set of CALL -> RETURN instructions are somehow like 'Go there' and 'Go back again' situation.Example
This is a simple CALL - RETURN example:
. CALL Label_1 ;The program flow will go directly to Label_1 position . . . Label_1 . . RETURN ;The program flow will go back to the last CALL position . ;Here this is directly under the CALL Label_1 instruction.
This instruction has already be described above at the CALL instruction. A remark should be made though, when the RETURN is done after a far CALL. As said before, to make a successful far CALL or GOTO instruction, the PCLATH bits must be changed so that the correct memory page is selected. During a RETURN though, this is not important. That is because the stack is 13-bit length and can hold the complete 13-bit memory position of a CALL instruction. Therefore, when popping a position from the stack, the program will return to the correct memory position, no matter which memory page it was before. It is highly recommended though to always switch to the currently running memory page. Due to the fact that the contents of PCLATH are unchanged after a RETURN, RETFIE or RETLW instruction, the user MUST re-select the correct memory page for any subsequent CALL or GOTO instruction.
To avoid errors that will kill your time trying to debug the program, remember to always select the target page during CALL and GOTO instructions, but also select the correct memory page after a RETURN, RETFIE, RETLW instruction as well. This will save you from many hours of debugging.
This instruction operates exactly as the previous-described RETURN instruction. The only difference is that right after a RETLW instruction, the W register will have the k field value as content.Example
. CALL Label_1 ;The program flow will go directly to Label_1 position . . . Label_1 . . RETLW 0x24 ;The program flow will go back to the last CALL position . ;Also, the W register will carry the 0x24 value
This is a very special RETURN instruction. It has a meaning to be used as a return after an interrupt request. The interrupts will be discussed thoroughly on later pages. This instruction will act exactly as the normal RETURN instruction. Also, it will set the GIE bit (Global Interrupt Enable) of the INTCON (INTerrupt CONtrol) register and will re-enable all interrupts.
Confirm your knowledge
There is an online test to check your knowledge on this page. You may reveal the test with the following button:
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise without the prior written permission of the author.
Read the Disclaimer
All trademarks used are properties of their respective owners.
Copyright © 2007-2009 Lazaridis Giorgos.
All rights reserved.