Code:
Loop
ifdef Debug
movlw 1
else
movlw 4 ; Wait a Quarter Second
endif
movwf Dlay + 2
clrf TMR1H ; Setup the Timer
clrf TMR1L
bsf T1CON, TMR1ON ; Enable the Counter
SecondLoopStart
ifdef Debug
movlw 1
else
movlw HIGH (50000 + 255) ; Inner Loop is 1/16 Second
endif
movwf Dlay + 1
ifdef Debug
movlw 1
else
movlw LOW (50000 + 255)
endif
SecondLoop
addlw 0x0FF
btfsc STATUS, Z
decfsz Dlay + 1, f
bra SecondLoop
decfsz Dlay + 2, f
bra SecondLoopStart
bcf T1CON, TMR1ON ; Stop the Timer
bsf ADCON0, GO ; Start the ADC Operation
bsf Polling ; Not Polling Yet
bcf STATUS, C
rrcf TMR1H, w ; Read the Timer with the Range 0-800
movwf TMR1Save + 1
rrcf TMR1L, w
movwf TMR1Save ; In Range 0 to 400
bcf STATUS, C
rrcf TMR1Save + 1, f
rrcf TMR1Save, f ; In Range 0 to 200
bcf STATUS, C
rrcf TMR1Save + 1, f
rrcf TMR1Save, f ; In Range 0 to 100
movlw 100 ; Go to a Maximum of 100
subwf TMR1Save, w
btfsc STATUS, C
subwf TMR1Save, f
btfsc ADCON0, GO ; Wait for ADC to Complete
bra $ - (2 * 1)
movf ADRESH, w ; Get the MSB 8 Bits of the ADC Operation
mullw 100 ; Get the Fraction of 100
movf PRODH, w
movwf SetSpeed ; Get the Set Speed to 100
movf TMR1Save, w ; Get the "DeltaSpeed"
subwf SetSpeed, w
movwf DeltaSpeed
btfsc DeltaSpeed, 7 ; Output the Delta Speed on LEDs (RB0-RB4)
bra LEDNegative
movlw 3 ; Is the Difference Between 0 and 2?
subwf DeltaSpeed, w
bc LEDPosGreat
bcf PORTB, 2 ; Yes, Nuts On
bra RetryLoop
LEDPosGreat
movlw 6 ; Is the Difference Between 3 and 5
subwf DeltaSpeed, w
bc LEDPosOut
bcf PORTB, 1 ; Yes, Slight Difference
bra RetryLoop
LEDPosOut ; Difference Greater than 5
bcf PORTB, 0
bra RetryLoop
LEDNegative ; What is the Negative Value
movf DeltaSpeed, w
sublw 0
movwf LEDTemp
movlw 3 ; Between 0 and -2?
subwf LEDTemp, w
bc LEDNegGreat
bcf PORTB, 2 ; Yes, Nuts On
bra RetryLoop
LEDNegGreat
movlw 6 ; Difference Between -3 and -6?
subwf LEDTemp, w
bc LEDNegOut
bcf PORTB, 3
bra RetryLoop
LEDNegOut ; Else, Out there
bcf PORTB, 4
RetryLoop ; Keep Retrying Here
clrf FSR1H ; Use FSR1 for the Received Data
movlw LOW RXData
movwf FSR1L
movf RCREG, w ; Make Sure Receive is Clear
bcf PIR1, RCIF ; As well As Interrupt Requests
movlw 0x01F ; Turn Off Delta Speed LEDs
iorwf PORTB, w
movf DeltaSpeed, w
movwf DDSave ; Send to the PC
call DecDisplay ; Send as a Decimal String
movlw 0x01A ; Output Ctrl-Z for End of the Record
call CharDisplay
nop
CharWaitLoop
ifdef Debug ; Wait for PC Reply
movlw 1
else
movlw 16 ; Wait a Full Second
endif
movwf Dlay + 2
ThirdLoopStart
ifdef Debug
movlw 1
else
movlw HIGH (35714 + 255) ; Inner Loop is 1/16 Second
endif
movwf Dlay + 1
ifdef Debug
movlw 1
else
movlw LOW (35714 + 255)
endif
ThirdLoop
btfsc PIR1, RCIF ; Has a Character Been Received?
bra GetChar
addlw 0x0FF
btfsc STATUS, Z
decfsz Dlay + 1, f
bra ThirdLoop
bcf Polling ; Turn on the "Polling" LED
decfsz Dlay + 2, f
bra ThirdLoopStart
bra RetryLoop ; Nothing Received, Try Sending Again
GetChar ; Get the Character and Compare to a Ctrl-Z
movf RCREG, w ; Read Character and Reset the Interrupt Request Flag
bcf PIR1, RCIF
movwf POSTINC1 ; Save the Character
btg Receive ; Toggle the Receive LED
xorlw 0x01A ; End Character?
bnz CharWaitLoop ; Yes, Have the New PWM Value
bsf Receive ; Turn Off the LEDs
bsf Polling
bsf Sending
clrf NewPWM ; Clear the New PWM Value
movlw RXData ; Read the New PWM Value/Past +/-
movwf FSR1L
movf INDF1, w ; Do we Have a Valid Decimal or +/-
xorlw '+'
bz GetCharSkip ; Yes, Skip Over
xorlw '-' ^ '+'
bnz GetCharLoop
GetCharSkip ; Have a + or - Character
movf POSTINC1, w ; Increment FSR
GetCharLoop ; Loop Here Until \0 Char Encountered
movf NewPWM, w ; Multiply the "NewPWM" Variable by 10 to be ready for the Next Value
mullw 10
movf POSTINC1, w ; Add the Next Variable to it
bz HaveChar ; At the End of the String
xorlw "." ; Have Decimal Point (with Everything to the Right)
bz HaveChar
xorlw "."
andlw 0x00F
addwf PRODL, w
movwf NewPWM
bra GetCharLoop
HaveChar ; "NewPWM" has the New PWM Value
movlw '-'
xorwf RXData, w ; Is the First Character + or -?
bnz MakePosPWM ; Plus, Keep it the Way it is
MakeNegPWM ; Negative PWM, do the Subtraction
movf NewPWM, w ; Negate the Value in NewPWM
subwf CCPR1L, w
btfss STATUS, C
movlw 0
movwf CCPR1L ; Update the PWM Value
bra Loop
MakePosPWM ; Add the Delta PWM to Get the New Value
movf NewPWM, w
addwf CCPR1L, w
movwf TempPWM
movlw 200 ; Go to a Maximum of 200
subwf TempPWM, w
btfsc STATUS, C
subwf TempPWM, f
movf TempPWM, w ; Get the New PWM Value
movwf CCPR1L
bra Loop ; Finished with the Delta PWM Value, Loop Again
DecDisplay ; Send the 8 Bit Value in "DDSave" as a Decimal Number
; Out Via RS-232
movlw '0' ; Set up the Data to Output
movwf DDOut
movwf DDOut + 1
movwf DDOut + 2
movlw '+' ; Positive or Negative
movwf DDOut + 3
btfss DDSave, 7 ; 2's Complement Negative Number?
bra DD_Hund ; No, Calculate the Value
movf DDSave, w ; Invert the Value to Convert
sublw 0
movwf DDSave
movlw '-'
movwf DDOut + 3
DD_Hund ; Find Out what each Digit Values are
movlw LOW 100
subwf DDSave, w
bnc DD_Ten ; Can't Take Away any More Tens
movwf DDSave
incf DDOut + 2, f
bra DD_Hund
DD_Ten ; Find Out what each Digit Values are
movlw 10
subwf DDSave, w
bnc DD_One ; Can't Take Away any More Ones
movwf DDSave
incf DDOut + 1, f
bra DD_Ten
DD_One ; Find Out what each Digit Values are
movlw 1
subwf DDSave, w
bnc DD_Display ; Display the Value
movwf DDSave
incf DDOut, f
bra DD_One
DD_Display
clrf FSR0H ; Point to Data to Display
movlw LOW DDOut + 3
movwf FSR0L
DD_DNumber
movf POSTDEC0, w ; Display the Digit
TXOut
movlw LOW (DDOut - 1) ; Past the End?
subwf FSR0L, w
bnz DD_DNumber ; No, Loop Around Again
DD_NUL ; Output the NUL of the String
movlw 0x000
TXOut
return
CharDisplay ; Output the Character in "WREG"
TXOut
return
end