Code:
; Walter Dunckel [email protected]
; http://www.scalerobotics.com/PWMpassthrough.html
@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF
DEFINE OSC 8
INCLUDE "DT_INTS-14.bas";interrupt routines
INTCON = %10101000 '
OSCCON = %01110000 'set for 8mhz internal
CMCON0 = 7 'TURN COMPARITORS OFF
ANSEL = %00000000 'Set A/D OFF
ADCON0 = %00000000 'Analog converter OFF
TRISIO = %000100 'Set GSIO 4 and 2 to INPUT, others to OUTPUT
OPTION_REG = %11000010
T1CON = %00110001
T2CON = %01001110
CCP1CON = %00000101
Servo1 VAR GPIO.1
Servo2 var GPIO.0
Servo3 var GPIO.4
Servo4 var GPIO.5
GPIO = 0
TMR0 = 0
pulsebit var byte bank0
bittest VAR pulsebit.0 'tells us if first/2nd cycle of pulseout interrupt
pulsebit = 0
pulsebit.1 = 1 ' pulsebit.1=pulse1 measurement, .2 =2 and .3 =3
pulsebit.4 = 1 ' pulsebit.4 through 7 is channel output counter
rise1 var word bank0
rise1_l var rise1.byte0
rise1_h var rise1.byte1
rise2 var word bank0
rise2_l var rise2.byte0
rise2_h var rise2.byte1
rise3 var word bank0
rise3_l var rise3.byte0
rise3_h var rise3.byte1
fall1 var word bank0
fall1_l var fall1.byte0
fall1_h var fall1.byte1
fall2 var word bank0
fall2_l var fall2.byte0
fall2_h var fall2.byte1
fall3 var word bank0
fall3_l var fall3.byte0
fall3_h var fall3.byte1
RC1 var byte bank0
RC2 VAR byte bank0
RC3 var byte bank0
RC4 var byte bank0
RC5 var byte bank0
adj var byte bank1 ;adjustment centers values for pulse out byte
adj = 484
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag
INT_Handler CCP1_INT, PWMeasure, ASM, yes
INT_Handler TMR0_INT, PulseOut, ASM, yes
endm
INT_CREATE
INT_ENABLE TMR0_INT
INT_ENABLE CCP1_INT
ENDASM
Main:
RC1 = 255 - (fall1 - rise1 - adj) ;RC channel 1
RC2 = 255 - (rise2 - fall1 - adj)
RC3 = 255 - (fall2 - rise2 - adj)
RC4 = 255 - (rise3 - fall2 - adj)
RC5 = 255 - (fall3 - rise3 - adj)
GOTO Main
'---[TMR0_INT - interrupt handler]---
ASM
PulseOut
pulse1
btfss _pulsebit,4
goto pulse2
btfsc _bittest ;test are we at end of 1ms, or end of 2nd half
goto endpulse1 ;if high skip 7 lines
bcf INTCON,5 ;stop timer
movf _RC1,w ;load TMR0 with value of pulse variable
movwf TMR0
bsf _bittest ;set bittest, indicating we are on second half
bsf INTCON,5 ;start timer again for second interrupt
goto exitpulse ;skip to return from interrupt
endpulse1
bcf INTCON,5 ;stop timer
bcf _Servo1 ;bring ServoOut pin low for end of pulse width
bcf _bittest
movlw d'17' ;set timer0 for next 1ms time base
movwf TMR0
bcf _pulsebit,4 ;done with ch1
bsf _pulsebit,5 ;set for ch2
bsf INTCON,5 ;enable timer0 interrupt
bsf _Servo2 ;set Servo2 pin high (begin pulse width)
goto exitpulse
pulse2
btfss _pulsebit,5
goto pulse3
btfsc _bittest
goto endpulse2
bcf INTCON,5
movf _RC2,w
movwf TMR0
bsf _bittest
bsf INTCON,5
goto exitpulse
endpulse2
bcf INTCON,5
bcf _Servo2
bcf _bittest
movlw d'17'
movwf TMR0
bcf _pulsebit,5
bsf _pulsebit,6
bsf INTCON,5
bsf _Servo3
goto exitpulse
pulse3
btfss _pulsebit,6
goto pulse4
btfsc _bittest
goto endpulse3
bcf INTCON,5
movf _RC3,w
movwf TMR0
bsf _bittest
bsf INTCON,5
goto exitpulse
endpulse3
bcf INTCON,5
bcf _Servo3
bcf _bittest
movlw d'17'
movwf TMR0
bcf _pulsebit,6
bsf _pulsebit,7
bsf INTCON,5
bsf _Servo4
goto exitpulse
pulse4
btfsc _bittest
goto endpulse4
bcf INTCON,5
movf _RC4,w
movwf TMR0
bsf _bittest
bsf INTCON,5
goto exitpulse
endpulse4
bcf INTCON,5
bcf _Servo4
bcf _bittest
movlw d'17'
movwf TMR0
bcf _pulsebit,7
bsf _pulsebit,4
goto exitpulse
exitpulse
INT_RETURN
ENDASM
'---[CCP1_INT - Pulse Capture interrupt handler]--
ASM
PWMeasure
BTFSS CCP1CON, CCP1M0 ; Check for falling edge watch
GOTO FALL_EDGE ; Go pick up the falling edge
btfss _pulsebit,1 ; Is it time to capture leading edge of pulse1
goto $+6 ; No, skip 6 lines, try next
MOVF CCPR1L,W ; else store leading edge of pulse1
MOVWF _rise1_l ; into word rise1
MOVF CCPR1H,W
MOVWF _rise1_h
goto nextone ; pulse1 rise values done
btfss _pulsebit,2 ; Is it time to capture leading edge of pulse2
goto $+6 ; No, try next
MOVF CCPR1L,W ; else store leading edge of pulse2
MOVWF _rise2_l ; into word rise2
MOVF CCPR1H,W
MOVWF _rise2_h
goto nextone ; pulse2 rise values done
btfss _pulsebit,3 ; Is it time to capture leading edge of pulse3
goto $+5 ; Shouldn't really get here, but if we do
MOVF CCPR1L,W ; else store leading edge of pulse3
MOVWF _rise3_l ; into word rise3
MOVF CCPR1H,W
MOVWF _rise3_h ; pulse3 rise values done
nextone
BCF CCP1CON, CCP1M0 ; Now set capture for trailing edge
GOTO nextone2 ; Exit the interrupt service routine
FALL_EDGE:
BSF CCP1CON, CCP1M0 ; Re-set for trailing edge capture
btfss _pulsebit,1 ; Is it time to capture trailing edge of pulse1
goto $+8 ; No, skip 8 lines and try next
MOVF CCPR1L,W ; else store trailing edge of pulse1
MOVWF _fall1_l ; into word fall1
MOVF CCPR1H,W
MOVWF _fall1_h
bcf _pulsebit,1 ; got values for pulse1,now set for pulse2
bsf _pulsebit,2
goto nextone2 ; Done with pulse1
btfss _pulsebit,2 ; Is it time to capture trailing edge of pulse2
goto $+8 ; No, skip 8 lines to next test
MOVF CCPR1L,W ; else store store trailing edge of pulse2
MOVWF _fall2_l ; into word fall2
MOVF CCPR1H,W
MOVWF _fall2_h
bcf _pulsebit,2 ; got values for pulse2,now set for pulse3
bsf _pulsebit,3
goto nextone2 ; Done with pulse2
btfss _pulsebit,3 ; Is it time to capture trailing edge of pulse3
goto nextone2 ; No, end trailing edge check
MOVF CCPR1L,W ; else store trailing edge of pulse3
MOVWF _fall3_l ; into word fall3
MOVF CCPR1H,W
MOVWF _fall3_h
bcf _pulsebit,3 ; got values for pulse3,now set for pulse1
bsf _pulsebit,1
;**Setup pulseout for Servo1 (at end of capture start pulsing out)
bcf INTCON,2 ;clear timer flag if set
movlw d'17' ;set timer0 first 1ms time base
movwf TMR0
bsf INTCON,5 ;enable timer0 interrupt
bsf _Servo1 ;set Servo1 pin high (begin pulse width)
nextone2
INT_RETURN
ENDASM
Bookmarks