Home > Electronic Tutorials > Microcontroller Tutorials - PIC > PIC Tutorial 5 - Subroutines

PIC Microcontroller Tutorial

PIC Tutorial 5 - Subroutines


A subroutine is a section of code, or program, than can be called as and when you need it. Subroutines are used if you are performing the same function more than once, for example creating a delay. The advantages of using a subroutine are that it will be easier to alter the value once inside a subroutine rather than, say, ten times throughout your program, and also it helps to reduce the amount of memory your program occupies inside the PIC.

Let us look at a subroutine:

ROUTINE                             COUNT        equ 255
LABEL                                 decfsz         COUNT,1
Goto            LABEL

First, we have to give our subroutine a name, and in this case we have chosen ROUTINE. We then type the code that we want to perform as normal. In this case, We have chosen the delay in our flashing led program. Finally, we end the subroutine by typing the RETURN instruction.

To start the subroutine from anywhere in our program, we simply type the instruction CALL followed by the subroutine name.

Let us look at this in slightly more detail. When we reach the part of our program that says CALL xxx, where xxx is the name of our subroutine, the program jumps to wherever the subroutine xxx resides. The instructions inside the subroutine are carried out. When the instruction RETURN is reached, the program jumps back to our main program to the instruction immediately following our CALL xxx instruction.

You can call the same subroutine as many times as you want, which is why using subroutines reduces the overall length of our program. However, there are two things you should be aware of. First, as in our main program, any constants must be declared before they are used. These can be either declared within the subroutine itself, or right at the start of the main program. We would recommend that you declare everything at the start of your main program, as then you know that everything is in the same place. Secondly, you must ensure that the main program skips over the subroutine. What We mean by this is if you put the subroutine right at the end of your main program, unless you use a ‘Goto’ statement to jump away from where the subroutine is, the program will carry on and execute the subroutine whether you want it to or not. The PIC does not differentiate between a subroutine and the main program.

Let us look at our flashing led program, but this time we will use a subroutine for the delay loop. Hopefully, you will see how much simpler the program looks, and also you will see how the subroutine works for real.

;*****Set up the Constants****

STATUS          equ       03h            ;Address of the STATUS register
TRISA             equ       85h           ;Address of the tristate register for port A
PORTA            equ       05h            ;Address of Port A
COUNT1          equ       08h            ;First counter for our delay loops
COUNT2          equ       09h            ;Second counter for our delay loops

;****Set up the port****

bsf                  STATUS,5       ;Switch to Bank 1
movlw              00h                ;Set the Port A pins
movwf              TRISA            ;to output
bcf                  STATUS,5       ;Switch back to Bank 0

;****Turn the LED on****

Start            movlw            02h          ;Turn the LED on by first putting it
          movwf           PORTA       ;into the w register and then on the port

;****Add a delay

          call                   Delay

;****Delay finished, now turn the LED off****

movlw              00h                ;Turn the LED off by first putting it
movwf              PORTA           ;into the w register and then on the port

;****Add another delay****

call                   Delay

;****Now go back to the start of the program
                     goto          Start      ;go back to Start and turn LED on again

;****Here is our Subroutine


Loop1          decfsz              COUNT1,1     ;This second loop keeps the LED
                  goto                 Loop1          ;turned off long enough for us to
                  decfsz              COUNT2,1     ;see it turned off
                  goto                 Loop1          ;

;****End of the program****

end                     ;Needed by some compilers, and also
                          ;just in case we miss the goto instruction.

Hopefully, you can see that by using a subroutine for our delay loop, we have reduced the size of the program. Each time we want a delay, either when the LED is on or off, we simply call the delay subroutine. At the end of the subroutine, the program goes back to the line following our ‘Call’ instruction. In the example above, we turn the LED on. We then call the subroutine. The program then returns so that we can turn the LED off. We call the subroutine again, and when the subroutine has finished, the program returns and the next instruction it sees is ‘goto Start’.

For those of you who are interested, our original program was 120 bytes long. By using the subroutine, we have reduced our program size down to 103 bytes. This may not seem to be that great, but seeing that we only have 1024 bytes in total inside the PIC, every little bit helps.

In the next tutorial, we will look at reading from the ports.

Click here  >>>>  Tutorial 6 (Reading from the I/O ports)

Note: To report broken links or to submit your projects please send email to Webmaster