Top | Bottom
Go Back | Go
Forward
Tachometers, duty-cycle meters, capacitor checkers, and precise interval timers can all be implemented with Pulsin.
To use Pulsin, you must set the desired pin to input and supply three arguments: the pulse direction in state (0 = 1-to-0, 255 = 0-to-1), the pin number (0 to 7) in pin, and the port number (0 = RA, 1 = RB, etc.) in w. When Pulsin returns, the 16-bit pulse width will be in hiB and lowB, and an error code in w. State and pin will have been modified by Pulsin for its own use, so your program should keep copies of these variables if needed.
The error codes returned in w are as follows:
One hint on using Pulsin: 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.

; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.picnpoke.com email: sales@picnpoke.com *** ; *************************************************************************** ; ; PULSIN port (in w), pin, state ; Measures the width of an input pulse in 10-cycle (10 us at 4 MHz) units. ; Returns a 16-bit (0 to 65,535) value. If no pulse occurs within ; 65,535 10-cycle intervals, the routine returns an error code in w. ; Routine is edge triggered. If the input pin is already in the target state ; when the routine begins, it will wait for the state to change, then wait ; for the specified edge. The routine waits 65,535 x 10 cycles for ; each edge, so it normally returns within 0.65535 seconds (4 MHz). ; However, if each transition is delayed by close to the full 65,535 x 10 ; cycles, the routine can take nearly 2 seconds to return (4 MHz). P = pic16c55 #include <16c55.inc> ; processor assembler definitions _CONFIG _xt_osc & _wdt_off & _protect_off reset start org 8 pin Res d'1' ; Pin number to sample (0-7). state Res d'1' ; Trigger: 255 = 0-to-1 transition. hiB Res d'1' ; MSB of measurement. lowB Res d'1' ; LSB of measurement. ; Device data and reset vector org 0 ; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b). Pinz ADDWF pcl RETLW d'1' RETLW d'2' RETLW d'4' RETLW d'8' RETLW d'16' RETLW d'32' RETLW d'64' RETLW d'128' start MOVLW d'0' ; Outputs to display result on LEDs. TRIS 6h MOVLW d'0' TRIS 7h MOVLW b'00001111' ; All inputs TRIS 5h MOVLW d'0' ; Negative pulse. MOVWF state MOVLW d'2' ; Pin 2. MOVWF pin MOVLW d'0' ; Port ra. CALL Pulsin MOVF lowB,w ; Write Pulsin result to ports RB MOVWF 6h MOVF hiB,w ; and RC for viewing on LEDs. MOVWF 7h GOTO start ; Do it again. ; Upon entry, the desired pin must already be set up as an input. ; The w register contains a number representing the input port (0-2) for ; RA through RC. Variable pin contains the pin number (0-7). Variable state ; contains 255 for a 0-to-1 (positive) pulse, or 0 for a 1-to-0 (negative) pulse. ; Upon exit, the 16-bit count is in variables lowB and hiB. ; Variable pin contains the mask bit used by pulsin (not the pin number ; anymore, but a value with a 1 in the pin position), and state has been ; ANDed with pin. W contains the error code: 0= no error; 1= pin in ; already in target state when Pulsin was called--timeout waiting ; for transition; 2= timeout waiting for initial edge; 3= timeout waiting ; for final edge. Pulsin CLRF lowB ; Clear the 16-bit counter. CLRF hiB MOVWF fsr ; Point to the port number. MOVLW 5h ; Add offset for port RA. ADDWF fsr MOVF pin,w ; Get bit mask from the table. CALL Pinz MOVWF pin ; Put the mask into pin. ANDWF state ; Mask extra bits out of state. Pulsin_Hold MOVF indirect,w ; Sample the port. ANDWF pin,w ; Mask off bits other than pin. XORWF state,w ; Check pin against state. BTFSS status,z ; If pin <> state, set up for edge. GOTO Pulsin_doneH INCF lowB ; Otherwise, lowB = lowB+1. BTFSC status,z ; Overflow in lowB? INCFSZ hiB ; Yes: hiB=hiB+1, watch for overflow. GOTO Pulsin_Hold ; Sample the pin again. RETLW d'1' ; Overflow in hiB? Timed out: return. Pulsin_doneH CLRF lowB CLRF hiB Pulsin_Edge1 MOVF indirect,w ; Sample the port. ANDWF pin,w ; Mask off bits other than pin. XORWF state,w ; Check pin against state. BTFSC status,z ; If pin = state, wait until change. GOTO Pulsin_doneE INCF lowB ; Otherwise, lowB = lowB+1. BTFSC status,z ; Overflow in lowB? INCFSZ hiB ; Yes: hiB=hiB+1, watch for overflow. GOTO Pulsin_Edge1 ; Sample the pin again. RETLW d'2' ; Overflow in hiB? Timed out: return. Pulsin_doneE CLRF lowB CLRF hiB Pulsin_Edge2 MOVF indirect,w ; Sample the port. ANDWF pin,w ; Mask off bits other than pin. XORWF state,w ; Check pin against state. BTFSS status,z ; If pin <> state, we're done. GOTO Pulsin_done INCF lowB ; Otherwise, lowB = lowB+1. BTFSC status,z ; Overflow in lowB? INCFSZ hiB ; Yes: hiB=hiB+1, watch for overflow. GOTO Pulsin_Edge2 ; Sample the pin again. RETLW d'3' ; Overflow in hiB? Timed out: return. Pulsin_done RETLW 0h ; Done: pulsewidth in hiB, lowB. end
device pic16c55,xt_osc,wdt_off,protect_off
reset start
org
8
pin ds 1
; Pin number to sample (0-7).
state ds 1
; Trigger: 255 = 0-to-1 transition.
hiB ds 1
; MSB of measurement.
lowB ds 1
; LSB of measurement.
; Device data and reset vector
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 !rb,#0
; Outputs to display result on LEDs.
mov
!rc,#0
mov
!ra, #1111b ; All inputs
mov
state,#0 ; Negative pulse.
mov
pin,#2 ; Pin 2.
mov
w,#0
; Port ra.
call
Pulsin
mov
rb,lowB ; Write Pulsin
result to ports RB
mov
rc,hiB ; and RC for
viewing on LEDs.
jmp
start ; Do
it again.
; Upon entry, the desired pin must already be set up as an input.
; The w register contains a number representing the input port
(0-2) for
; RA through RC. Variable pin contains the pin number (0-7). Variable
state
; contains 255 for a 0-to-1 (positive) pulse, or 0 for a 1-to-0
(negative) pulse.
; Upon exit, the 16-bit count is in variables lowB and hiB.
; Variable pin contains the mask bit used by pulsin (not the pin
number
; anymore, but a value with a 1 in the pin position), and state
has been
; ANDed with pin. W contains the error code: 0= no error; 1= pin
in
; already in target state when Pulsin was called--timeout waiting
; for transition; 2= timeout waiting for initial edge; 3= timeout
waiting
; for final edge.
Pulsin clr lowB
; Clear the 16-bit counter.
clr
hiB
mov
fsr,w ; Point
to the port number.
add
fsr,#RA ; Add offset for
port RA.
mov
w,pin ; Get
bit mask from the table.
call
Pinz
mov
pin,w ; Put
the mask into pin.
AND
state,w ; Mask extra bits
out of state.
:Hold mov w,indirect
; Sample the port.
AND
w,pin ; Mask
off bits other than pin.
XOR
w,state ; Check pin against
state.
jnz
:doneH ; If pin <>
state, set up for edge.
inc
lowB
; Otherwise, lowB = lowB+1.
snz
; Overflow in lowB?
incsz hiB
; Yes: hiB=hiB+1, watch for overflow.
jmp
:Hold ; Sample
the pin again.
retw
1
; Overflow in hiB? Timed out: return.
:doneH clr lowB
clr
hiB
:Edge1 mov w,indirect
; Sample the port.
AND
w,pin ; Mask
off bits other than pin.
XOR
w,state ; Check pin against
state.
jz
:doneE ; If pin =
state, wait until change.
inc
lowB
; Otherwise, lowB = lowB+1.
snz
; Overflow in lowB?
incsz hiB
; Yes: hiB=hiB+1, watch for overflow.
jmp
:Edge1 ; Sample the
pin again.
retw
2
; Overflow in hiB? Timed out: return.
:doneE clr lowB
clr
hiB
:Edge2 mov w,indirect
; Sample the port.
AND
w,pin ; Mask
off bits other than pin.
XOR
w,state ; Check pin against
state.
jnz
:done ; If
pin <> state, we're done.
inc
lowB
; Otherwise, lowB = lowB+1.
snz
; Overflow in lowB?
incsz hiB
; Yes: hiB=hiB+1, watch for overflow.
jmp
:Edge2 ; Sample the
pin again.
retw
3
; Overflow in hiB? Timed out: return.
:done ret
; Done: pulsewidth in hiB, lowB.
Top | Bottom
Go Back | Go
Forward