Pulsout

produces a pulse by inverting the state of the specified pin for a period of 1 to 65,535 units of 10 instruction cycles.

Pulsout can produce brief clock pulses to blip the enable lines of LCD modules and logic devices, or wide-range pulses to drive positioning servos. It differs from the Pwm command in two ways: it produces only one pulse each time it is called, and duty cycle is controlled by the ratio of the pulse width to the interval between pulses (if it is called repeatedly).

To use Pulsout, you must set the desired pin to output and supply three arguments: the desired length of the pulse in 10-instruction cycle units in the 16-bit variable consisting of hiB and lowB, the pin number (0 to 7) in pin, and the port number (0 = RA, 1 = RB, etc.) in w.

The type of pulse generated by Pulsout depends on the state of the pin's output latch when the routine is called. If pin is initially 1, Pulsout will invert it to 0 for the specified period of time, then restore it to 1. If it's initially 0, it will be set to 1 for the specified time, then cleared to 0.

Upon return, the contents of hiB and lowB will have been cleared, so keep copies of these values if they are required elsewhere in your program.

Half of Pulsout's 10-cycle delay is produced with nop instructions. If you want a 5-cycle version of Pulsout, remove the nops.

Pulsout, like the other routines that accept pin and port arguments, requires the short table Pinz. Remember that tables must be located in the first 256 words of a 512-word program memory page. One hint on using Pulsout: always assign the port number to w immediately before calling the routine. If you don't, some other instruction that uses w may change its contents, causing an error.

Demonstrating Pulsout.

To see Pulsout 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 PULSOUT.SRC. The 'scope will show a series of 100-µs pulses (assuming a 4-MHz clock for the PIC).
 



; PULSOUT port, pin, time
; Generates an output pulse in 10-cycle (10 us at 4 MHz) units, 
; based on a 16-bit (1 to 65,535) value. The pulse is the reverse
; of the pin's state when pulsout is called. For instance,  if the 
; specified pin is initially 1, Pulsout will invert it to make a 
; negative-going pulse. 

        org     8
hiB     ds      1       ; MSB of time. 
lowB    ds      1       ; LSB of time. 
pin     ds      1       ; Pin number to pulse (0-7). 

temp    ds      1       ; Temporary variables for time delay
temp2   ds      1       ; between pulses

; 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

start   mov     !ra, #0 ; All outputs. 
        clr     ra      ; Start with 0s. 
        mov     lowB,#10        ; 10 x 10-cycle pulse
        clr     hiB
        mov     pin,#2  ; Pin 2. 
        mov     w,#0    ; of port ra. 
        call    Pulsout ; Pulse pin high for 100 cycles. 
        call    delay   ; Wait a while between pulses. 
        jmp     start   ; Do it again. 
; Upon entry, the desired pin must already be set up as an output. 
; The w register contains a number representing the output port (0-2) for 
; RA through RC. Variable "pin" contains the pin number (0-7). The variables
; hiB and lowB are the MSB and LSB of the time argument. 

Pulsout 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. 
        mov     pin,w   ; Put the mask into pin
        NOT     hiB     ; Take twos complement
        NEG     lowB    ; of the 16-bit counter
        snz             ; If zero, lowB overflowed,
        inc     hiB     ; so carry into hiB.
        XOR     indirect,pin    ; Invert the selected pin. 

; The main timing loop. Remove the nops for 5-cycle resolution. 
:loop   jmp     $+1     ; Two-cycle "nop."
        jmp     $+1     ; Two-cycle "nop."
        nop     
        inc     lowB    ; lowB = lowB+1. 
        snz             ; Overflow in lowB? 
        incsz   hiB     ; Yes: hiB=hiB+1, watch for overflow. 
        jmp     :loop   ; If not overflow, do it again. 
        XOR     indirect,pin    ; Invert pin (back to initial state).
        ret             

; Delay routine for demonstration. Not required by Pulsout.  

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