No, your mistake. I was talking about the so-called 'PPM' signal used to modulate the RF signal.
For a constant frame rate, the signal going to the servo is PWM.
Yes, I would say your comment on resolution being poor in the example you gave is correct.That make sense or have I got it all wrong?
Lefty
No, your mistake. I was talking about the so-called 'PPM' signal used to modulate the RF signal.
Getting back to the original question of 3 inputs and 3 output PWM's, a PIC 18fxx31 series chip would give you 3 to 4 channels of 14 bit PWM. This is assuming that the three inputs would in fact be three different channels on a single RX PPM stream.
On a Vex transmitter/receiver the synch pulse was around 8ms (low), the start pulse about .5ms(high) and the variable servo pulse was about 0.65-1.45ms(low).
Well my mistake for jumping in late on topic, I should know betterAgain, this is nothing to do with the original question? - who cares about the carrier transmisisons, the only outputs he has access to are the servo outputs from the receiver, which are a single 1-2mS pulse repeated every 20mS.
I'm working on an idea for a remote controlled device that could be simplified greatly if i can get a chip that can measure the pulse width of 3 and produce 3 pwm signals simultaniously, better yet measure 3 and output 6, I'm newer at this so if that's ridiculous forgive my ignorance.
Yea the little phone connector goes to the Vex controller box for processing. I think you are on the right track. Retail on the Vex transmitter is high.I didnt realize vex worked that way, so that would explain some of the confusion. Anyway, I'll be using traxxas and futaba, so I dont think it will come up. For what I can tell vex is no better but costs a lot more because it says its for robots.
Device 16F876
Dim Speed, Steer, C, Dead, Left, Right, Error
Freq=20
Define PortC=%00000000
Define PortB=%11111111
Define PortA=%11111111
Dead=30 'set dead band value
Set(CCP1=PWM)
Set(CCP2=PWM)
PERIOD_REG=249
Set(TIMER2_PRESCALER=1)
Set(TIMER2_POSTSCALER=1)
START(TIMER2)
OUTC(0)
OUTB(0)
Error=0
ReStart:
Left=0
Right=0
Loop:
PWM_Duty1L=Left
PWM_Duty2L=Right
Speed=Pulsein(portB, 7, 1)
If Speed=0 Then Goto NoPulse
If Speed>750 Then Speed=750
If Speed<250 Then Speed=250
Steer=Pulsein(portB, 6, 1)
If Steer=0 Then Goto NoPulse
Error=0 'both pulses OK
If Steer>750 Then Steer=750
If Steer<250 Then Steer=250
Steer=Steer-250
If Steer<250 Then Gosub TurnLeft
If Steer>249 Then Gosub TurnRight
Goto Loop
NoPulse:
Error=Error+1
If Error > 5 Then Goto ReStart
Goto Loop
TurnLeft:
C=250-Steer
Right=Speed+C
Left=Speed-C
Gosub Scale
Return
TurnRight:
C=Steer-250
Left=Speed+C
Right=Speed-C
Gosub Scale
Return
Scale:
Right=Right-250
Left=Left-250
If Left>10000 Then Left=0 'correct for negative number
If Right>10000 Then Right=0 'correct for negative number
If Right>500 Then Right=500
If Left>500 Then Left=500
If Right<250 Then Goto ReverseA
Goto ForwardA
Do_Left:
If Left<250 Then Goto ReverseB
Goto ForwardB
Done_Left:
Return
ReverseA:
Right=250-Right
Gosub Check_Dead
High PortC, 3
Goto Do_Left
ForwardA:
Right=Right-250
Gosub Check_Dead
Low PortC, 3
Goto Do_Left
ReverseB:
Left=250-Left
Gosub Check_Dead
High PortC, 4
Goto Done_Left
ForwardB:
Left=Left-250
Gosub Check_Dead
Low PortC, 4
Goto Done_Left
Check_Dead:
If Right<Dead Then Right=0
If Left<Dead Then Left=0
Return
end
; WinPicProg BASIC Compiler Version1.9
;
; Device 16F876
LIST P=16F876, W=2, X=ON, R=DEC
#INCLUDE P16F876.INC
__CONFIG 0x393A
;Flags register bit definitions
LEADZ EQU 0x00 ;set to show leading zeros
Lo EQU 0x05 ;set for I2C normal addressing
Hi EQU 0x06 ;set for I2C extended addressing
Err EQU 0x07 ;set for I2C error
;Pre-defined variables
TEMP1 EQU 32
TEMP2 EQU 33
RESTORE EQU 34
TEMP1_DU EQU 35
TEMP2_DU EQU 36
RESTORE_DU EQU 37
W_DU EQU 38
STATUS_DU EQU 39
Bit_Cntr EQU 40
Xmit_Byte EQU 41
Rcv_Byte EQU 42
LCD_DAT1 EQU 43
Delay_Count EQU 44
_N EQU 44
LCD_DAT2 EQU 45
LCD_DAT3 EQU 46
TEMP_LCD EQU 47
TEMP_LCD2 EQU 48
DELAY1 EQU 49
state EQU 50
pin EQU 51
hiRnd EQU 52
lowRnd EQU 53
Acc1L EQU 54
Acc1H EQU 55
Acc2L EQU 56
Acc2H EQU 57
Acc3L EQU 58
Acc3H EQU 59
Flags EQU 60
TenK EQU 61
Thou EQU 62
Hund EQU 63
Tens EQU 64
Ones EQU 65
Adr_Lo EQU 66
Adr_Hi EQU 67
Chip_Adr EQU 68
Data_Page EQU 69
ORG 0x00
GOTO _START1
ORG 0x010
#INCLUDE HANDLERS.INC
#INCLUDE MATHS.INC
_START1
CLRF RESTORE
CLRF Flags
BCF Flags, LEADZ
BANKSEL ADCON1
MOVLW 0x06
MOVWF ADCON1
BANKSEL PORTA
; Dim Speed, Steer, C, Dead, Left, Right, Error
VAR2 EQU 70;Speed
VAR4 EQU 72;Steer
VAR6 EQU 74;C
VAR8 EQU 76;Dead
VAR10 EQU 78;Left
VAR12 EQU 80;Right
VAR14 EQU 82;Error
; Freq=20
; Oscillator frequency set to 20MHz
; Define PortC=%00000000
BANKSEL TRISC
MOVLW 0
MOVWF TRISC
BANKSEL PORTC
; Define PortB=%11111111
BANKSEL TRISB
MOVLW 255
MOVWF TRISB
BANKSEL PORTB
; Define PortA=%11111111
BANKSEL TRISA
MOVLW 255
MOVWF TRISA
BANKSEL PORTA
; Dead=30
MOVLW 0
MOVWF VAR8+1
MOVLW 30
MOVWF VAR8
; Set(CCP1=PWM)
MOVF CCP1CON,W
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP1CON
; Set(CCP2=PWM)
MOVF CCP2CON,W
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP2CON
; PERIOD_REG=249
MOVLW 249
BANKSEL PR2
MOVWF PR2
BANKSEL TMR2
; Set(TIMER2_PRESCALER=1)
MOVF T2CON,W
ANDLW 0xF8
IORLW 0x00
MOVWF T2CON
; Set(TIMER2_POSTSCALER=1)
MOVF T2CON,W
ANDLW 0x07
IORLW 0x00
MOVWF T2CON
; START(TIMER2)
BSF T2CON, TMR2ON
; OUTC(0)
MOVLW 0
MOVWF PORTC
; OUTB(0)
MOVLW 0
MOVWF PORTB
; Error=0
MOVLW 0
MOVWF VAR14+1
MOVLW 0
MOVWF VAR14
; ReStart:
LAB1:
; Left=0
MOVLW 0
MOVWF VAR10+1
MOVLW 0
MOVWF VAR10
; Right=0
MOVLW 0
MOVWF VAR12+1
MOVLW 0
MOVWF VAR12
; Loop:
LAB2:
; PWM_Duty1L=Left
MOVF VAR10,W
MOVWF CCPR1L
; PWM_Duty2L=Right
MOVF VAR12,W
MOVWF CCPR2L
; Speed=Pulsein(portB, 7, 1)
MOVLW 7
MOVWF pin
MOVLW 0xFF
MOVWF state
MOVLW 1
CALL _PULSEIN
MOVF Acc1L, w
MOVWF VAR2
MOVF Acc1H, W
MOVWF VAR2+1
; If Speed=0 Then Goto NoPulse
MOVF VAR2+1 ,W
MOVWF Acc1H
MOVF VAR2,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 0
MOVWF Acc2L
CALL _COMP16
BTFSS STATUS, Z
GOTO IFLAB1
; Goto NoPulse
GOTO LAB3
IFLAB1:
; If Speed>750 Then Speed=750
MOVF VAR2+1 ,W
MOVWF Acc1H
MOVF VAR2,W
MOVWF Acc1L
MOVLW 2
MOVWF Acc2H
MOVLW 238
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB2
; Speed=750
MOVLW 2
MOVWF VAR2+1
MOVLW 238
MOVWF VAR2
IFLAB2:
; If Speed<250 Then Speed=250
MOVF VAR2+1 ,W
MOVWF Acc1H
MOVF VAR2,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 250
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB3
; Speed=250
MOVLW 0
MOVWF VAR2+1
MOVLW 250
MOVWF VAR2
IFLAB3:
; Steer=Pulsein(portB, 6, 1)
MOVLW 6
MOVWF pin
MOVLW 0xFF
MOVWF state
MOVLW 1
CALL _PULSEIN
MOVF Acc1L, w
MOVWF VAR4
MOVF Acc1H, W
MOVWF VAR4+1
; If Steer=0 Then Goto NoPulse
MOVF VAR4+1 ,W
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 0
MOVWF Acc2L
CALL _COMP16
BTFSS STATUS, Z
GOTO IFLAB4
; Goto NoPulse
GOTO LAB3
IFLAB4:
; Error=0
MOVLW 0
MOVWF VAR14+1
MOVLW 0
MOVWF VAR14
; If Steer>750 Then Steer=750
MOVF VAR4+1 ,W
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc1L
MOVLW 2
MOVWF Acc2H
MOVLW 238
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB5
; Steer=750
MOVLW 2
MOVWF VAR4+1
MOVLW 238
MOVWF VAR4
IFLAB5:
; If Steer<250 Then Steer=250
MOVF VAR4+1 ,W
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 250
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB6
; Steer=250
MOVLW 0
MOVWF VAR4+1
MOVLW 250
MOVWF VAR4
IFLAB6:
; Steer=Steer-250
MOVF VAR4,W
MOVWF Acc1L
MOVF VAR4+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR4
MOVF Acc1H, W
MOVWF VAR4+1
; If Steer<250 Then Gosub TurnLeft
MOVF VAR4+1 ,W
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 250
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB7
; Gosub TurnLeft
CALL LAB4
IFLAB7:
; If Steer>249 Then Gosub TurnRight
MOVF VAR4+1 ,W
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 249
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB8
; Gosub TurnRight
CALL LAB5
IFLAB8:
; Goto Loop
GOTO LAB2
; NoPulse:
LAB3:
; Error=Error+1
MOVF VAR14,W
MOVWF Acc1L
MOVF VAR14+1,W
MOVWF Acc1H
MOVLW 1
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Add16
MOVF Acc1L, W
MOVWF VAR14
MOVF Acc1H, W
MOVWF VAR14+1
; If Error > 5 Then Goto ReStart
MOVF VAR14+1 ,W
MOVWF Acc1H
MOVF VAR14,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 5
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB9
; Goto ReStart
GOTO LAB1
IFLAB9:
; Goto Loop
GOTO LAB2
; TurnLeft:
LAB4:
; C=250-Steer
MOVLW 250
MOVWF Acc1L
MOVLW 0
MOVWF Acc1H
MOVF VAR4,W
MOVWF Acc2L
MOVF VAR4+1,W
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR6
MOVF Acc1H, W
MOVWF VAR6+1
; Right=Speed+C
MOVF VAR2,W
MOVWF Acc1L
MOVF VAR2+1,W
MOVWF Acc1H
MOVF VAR6,W
MOVWF Acc2L
MOVF VAR6+1,W
MOVWF Acc2H
CALL _Add16
MOVF Acc1L, W
MOVWF VAR12
MOVF Acc1H, W
MOVWF VAR12+1
; Left=Speed-C
MOVF VAR2,W
MOVWF Acc1L
MOVF VAR2+1,W
MOVWF Acc1H
MOVF VAR6,W
MOVWF Acc2L
MOVF VAR6+1,W
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR10
MOVF Acc1H, W
MOVWF VAR10+1
; Gosub Scale
CALL LAB6
; Return
RETURN
; TurnRight:
LAB5:
; C=Steer-250
MOVF VAR4,W
MOVWF Acc1L
MOVF VAR4+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR6
MOVF Acc1H, W
MOVWF VAR6+1
; Left=Speed+C
MOVF VAR2,W
MOVWF Acc1L
MOVF VAR2+1,W
MOVWF Acc1H
MOVF VAR6,W
MOVWF Acc2L
MOVF VAR6+1,W
MOVWF Acc2H
CALL _Add16
MOVF Acc1L, W
MOVWF VAR10
MOVF Acc1H, W
MOVWF VAR10+1
; Right=Speed-C
MOVF VAR2,W
MOVWF Acc1L
MOVF VAR2+1,W
MOVWF Acc1H
MOVF VAR6,W
MOVWF Acc2L
MOVF VAR6+1,W
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR12
MOVF Acc1H, W
MOVWF VAR12+1
; Gosub Scale
CALL LAB6
; Return
RETURN
; Scale:
LAB6:
; Right=Right-250
MOVF VAR12,W
MOVWF Acc1L
MOVF VAR12+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR12
MOVF Acc1H, W
MOVWF VAR12+1
; Left=Left-250
MOVF VAR10,W
MOVWF Acc1L
MOVF VAR10+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR10
MOVF Acc1H, W
MOVWF VAR10+1
; If Left>10000 Then Left=0
MOVF VAR10+1 ,W
MOVWF Acc1H
MOVF VAR10,W
MOVWF Acc1L
MOVLW 39
MOVWF Acc2H
MOVLW 16
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB10
; Left=0
MOVLW 0
MOVWF VAR10+1
MOVLW 0
MOVWF VAR10
IFLAB10:
; If Right>10000 Then Right=0
MOVF VAR12+1 ,W
MOVWF Acc1H
MOVF VAR12,W
MOVWF Acc1L
MOVLW 39
MOVWF Acc2H
MOVLW 16
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB11
; Right=0
MOVLW 0
MOVWF VAR12+1
MOVLW 0
MOVWF VAR12
IFLAB11:
; If Right>500 Then Right=500
MOVF VAR12+1 ,W
MOVWF Acc1H
MOVF VAR12,W
MOVWF Acc1L
MOVLW 1
MOVWF Acc2H
MOVLW 244
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB12
; Right=500
MOVLW 1
MOVWF VAR12+1
MOVLW 244
MOVWF VAR12
IFLAB12:
; If Left>500 Then Left=500
MOVF VAR10+1 ,W
MOVWF Acc1H
MOVF VAR10,W
MOVWF Acc1L
MOVLW 1
MOVWF Acc2H
MOVLW 244
MOVWF Acc2L
CALL _COMP16
BTFSC STATUS, C
GOTO IFLAB13
; Left=500
MOVLW 1
MOVWF VAR10+1
MOVLW 244
MOVWF VAR10
IFLAB13:
; If Right<250 Then Goto ReverseA
MOVF VAR12+1 ,W
MOVWF Acc1H
MOVF VAR12,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 250
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB14
; Goto ReverseA
GOTO LAB7
IFLAB14:
; Goto ForwardA
GOTO LAB8
; Do_Left:
LAB9:
; If Left<250 Then Goto ReverseB
MOVF VAR10+1 ,W
MOVWF Acc1H
MOVF VAR10,W
MOVWF Acc1L
MOVLW 0
MOVWF Acc2H
MOVLW 250
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB15
; Goto ReverseB
GOTO LAB10
IFLAB15:
; Goto ForwardB
GOTO LAB11
; Done_Left:
LAB12:
; Return
RETURN
; ReverseA:
LAB7:
; Right=250-Right
MOVLW 250
MOVWF Acc1L
MOVLW 0
MOVWF Acc1H
MOVF VAR12,W
MOVWF Acc2L
MOVF VAR12+1,W
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR12
MOVF Acc1H, W
MOVWF VAR12+1
; Gosub Check_Dead
CALL LAB13
; High PortC, 3
BSF PORTC, 3
; Goto Do_Left
GOTO LAB9
; ForwardA:
LAB8:
; Right=Right-250
MOVF VAR12,W
MOVWF Acc1L
MOVF VAR12+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR12
MOVF Acc1H, W
MOVWF VAR12+1
; Gosub Check_Dead
CALL LAB13
; Low PortC, 3
BCF PORTC, 3
; Goto Do_Left
GOTO LAB9
; ReverseB:
LAB10:
; Left=250-Left
MOVLW 250
MOVWF Acc1L
MOVLW 0
MOVWF Acc1H
MOVF VAR10,W
MOVWF Acc2L
MOVF VAR10+1,W
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR10
MOVF Acc1H, W
MOVWF VAR10+1
; Gosub Check_Dead
CALL LAB13
; High PortC, 4
BSF PORTC, 4
; Goto Done_Left
GOTO LAB12
; ForwardB:
LAB11:
; Left=Left-250
MOVF VAR10,W
MOVWF Acc1L
MOVF VAR10+1,W
MOVWF Acc1H
MOVLW 250
MOVWF Acc2L
MOVLW 0
MOVWF Acc2H
CALL _Sub16
MOVF Acc1L, W
MOVWF VAR10
MOVF Acc1H, W
MOVWF VAR10+1
; Gosub Check_Dead
CALL LAB13
; Low PortC, 4
BCF PORTC, 4
; Goto Done_Left
GOTO LAB12
; Check_Dead:
LAB13:
; If Right<Dead Then Right=0
MOVF VAR12+1 ,W
MOVWF Acc1H
MOVF VAR12,W
MOVWF Acc1L
MOVF VAR8+1 ,W
MOVWF Acc2H
MOVF VAR8,W
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB16
; Right=0
MOVLW 0
MOVWF VAR12+1
MOVLW 0
MOVWF VAR12
IFLAB16:
; If Left<Dead Then Left=0
MOVF VAR10+1 ,W
MOVWF Acc1H
MOVF VAR10,W
MOVWF Acc1L
MOVF VAR8+1 ,W
MOVWF Acc2H
MOVF VAR8,W
MOVWF Acc2L
CALL _COMP16I
BTFSC STATUS, C
GOTO IFLAB17
; Left=0
MOVLW 0
MOVWF VAR10+1
MOVLW 0
MOVWF VAR10
IFLAB17:
; Return
RETURN
; end
CLRWDT
SLEEP
END
;
;Number of variables used:82 out of 127
NOLIST
_PULSEIN CLRF Acc1L
CLRF Acc1H
MOVWF FSR
MOVLW 0x05
ADDWF FSR
MOVF pin, w
CALL _PINZ
MOVWF pin
ANDWF state
Pulsin_Hold MOVF INDF, w
ANDWF pin, w
XORWF state, w
BTFSS STATUS, Z
GOTO Pulsin_doneH
INCF Acc1L
BTFSC STATUS, Z
INCFSZ Acc1H
GOTO Pulsin_Hold
GOTO Pulsin_Error
Pulsin_doneH CLRF Acc1L
CLRF Acc1H
Pulsin_Edge1 MOVF INDF, w
ANDWF pin, w
XORWF state, w
BTFSC STATUS, Z
GOTO Pulsin_doneE
INCF Acc1L
BTFSC STATUS, Z
INCFSZ Acc1H
GOTO Pulsin_Edge1
GOTO Pulsin_Error
Pulsin_doneE CLRF Acc1L
CLRF Acc1H
Pulsin_Edge2 MOVF INDF, w
ANDWF pin, w
XORWF state, w
BTFSS STATUS, Z
RETURN
INCF Acc1L
BTFSC STATUS, Z
INCFSZ Acc1H
GOTO Pulsin_Edge2
Pulsin_Error CLRF Acc1L
CLRF Acc1H
RETURN
LIST
NOLIST
_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'
_Sub16 COMF Acc2H ; Take two's complement
COMF Acc2L ; of Acc2. If zero, Acc2L
INCF Acc2L
BTFSC STATUS, Z ; overflowed, so carry
INCF Acc2H ; into Acc2H.
_Add16 BCF Flags, OverFlow ; clear overflow flag
MOVF Acc2L, w ; Add the LSBs. If carry,
ADDWF Acc1L
BTFSC STATUS, C ; increment MSB of sum.
INCF Acc1H
MOVF Acc2H, w ; Add the MSBs
ADDWF Acc1H
BTFSC STATUS, C ; check for sum overflow
BSF Flags, OverFlow ; set overflow flag
MOVF Acc1L, w ; return lobyte in W
RETURN
_Mult16
CLRF Acc3H ; Clear product to make
CLRF Acc3L ; way for new calculation.
MOVLW d'16' ; Number of bits to calc.
MOVWF TEMP1
Multiply_loop
BCF STATUS, C
RLF Acc3L ; Shift product left.
RLF Acc3H
BCF STATUS, C
RLF Acc1L ; Shift multiplicand left.
RLF Acc1H
BTFSS STATUS, C ; If carry, add multiplier
GOTO Multiply_skip
MOVF Acc2L,w ; to the product. Else skip.
ADDWF Acc3L
BTFSC STATUS, C ; 16-bit addition: prod+mulp
INCF Acc3H
MOVF Acc2H, w
ADDWF Acc3H
Multiply_skip
DECFSZ TEMP1
GOTO Multiply_loop
MOVF Acc3H, w
MOVWF Acc1H ; return answer in Acc1
MOVF Acc3L, w
MOVWF Acc1L ; with lobyte in W
RETURN
_DIV16 MOVF Acc2H, w ; Check for division by 0.
IORWF Acc2L, w
BTFSC STATUS, Z
RETLW d'255' ; Error code= 255: return.
MOVLW d'1' ; Otherwise, initialize variables
MOVWF TEMP1
CLRF TEMP2 ; index for the division.
CLRF Acc3H
CLRF Acc3L
Divide_sh_loop BTFSC Acc2H, d'7' ; Shift divisor left
GOTO Divide_d1
BCF STATUS, C ; until msb is in
RLF Acc2L ; Acc2H.7.
RLF Acc2H ; TEMP1 = no. of shifts+1.
INCF TEMP1
GOTO Divide_sh_loop
Divide_d1 BCF STATUS, C
RLF Acc3L ; Shift quotient left.
RLF Acc3H
MOVF Acc2L,w ; top = top - btm.
SUBWF Acc1L
BTFSC STATUS, C ; If top - btm < 0 then
GOTO Divide_d2
MOVLW d'1' ; top = top + btm
SUBWF Acc1H
BTFSC STATUS, C ; The idea is to do the
GOTO Divide_d2
INCF Acc1H ; the subtraction and comparison
MOVF Acc2L, w ; (top > btm?) in one step.
ADDWF Acc1L
goto Divide_reentr ; Then, if btm > top, undo <Microchip instruction>
Divide_d2 MOVF Acc2H, w ; the subtraction by adding
SUBWF Acc1H
BTFSS STATUS, C ; top and btm back together
goto Divide_less ; <Microchip instruction>
BSF Acc3L, d'0'
Divide_reentr
BCF STATUS, C
RRF Acc2H
RRF Acc2L
DECFSZ TEMP1
GOTO Divide_d1
MOVF Acc3H, w
MOVWF Acc1H ; return answer in Acc1
MOVF Acc3L, w
MOVWF Acc1L ; with lobyte in W
RETURN
Divide_less MOVF Acc2L, w ; btm > top, so
ADDWF Acc1L
BTFSC STATUS, C ; undo the subtraction by
INCF Acc1H ; adding them back together.
MOVF Acc2H, w
ADDWF Acc1H
goto Divide_reentr ; <Microchip instruction>
_SHIFTR MOVWF Acc2L
_LoopR BCF STATUS, C
RRF Acc1H, F
RRF Acc1L, F
DECFSZ Acc2L
GOTO _LoopR
MOVF Acc1L, W
RETURN
_SHIFTL MOVWF Acc2L
_LoopL BCF STATUS, C
RLF Acc1L, F
RLF Acc1H, F
DECFSZ Acc2L
GOTO _LoopL
MOVF Acc1L, W
RETURN
_CONVERT: ; Takes number in Acc1H:Acc1L
; Returns decimal in
; TenK:Thou:Hund:Tens:Ones
swapf Acc1H, w
iorlw B'11110000'
movwf Thou
addwf Thou,f
addlw 0XE2
movwf Hund
addlw 0X32
movwf Ones
movf Acc1H,w
andlw 0X0F
addwf Hund,f
addwf Hund,f
addwf Ones,f
addlw 0XE9
movwf Tens
addwf Tens,f
addwf Tens,f
swapf Acc1L,w
andlw 0X0F
addwf Tens,f
addwf Ones,f
rlf Tens,f
rlf Ones,f
comf Ones,f
rlf Ones,f
movf Acc1L,w
andlw 0X0F
addwf Ones,f
rlf Thou,f
movlw 0X07
movwf TenK
movlw 0X0A
Lb1:
addwf Ones,f
decf Tens,f
btfss 3,0
goto Lb1
Lb2:
addwf Tens,f
decf Hund,f
btfss 3,0
goto Lb2
Lb3:
addwf Hund,f
decf Thou,f
btfss 3,0
goto Lb3
Lb4:
addwf Thou,f
decf TenK,f
btfss 3,0
goto Lb4
return
_COMP16:
movf Acc1H, w
subwf Acc2H, w
btfss STATUS, Z
goto $+3
movf Acc1L, w
subwf Acc2L,
return
_COMP16I:
movf Acc2H, w
subwf Acc1H, w
btfss STATUS, Z
goto $+3
movf Acc2L, w
subwf Acc1L, w
return
LIST
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?