Toggle

inverts the state of an output pin.

In assembly language, inverting the state of a pin (or any bit, for that matter) is a matter of XORing the register with a value containing a 1 in the corresponding position. For example, to invert bit 2 of port RA, you would use the instructions XOR ra, #00000100b.

PBASIC's Toggle also changes the pin's data direction to output by putting a 0 in the appropriate bit of the tristate (TRIS) register. (In assembly, a 0 in TRIS means makes a pin and output; a 1 makes it an input. This is the opposite of the BASIC Stamp.) The assembly-language example here changes only the output latch, not TRIS.

Of course, if you use a literal number to toggle a pin's state with XOR, you cannot change the pin to be toggled while the program is running. The literal number is coded as part of the machine-language instruction. The accompanying program listing is a port- and pin-independent Toggle routine. Write the pin number to pin, the port number to w, and call Toggle.

Demonstrating Toggle.

To see Toggle in operation, either run the program with the PSIM simulator, or connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run TOGGLE.SRC. When you apply power to the PIC, the LEDs connected to ports RB and RC will be inverted one-by-one, beginning with RB.0.


; TOGGLE port (in w), pin
; Toggles (inverts) the state of the specified port and pin.

        org     8
pin     ds      1       ; Pin number to set (0-7).

; Variables for the demo program--not required by Toggle.
p_index         ds      1       ; Copy of pin number, port number.
temp    ds      1       ; Temporary variables for time delay
temp2   ds      1       ; between outputs.

; Device data and reset vector
        device  pic16c55,xt_osc,wdt_off,protect_off
        reset   start
        org     0

; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b).
Pinz    jmp     pc+w
        retw    1,2,4,8,16,32,64,128

; The following demonstration code should show the value of being able to
; toggle a particular bit of a port based on a calculation performed while the
; program is running. As the variable p_index is incremented from 0 to 15,
; it is used to specify the pin and port to invert using Toggle.

start   mov     !rb, #0 ; All outputs on rb.
        mov     !rc, #0 ; All outputs on rc.
        mov     rb,#10101010b   ; Put a pattern of alternating lights
        mov     rc,#10101010b   ; onto rb and rc. 
        clr     p_index ; Clear p_index.
:loop   mov     pin,#7  ; Copy three lsbs of p_index into
        AND     pin,p_index     ; variable pin.
        mov     w,#1    ; IF p_index.3 = 0

        snb     p_index.3       ; THEN w = 1
        mov     w,#2    ; ELSE w = 2
        call    Toggle
        call    delay   ; Wait a while between toggles.
        inc     p_index ; Next pin/port.
        sb      p_index.4       ; IF p_index < 15 (rc.7)
        jmp     :loop   ; THEN :loop ELSE done
done    jmp     $       ; Endless loop.

; To use the routine Toggle, put the pin number into the variable pin
; and the port number into w. Then call Toggle. 

Toggle  mov     fsr,w   ; Point to the port number.
        ADD     fsr,#RA ; Add offset for port RA.
        mov     w,pin
        call    Pinz    ; Get bit mask from the table.
        XOR     indirect,w      ; Invert the selected bit
        ret

; Delay routine for demonstration. Not required by Toggle.

delay   djnz    temp,delay      ; Time delay to provide spacing
        djnz    temp2,delay     ; between highs.
        ret