; ===== HISTORY ===========
; Program by CatsEyes - 24 Nov 2003
; Comments added by Ironsides - 25 Nov 2003
; TRIM variable introduced by Ironsides for testing - 25 Nov 2003
; OFFSET variable introduced by CatsEyes for testing - 26 Nov 2003
; ===== CONFIGURATION =====
; FILE Reverser.asm
; PROCESSOR PIC12F675
LIST P=12f675 ; Define processor
#INCLUDE <P12F675.inc> ; Processor specific definitions
errorlevel -302 ; Suppress message 302
radix dec ; Everything in decimal
; unless otherwise indicated
;======= TRIM POTENTIOMETER ==========
; This version has no trim potentiometer
; A TRIM variable has been added to adjust the slave (reversed) servo to align
exactly with the master servo
;======= SPECIAL NOTE ==========
;In this application there is a requirement to subtract a number from a constant
(300) that gets into underflow/overflow
;under 8 bit arithmetic - that is, eight bits only produces 256 possible numbers
;To overcome this limitation, if the number is in the W register and you want
"300 - W", you can use:
;
; sublw 44
;
; Since 44 + 256 = 300.
;
; However, since we have a "low" function in the assembler, which extracts the
low-order byte of a value,
; we can use it:
;
; sublw low 300
;
; This is easier to read and results in the same thing, since extracting the low
byte of 300 yields 44.
; ===================
; Configuration word has the following values set:
; (See section 9.1, page 52 of the Microchip data sheet)
; * No Data protect
; * No code protect
; * No brown-out reset
; * No MCLR pin function
; * Power-up Timer enabled
; * Watchdog Timer disabled
; * Oscillator is INTOSC with no CLKOUT
__config B'110000100'
; ===== CONSTANTS =====
; Chip circuit context
GP_OUTPUT equ 1 ; GP1 = Output to servo
GP_INPUT equ 3 ; GP3 = Input from the receiver
; ===== VARIABLES =====
INPUT_PULSE equ 32 ; Input pulse width
TIMER_OUTPUT equ 33 ; Output pulse width for servo
TIMER equ 34 ; "Scratch" variable for timinout output pulses
TRIM equ 35 ; A number that will adjust the throw of the slave (reversed) servo
- DCS - 25 Nov 2003
OFFSET equ 36 ; Used to take the TRIM value to adjust the throw of the slaved
servo - CatsEyes - 26 Nov 2003
; ===== CODE =====
RST_VECT org 000h ; Power-on Reset vector
; Initializations
clrf GPIO ; All outputs to zero for now
bsf STATUS, RP0 ; Bank 1
movlw B'00001000' ; Tristate configuration: all outputs except pin 3
movwf TRISIO
; Disable the Analog/Digital module
; Note: we will come back to this to enable a trim potentiometer
; The A/D will use Vdd as a voltage reference - the ratio will stay constant
even as the flight pack voltage drops
clrf ANSEL ; Set GP<3:0> to digital I/O
bcf STATUS, RP0 ; Bank 0
; Disable comparator module
movlw B'00000111' ; Set GP<2:0> to digital I/O
movwf CMCON
; Initialize output
movlw 150
movwf TIMER_OUTPUT
; Input the TRIM variable DCS - 25 Nov 2003
; Set to a positive or negative INTEGER (no decimals) to adjust the throw of the
slaved servo where
;zero is neutral
movlw 5
movwf TRIM
; ===== Main outer program loop =====
MAIN_LOOP call ONE_PULSE ; Wait for and time one pulse
movf INPUT_PULSE, W ; Get input into W
movf TRIM, W ; Get trim value
addlw low 300 ; Add to "300" (nominal centre value)
movwf OFFSET ; Save offset value
movf INPUT_PULSE, W ; Get input into W
subwf OFFSET, W ; Subtract from offset value
movwf TIMER_OUTPUT ; Save to output timer
goto MAIN_LOOP
; Function: ONE_PULSE
; Description: process one pulse
; 1) Wait for input pulse to start
; 2) Time length of input pulse
; 3) Output a pulse to the servo using current timing
; -- Wait for input pulse to start --
ONE_PULSE btfss GPIO, GP_INPUT ; If GP3 is "set," pulse has started
goto ONE_PULSE ; If not, continue to wait
; -- Time length of input pulse --
clrf INPUT_PULSE ; Start at zero
IN_LOOP incf INPUT_PULSE, f ; (1) Increment each time around the loop
nop ; (2) No-ops to pad loop to be exactly 10 microsecond
nop ; (3)
nop ; (4)
nop ; (5)
nop ; (6)
nop ; (7)
btfsc GPIO, GP_INPUT ; (8) If GP3 is "clear," pulse has ended
goto IN_LOOP ; (9 & 10) Otherwise, continue with loop
; -- Output a pulse to the servo --
movf TIMER_OUTPUT, W ; Get current timing for servo pulse
movwf TIMER ; Save to "scratch" timer variable
bsf GPIO, GP_OUTPUT ; Start our pulse on GP1
OUTLOOP nop ; (1) No-ops to pad loop to be exactly 10 microsecond
nop ; (2)
nop ; (3)
nop ; (4)
nop ; (5)
nop ; (6)
nop ; (7)
decfsz TIMER, f ; (8) Decrement the timer
goto OUTLOOP ; (9 & 10) Loop if timer hasn't reached zero yet
bcf GPIO, GP_OUTPUT ; End our pulse on GP1
; That's it -- we're done!
return
END