Αστέρια ΑνενεργάΑστέρια ΑνενεργάΑστέρια ΑνενεργάΑστέρια ΑνενεργάΑστέρια Ανενεργά
 

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 I was introducing the commands for 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.  I think I 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 exlusive 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.  I, 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.

I 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, I 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!

Προσθήκη νέου σχολίου


Κωδικός ασφαλείας
Ανανέωση