;******************************************************************* ; mixer8.asm - came from mixer7.asm ; 2001/08/18 ; measure the length of 2 input servo pulses ; generate 2 output mixed sum and difference pulses ;******************************************************************* ; rtcc not used - ideal resolution is 5us not a prescale option ; use instruction timing instead ; instructions take 1us or 2us for branch type ; count loop takes 5us ; mid pulse = 1.52ms = 304 loops = 0x130h (256 + 48) ; desired count for mid pulse is 0 so ; preload counter with 0 - 0x30h = 0xd0h (208) ; can't tell which will come 1st so need to check both ;******************************************************************* ; LIST p=16F84A ; PIC16F84A is the target processor #include "P16F84A.INC" ; Include header file ; defines to find things easier ; ***** pic register equates ***** rtcc equ 1 ; counter register pc equ 2 ; program counter status equ 3 ; status register carry equ 0 ; carry bit zro equ 2 ; zero bit (note spelling) ; ***** port assignments ***** porta equ 5 ; port a equates portb equ 6 ; port b equates ip0 equ 0 ; input 0 ip1 equ 1 ; input 1 opsum equ 2 ; sum output to servo opdif equ 3 ; dif output to servo lo0 equ 0ch ; use 1st spare register as lo byte counter hi0 equ 0dh ; use 2nd spare register as hi byte counter lo1 equ 0eh ; use 3rd spare register as lo byte counter hi1 equ 0fh ; use 4th spare register as hi byte counter sum equ 10h ; for sum op pulse timing dif equ 11h ; for dif op pulse timing pulse equ 12h ; counter for op pulse timing ; org 0 ; reset vector goto init ; start at init ; init ************************************************************** init movlw b'00000011' ; set a0-a1 inputs tris porta ; a2-a3 outputs clrf porta ; clear porta out bits movlw 0h ; set port b as all outs tris portb movlw b'00000010' ; rtcc pre-scalar /8 option ; 8us count loop = 2.048ms movlw b'01010101' ; alternate bits set movwf portb ; put the count out to port b movlw 0h ; 0 movwf lo0 ; init counters to 0 movwf hi0 ; movwf lo1 ; movwf hi1 ; ; *********************************************************** ; wait for either input0 or 1 to go from 0 to 1 (pulse start) ; *********************************************************** ; make sure both are low 1st wait0_0 btfsc porta, ip0 ; wait for 0 on 0 b wait0_0 ; wait0_1 btfsc porta, ip1 ; wait for 0 on 1 b wait0_1 ; ; *********************************************************** ; now check for either to go high - check when both done ; *********************************************************** wait1 btfsc porta, ip0 ; wait for 1 b then1 ; 0 came 1st btfsc porta, ip1 ; b then0 ; 1 came 1st b wait1 ; round again ;************************ ; then1 0 pulse came 1st ; *********************** then1 nop ; ; bsf porta, opsum ; echo the pulse call time0 ; measure the pulse then11 btfss porta, ip1 ; b then11 ; wait for ip1 to go hi call time1 ; measure the other pulse (ip1) b calc ; now do calc ;************************ ; then0 1 pulse came 1st ; *********************** then0 nop call time1 ; measure the pulse then01 btfss porta, ip0 ; b then01 ; wait for ip0 to go hi call time0 ; measure the other pulse (ip1) b calc ; now do calc ; ************************************************* ; calc - work out the timing for sum and dif pulses ; ************************************************* calc nop ; ; movlw 0h ; put 0 in w comf lo0 ; complement lo0 leave result in lo0 - invert it movf lo0, w ; temp use ip1 count rlf lo0, w ; shift the sign bit into carry rrf lo0, w ; div by 2 preserving sign movwf sum ; stick it in sum movf lo1, w ; temp use ip1 count rlf lo1, w ; shift the sign bit into carry rrf lo1, w ; div by 2 preserving sign addwf sum ; add to sum and result in sum call sumout ; do the sum pulse movf lo0, w ; temp use ip1 count rlf lo0, w ; shift the sign bit into carry rrf lo0, w ; div by 2 preserving sign movwf dif ; stick it in dif movf lo1, w ; temp use ip1 count rlf lo1, w ; shift the sign bit into carry rrf lo1, w ; div by 2 preserving sign subwf dif ; add to sum and result in sum call difout ; do the sum pulse b wait0_0 ; round again ; ************ ; sub routines ; ************ ; ******************************** ; time0 - time the 0 channel pulse ; ******************************** time0 movlw 0d0h ; frig counter for 0 at mid pulse movwf lo0 ; cnt0 incf lo0 ; count up - 1us nop ; pad 5us loop - 1us end0 btfsc porta, ip0 ; done - 1us b cnt0 ; not done yet - 2us retlw 0h ; return ; *********************************************************** ; ******************************** ; time1 - time the 1 channel pulse ; ******************************** time1 movlw 0d0h ; frig counter for 0 at mid pulse movwf lo1 ; cnt1 incf lo1 ; count up - 1us nop ; pad 5us loop - 1us end1 btfsc porta, ip1 ; done - 1us b cnt1 ; not done yet - 2us bcf porta, opdif ; echo the pulse movf lo1, w ; fetch the count movwf portb ; count out to portb retlw 0h ; return ; *********************************************************** ; ****************************** ; sumout - send the sum op pulse ; need a 5us loop ; need to go round 1x complete then time the 2nd ; ****************************** sumout nop ; movlw 0b0h ; preload the counter movwf pulse ; bsf porta, opsum ; start the pulse ;precnt cntsum1 decf pulse ; count up - 1us nop ; pad 5us loop - 1us btfss status, zro ; done - 1us b cntsum1 ; not done yet - 2us movf sum, w ; load the variable bit addlw 080h ; shift origin movwf pulse ; load the count cntsum2 decf pulse ; count up - 1us nop ; pad 5us loop - 1us btfss status, zro ; done - 1us b cntsum2 ; not done yet - 2us bcf porta, opsum ; stop the pulse retlw 0h ; return ; ****************************** ; difout - send the dif op pulse ; need a 5us loop ; need to go round 1x complete then time the 2nd ; ****************************** difout nop ; movlw 0b0h ; preload the counter movwf pulse ; bsf porta, opdif ; start the pulse ;precnt cntdif1 decf pulse ; count up - 1us nop ; pad 5us loop - 1us btfss status, zro ; done - 1us b cntdif1 ; not done yet - 2us movf dif, w ; load the variable bit addlw 080h ; shift origin movwf pulse ; load the count cntdif2 decf pulse ; count up - 1us nop ; pad 5us loop - 1us btfss status, zro ; done - 1us b cntdif2 ; not done yet - 2us bcf porta, opdif ; stop the pulse retlw 0h ; return END