; ; *************************************************************************** ; *** 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