; (C) Copyright Michael Ihde ; This code is released under the BSD license title "Servo Switch" #define _version "0.01" ;===================================================================== ; This program turns a servo type input into a on/off switch ; PD is the pulse detect output, normally off ; NORM_OFF is a normally off ouput ; NORM_ON is the complement of NORM_OFF ; STRB is a 1pps output ; One cycle is 1 us ;===================================================================== LIST R=DEC, P=16F84 ; Device Specification INCLUDE "p16F84.inc" ; Include Files/Registers __CONFIG _CP_OFF & _HS_OSC & _PWRTE_ON & _WDT_OFF #define SERVO_PULSE_IN PORTB, 0 #define PUP PORTB, 1 #define PD PORTB, 4 #define NORM_OFF PORTB, 5 #define NORM_ON PORTB, 6 #define WAIT PORTB, 7 ;===================================================================== ;===================================================================== ; Variables ;===================================================================== ;===================================================================== CBLOCK 0x30 count Dlay ENDC ;===================================================================== ;===================================================================== ; Code ;===================================================================== ;===================================================================== ORG 0x00 goto init ORG 0x04 goto interrupt ;===================================================================== ; The initialization section ;===================================================================== init movlw 0x01 ; GP0 is input tris PORTB ; set the tris bits with the contents in w clrf PORTB ; shut all outputs off at startup bsf PUP ; acknolwedge power up ;======================= ; setup the interrupt ;======================= ;bsf OPTION_REG, INTEDG ; rising edge bsf INTCON, GIE ; global interrupt enable bsf INTCON, INTE ; rb0 interrupt ;===================================================================== ; This section of code is the wait loop when the pulse is not changing ;===================================================================== pulse_wait ;======================= ; Set the ouputs to ; the no pulse state ;======================= bcf PD bcf NORM_OFF bsf NORM_ON bsf WAIT ;======================= ; Sleep here, an interrupt ; will wake the processor ;======================= clrf count ; reset count pulse_loop ;======================= ; begin waiting for the ; pulse to trigger the ; interrupt. The ; interrupt will keep ; clearing count ;======================= incf count, f btfsc STATUS, Z ; if we are zero assume overflow goto pulse_wait call Dlay98 goto pulse_loop ;======================= ; If we are here the ; pulse has disappered ;======================= goto pulse_wait ;===================================================================== ; The interrupt on rising edge of the pulse ; A servo pulse has started, begin timing how long it lasts ; the switch goes at the neutral position ; ; _|---------------|_________________ Neutral = 1.5 ms (60 loops) ; _|------------|____________________ 0 deg = 1.25 ms (50) ; _|------------------|______________ 180 deg = 1.75 ms (70) ; ; ;===================================================================== interrupt clrf count ; reset the timeout bcf INTCON, INTF ; clear the edge flag ;======================= ; time the pulse ;======================= bcf WAIT bsf PD pulse_h_loop ;======================= ; Every .025msec check ; (25 cycles) ; the if the pulse is ; still high ;======================= incf count, f btfsc STATUS, Z ; if we wrap around to zero assume overflow retfie ; and will assume the line is stuck ; high call Dlay23 btfsc SERVO_PULSE_IN ; if the pulse isn't low keep couting goto pulse_h_loop ;======================= ; Figure out what the ; outputs should be ;======================= movlw 50 subwf count, w btfss STATUS, C ; if clear a borrow occurd count < 60 goto set_off_state ; < 60 goto set_on_state ; > 60 set_off_state bcf NORM_OFF bsf NORM_ON goto ret_int set_on_state bsf NORM_OFF bcf NORM_ON goto ret_int ret_int clrf count ; reset the timeout retfie ;===================================================================== ;===================================================================== ; Subroutines ;===================================================================== ;===================================================================== ;===================================================================== ; Dlay23 - Delays 23 cycles (.025 msec with the call) (8 + (X - 1)*3) ; WARNING : Modifys w and Dlay ;===================================================================== Dlay23 nop ; 1 nop ; 1 movlw 6 ; 1 movwf Dlay ; 1 decfsz Dlay, f ; 1,2 goto $ - 1 ; 2 retlw 0 ; 2 ;===================================================================== ; Dlay98 - Delays 98 cycles (.100 msec with the call) (8 + (X - 1)*3) ; WARNING : Modifys w and Dlay ;===================================================================== Dlay98 nop nop movlw 31 movwf Dlay decfsz Dlay, f goto $ - 1 retlw 0 END