| 
 So far, we have made the PIC flash an LED on and off. Then we were able 
to interact with our PIC by adding a switch, and so altering the flash rate. 
The only problem is, the program is very long and very wasteful of memory. 
It was fine when we were introducing the commands for the first time, but there 
must be a better way of doing it. Well there is (you knew that was coming, 
right?). 
Let us examine how we were actually turning the LED on and off. 
movlw              02h 
movwf              PORTA 
movlw              00h 
movlw              PORTA 
First we loaded our w register with 02h, then moved it to our PortA register to turn the LED on. To turn it off, we loaded w with 00h and then moved it to our PortA register. In between these routines we had to call a subroutine so that we could see the LED flashing. So, we had to move two sets of data twice (once into the w register then to PORTA) 
and call a subroutine twice (once for on and once for off). 
So, how can we do this more efficiently?  Simple. We use another instruction called XORF. 
The XORF instruction performs an Exclusive OR function on the register that 
we specify with the data we give it. We think we need to explain what on 
earth an Exclusive OR is before we go on. 
If we have two inputs, and one output, the output will only be a 1 if, and only if, the two inputs are different. If they are the same, then the output will be 0. Here is a truth table, for those who prefer to look at these: 
A          B         F 
0          0          0 
0          1          1 
1          0          1 
1          1          0 
Let us now look to what happens if we make B the same as our previous output, 
and just changing the value of A: 
A         B          F 
0          0          0 
0          0          0 
1          0          1 
1          1          0 
1          0          1 If we keep the value of A equal to 1, and we Exclusive OR it with the output, the output will toggle. For those 
who can’t see this from the truth table, here it is using binary: 
0          Current Output 
EX-OR With 1 1          New Output 
EX-OR With 1 0          New Output 
Hopefully you can see that by exclusive ORing the output with 1, we are now toglling 
the output from 0 to 1 to 0. 
So, to turn our LED on and off, we just need two lines: 
MOVLW     02h 
XORWF     PORTA,1 
What we are doing is loading our w register with 02h. We are then Exclusive ORing this number with whatever is on our PortA. 
If bit 1 is a 1, it will change to a 0. If bit 1 is a 0, it will change to 
a 1. 
Let’s run through this code a couple of times, to show how it is working in 
binary: 
                      PORTA 
                      00010 
xorwf               00000 
xorwf               00010 
xorwf               00000 
xorwf               00010 
We don’t even need to load the same value into our w register each time, so we can do this once at the beginning, and just jump back to our toggle command. Also, we don’t need to set up a value on our PortA 
register. Why? Well, because if on power up it is a 1, we will toggle it. 
We, on the other hand it is a 0 on power up, we will still toggle it. 
So, let us now see our new code. The first one is our original flashing 
LED, and the second is where we added a switch: 
Flashing LED 
;*****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 
movlw              
02h              
  ;Set up our w register with 02h. 
;****Turn the LED on and off**** 
Start                 xorwf               
PORTA,1        ;Toggle the LED 
;****Add a 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 
Delay 
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              ; 
return 
;****End of the program**** 
end           ;Needed by some compilers, and also 
               ;just in case we miss the goto 
instruction. 
Flashing LED With Switch: 
;*****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              01h               ;Set the Port A pins: movwf             TRISA             ;bit 1to output, bit 0 to input. bcf                  STATUS,5       
;Switch back to Bank 0 
movlw              02h                 ; 
Set up our w register with 02h 
;****Turn the LED on and off**** 
Start                 xorwf               
PORTA,1        ;Toggle the LED 
;****Check if the switch is closed 
BTFSC                   PORTA,0        ;Get the value from PORT A 
                                                   ;BIT 0. If it is a zero, 
call                         Delay             ;carry on as normal. 
                                                   ;If is a 1, then add an 
                                                   ;extra 
delay routine 
;****Add a delay 
call       Delay 
;****Check if the switch is still closed 
BTFSC                       PORTA,0      ;Get the value from PORT A 
                                                     ;BIT 0. If it is a zero, 
call                             Delay           ;carry on as normal. 
                                                     ;If is a 1, then add an 
                                                     ;extra 
delay routine 
;****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 
Delay 
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          ; 
return 
;****End of the program**** 
end     ;Needed by some compilers, and also           ;just in case we miss the goto 
instruction. 
We hope you can see that by just using one simple instruction, we have reduced the size of our program. In fact, just to show how much we have reduced our programs by, We have shown the two programs, what changes were made, and their sizes in the table below: 
Program                    Change             Size (Bytes) 
Flashing LED              Original                          120 
Flashing LED              Subroutine Added           103 
Flashing LED              XOR Function Used          91 
LED With Switch         Original                          132 
LED With Switch         XOR Function Used         124. 
So, not only have we learnt some new instructions, we have also reduced the size of our coding 
 Click here  >>>>  Tutorial 8  |