;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Helm Helper Pic
; Switch Code, Mic Code, Accel. Code, Shift Reg. Code, SSP Code
; 218C Spring 2008
; Redneck Yacht Club
; Kuan Li, Stephanie Lue, Christine Tower
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
list P=PIC16F690
#include "p16f690.inc"
__config (_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC)
; Note: Timing is based on using the external resonator (10MHz)
;
; variable definitions
W_TEMP equ 0x70
STATUS_TEMP equ 0x71
overflow_count equ 0x20 ; counts number of timer 1 overflow (speed calc timer)
switch_count equ 0x21 ; counts number of switch hits (via input capture)
speed_calc equ 0x22 ; a flag, when = 1 2 sec have elapsed and the speed should be calc.
MicValue equ 0x24 ; when mic value = 1, a yell has occurred
Hi_PulseFlag equ 0x25 ; 7-segment variable
Lo_PulseFlag equ 0x26 ; 7-segment variable
number equ 0x27 ; the number that needs to be displayed on 7-segment
ClearCount equ 0x28 ; a counter in the display clear process
SpecialButton1 equ 0x29 ; variable for SpecialButton1 (other boats)
SpecialButton2 equ 0x2A ; variable for SpecialButton2 (other boats)
temp_reg3 equ 0x2B
temp_reg equ 0x2C
subtractcount equ 0x2D
div_storage equ 0x2E
temp_reg1 equ 0x2F
temp_reg2 equ 0x30
ADC_DATA equ 0x31
LED_data equ 0x32
tx_ssp_byte equ 0x33
team equ 0x34 ; if team =0, blue team; if team =1, red team
; Information to send back to xBee pic
NAV equ 0x23 ; the navigation byte
SPECIAL equ 0x2B ; the special byte
;multiply and divide variables:
number2 equ 0x72
multiplier equ 0x73
result_multiply equ 0x74
numerator equ 0x75
denominator equ 0x76
result_divide equ 0x77
;
; #Defines
; Button Count Defines
#define TIMER_OVERFLOWS 0x26 ; this enables 76 overflows at 0.026s/overflow (every 2 seconds)
#define STOP_COUNT 0x00 ; 0 switch counts results in no movement
#define SLOW_COUNT 0x03 ; 1-3 switch counts results in slow movement
#define MEDIUM_COUNT 0x07 ; 3-7 switch counts results in medium movement
; > 7 switch counts results in fast movement
#define SSP_HEADER 0xAA
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 0
goto Main
org 4
goto InterruptServiceRoutine
org 5
;
; Tables can go here
;
DisplaySwitch:
addwf PCL,f
goto Case0
goto Case1
goto Case2
goto Case3
goto Case4
goto Case5
goto Case6
goto Case7
goto Case8
goto Case9
goto Case10
goto Case11
END_TBL:
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main
; Main program
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Main:
;
call SSP_Init
call InitializeSpeedSwitch
call InitializeMicrophone
call InitializeShiftRegister
call InitializeExtraButtons
call InitializeADC
call InitializeBaseLED
call ClearVariables
banksel TRISC
bcf TRISC,1
banksel ANSEL
bcf ANSEL,ANS5
;
Loop:
banksel PORTC
bsf PORTC,1
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
; Call all sensor functions
call GRAB_ADC
btfsc speed_calc,0 ; if speed_calc = 0, it is not time to get a new speed
call CalculateSpeed
call GetMicrophone
call GetExtraButtons
; Generate the packet
call GeneratePacket
; Send the packet
movlw SSP_HEADER ; send the sensor header byte
movwf tx_ssp_byte
call SSP
movf NAV,w
movwf tx_ssp_byte ; send the NAV byte
call SSP
movf SPECIAL,w
movwf tx_ssp_byte ; send the SPECIAL byte
call SSP
; Display boat number
call GetNumber ; get number out of LED_data byte
call GetTeam
call ClearDisplay
call DisplayNumber ; display number to 7-seg
call SetActiveBaseLED
banksel PORTC
bcf PORTC,1
goto Loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Setup for all the SSP:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SSP_Init:
banksel SSPSTAT ;The Sync Serial Port Status Register (pg 180 of manual)
bsf SSPSTAT,SMP ;Input data sampled at end of data output line. (clear for Slave mode)
nop
bsf SSPSTAT,CKE ;Data transmitted on falling edge of SCK
nop
banksel SSPCON ;The Sync Serial Port Control Register (pg 181 of manual)
bsf SSPCON,SSPEN ;SSP enable bit.
nop
bsf SSPCON,CKP ;Clock polarity Select Bit; transmit happens on rising edge, receive on falling edge
nop
;The SSP mode select.
;This is for the Slave mode: with clock = SCK pin, and SS pin control disabled
;----------------------
bcf SSPCON,SSPM3
nop
bsf SSPCON,SSPM2
nop
bcf SSPCON,SSPM1
nop
bcf SSPCON,SSPM0
nop
banksel ANSELH
bcf ANSELH,1 ; Sets the ANSEL9 (RC7) to digital input/output
nop
bcf ANSELH,2 ; Sets the ANSEL10 (RB4) to digital input/output.
banksel TRISC
bcf TRISC,7 ; Set the Data direction to output for the SDO for the SSP
nop
bsf TRISB,4 ; Set the Data direction to input for the SDI for the SSP
nop
banksel TRISB
; bcf TRISB,6 ; Clear the SCK to output for MASTER MODE on TRISB 6
; nop
bsf TRISB,6 ; SET the SCK to input for SLAVE MODE on TRISB 6
nop
;This is setting up the slave select line.
banksel ANSELH
bcf ANSELH,ANS8 ; This is to set control of the Slave select line.
banksel TRISC
; bcf TRISC,6 ; Clears the bit so that the SS is output (This is for MASTER)
; nop
bsf TRISC,6 ; Sets the bit so that the SS is input (this is for SLAVE)
nop
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize Speed Switch
; Configures Port C5 for the input capture and timer 1 for timer 1 overflow interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeSpeedSwitch:
;
; Configure NECESSARY ports
banksel TRISC
bsf TRISC,TRISC5 ; configure C5 as an input for input capture
; Timer 1 set up
banksel T1CON
bsf T1CON,TMR1ON ; Enable timer 1
bcf T1CON,TMR1CS ; Use internal clock
bcf T1CON,T1CKPS1 ; Set clock prescale to 1:1
bcf T1CON,T1CKPS0
; Enable input capture interrupts
banksel PIE1
bsf PIE1,CCP1IE ; enable capture/compare interrupts
; Configure input capture, every rising edge
banksel CCP1CON
bcf CCP1CON,CCP1M3
bsf CCP1CON,CCP1M2
bcf CCP1CON,CCP1M1
bsf CCP1CON,CCP1M0
banksel PIR1
bcf PIR1,CCP1IF ; clear the input capture interrupt flag
; Enable timer overflow interrupts
banksel INTCON
bsf INTCON,GIE ; enable global interrupts
bsf INTCON,PEIE ; enable peripheral interrrupts
banksel PIE1
bsf PIE1,TMR1IE ; enable timer 1 interrupts
banksel PIR1
bcf PIR1,TMR1IF ; clear the timer 1 interrupt flag
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeMicrophone
; Sets up ports for microphone input
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeMicrophone:
banksel TRISA
bsf TRISA,2 ; make port A2 an input from the microphone
banksel ANSEL
bcf ANSEL,ANS2 ; make port A2 digital I/O for mic
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeShiftRegister
; Sets up ports for shift register
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeShiftRegister:
; A0 is the CLOCK LINE
banksel ANSEL
bcf ANSEL, ANS0 ; A0 as a digital I/O
banksel TRISA
bcf TRISA,TRISA0 ; A0 as an output
; A1 is the DATA LINE
banksel ANSEL
bcf ANSEL, ANS1 ; A1 as a digital I/O
banksel TRISA
bcf TRISA, TRISA1 ; A1 as an output
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeExtraButtons
; Initializes buttons that we do not use (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeExtraButtons:
; Initialize ports for button inputs
banksel TRISC
bsf TRISC,TRISC2 ; configure C2 as an input for extra button 1
bsf TRISC,TRISC3 ; configure C3 as an input for extra button 2
banksel ANSEL
bcf ANSEL,ANS6 ; configure C2 as digital I/O
bcf ANSEL,ANS7 ; configure C3 as digital I/O
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeADC
; Initializes buttons that we do not use (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeADC:
;Setup for the port directions and etc.
banksel TRISC
bsf TRISC,0 ; Set the direction port to be input
banksel ANSEL
bsf ANSEL,ANS0 ; Set port C0 to be analog input.
banksel ADCON1
bsf ADCON1,5
bcf ADCON1,6
bcf ADCON1,4
banksel ADCON0
movlw b'00010001'
movwf ADCON0 ; Turn on ADC, right justified, VDD is ref, and AN4 active, don't start conversion
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitializeBaseLED
; Initializes ports for base LED
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InitializeBaseLED:
; Configure port for Blue Base Active LED
banksel TRISC
bcf TRISC,TRISC4 ; configure C4 as an output
; Configure port for Red Base Active LED
banksel TRISB
bcf TRISB,TRISB5 ; configure B5 as an output
; Configure port for Red Team LED
banksel TRISC
bcf TRISC,TRISC1
banksel ANSEL
bcf ANSEL,ANS1 ; configure C1 as an output
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClearVariables
; Initially clears all the registers used as variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClearVariables:
; Clear speed calculation variables
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
clrf overflow_count ; initially clear the overflow count value
clrf switch_count ; initially clear the number of switch hits
clrf speed_calc ; initially clear the command to calculate speed
clrf ADC_DATA ; initially clear the ADC variable
movlw 0x88 ; move not moving into the NAV byte
movwf NAV
; Clear microphone variables
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
clrf MicValue ; clear the MicValue
; Clear 7-segment variables
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
clrf number ; clear the number variable
clrf ClearCount ; clear the ClearCount variable
; Clear the special byte
clrf SPECIAL
; Clear the LED_data byte initially
clrf LED_data
; Set Base LED lines low
banksel PORTB
bcf PORTB,5
banksel PORTC
bcf PORTC,4
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SSP function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SSP:
; function for sending data from an address through the SSP
; The argument is the address of the data to be sent
sspcomplete1: ; wait until the flag is set
banksel SSPSTAT
pagesel sspcomplete1
BTFSS SSPSTAT, BF ; checks the status of the reg2 flag in the reg1 register.
GOTO sspcomplete1
banksel SSPBUF
MOVF SSPBUF, W ; contents of the SSBUF is now in w register
bcf STATUS,RP1 ; switch to bank 0 to
bcf STATUS,RP0
MOVWF LED_data ; save the receieved data to this variable
bcf STATUS,RP1 ; switch to bank 0 to
bcf STATUS,RP0
MOVF tx_ssp_byte,W ; prep the W reg with your data to send.
banksel SSPBUF
MOVWF SSPBUF ; sends out your transmit data.
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetNumber
; This function gets the boat number from the LED_data variable that is sent from the helm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetNumber:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
clrf number ; initially clear the number variable for 7-segment
btfsc LED_data,0
bsf number,0 ; set the 0 bit of number
btfsc LED_data,1
bsf number,1 ; set the 1 bit of number
btfsc LED_data,2
bsf number,2 ; set the 2 bit of number
btfsc LED_data,3
bsf number,3 ; set the 3 bit of number
movf number,f
btfss STATUS,Z
goto second_check
goto set_default
second_check:
; checks to see that "number" is valid
movlw 0x0C
subwf number,W
btfsc STATUS,C ; if C = 1 then number >= 12 ...THIS IS BAD
goto set_default
goto exit_get_number
set_default:
clrf number
incf number,f ; number is at default set to 1 now
exit_get_number:
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetTeam
; This function gets the team affiliation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetTeam:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
btfss LED_data,4 ; test the 4th bit of LED_data
goto set_blue_team
goto set_red_team ; if the 4th bit is set, on red team (odd number)
set_blue_team:
; clear bit 0 of team variable
goto exit_get_team
bcf PORTC,1
set_red_team:
goto exit_get_team
bsf PORTC,1
exit_get_team:
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClockPulse
; This function sets PORTA0 hi and low to pulse the clock...we do this when we want to send data out
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClockPulse:
banksel PORTA
bsf PORTA,0 ; set PORTA0 Hi
nop
nop
nop
bcf PORTA,0 ; set PORTA1 Lo
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DataHigh
; This function sets PORTA1 hi and then pulses the clock
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DataHigh:
banksel PORTA
bsf PORTA,1 ; set PORTA1 HI
nop
nop
pagesel ClockPulse
call ClockPulse ; pulse the clock after you've set the line hi
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DataLow
; This function sets PORTA1 low pulses the clock
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DataLow:
banksel PORTA
bcf PORTA,1 ; set PORTC3 LO
nop
nop
pagesel ClockPulse
call ClockPulse ; pulse the clock after you've set the line lo
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ClearDisplay
; This function sets PORTA1 hi and low to pulse the clock...we do this when we want to send data out
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ClearDisplay:
banksel ClearCount
movlw d'7' ; move 7 into W
movwf ClearCount ; move 7 into ClearCount
CountDownFrom8: ; this will call DataHi 8 times
pagesel DataHigh
call DataHigh
banksel ClearCount
decfsz ClearCount ; decrement ClearCount
goto CountDownFrom8
return ; done clearing all 8 registers
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DisplayNumpber
; Sets the 7-segment to display the correct number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DisplayNumber:
bcf STATUS,RP0
bcf STATUS,RP1
decf number ; decrement number (so that it goes from 0 - 11)
movf number,W ; move the number to W
call DisplaySwitch ; call the Display Switch statement
return ; exit the Display Number function
;
;
Case0: ; display team 1
pagesel DataHigh
call DataHigh ; going to Q7
call DataHigh ; going to Q6
call DataHigh ; going to Q5
call DataHigh ; going to Q4
call DataLow ; going to Q3
call DataLow ; going to Q2
call DataHigh ; going to Q1
call DataHigh ; going to Q0
return
Case1: ; display team 2
pagesel DataHigh
call DataHigh ; going to Q7
call DataLow ; going to Q6
call DataHigh ; going to Q5
call DataLow ; going to Q4
call DataLow ; going to Q3
call DataHigh ; going to Q2
call DataLow ; going to Q1
call DataLow ; going to Q0
return
Case2: ; display team 3
pagesel DataHigh
call DataHigh ; going to Q7
call DataLow ; going to Q6
call DataHigh ; going to Q5
call DataLow ; going to Q4
call DataLow ; going to Q3
call DataLow ; going to Q2
call DataLow ; going to Q1
call DataHigh ; going to Q0
return
Case3:
pagesel DataHigh
call DataHigh ; going to Q7
call DataLow ; going to Q6
call DataLow ; going to Q5
call DataHigh ; going to Q4
call DataLow ; going to Q3
call DataLow ; going to Q2
call DataHigh ; going to Q1
call DataHigh ; going to Q0
return
Case4:
pagesel DataHigh
call DataHigh ; Q7
call DataLow ; Q6
call DataLow ; Q5
call DataLow ; Q4
call DataHigh ; Q3
call DataLow ; Q2
call DataLow ; Q1
call DataHigh ; Q0
return
Case5:
pagesel DataHigh
call DataHigh
call DataLow
call DataLow
call DataLow
Call DataHigh
call DataLow
call DataLow
call DataLow
return
Case6:
pagesel DataHigh
call DataHigh
call DataHigh
call DataHigh
call DataHigh
call DataLow
call DataLow
call DataLow
call DataHigh
call DataHigh
return
Case7:
pagesel DataLow
call DataHigh
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
return
Case8:
pagesel DataHigh
call DataHigh
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
call DataHigh
call DataHigh
return
Case9:
pagesel DataHigh
call DataHigh
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
call DataLow
call DataHigh
call DataLow
return
Case10:
pagesel DataLow
call DataHigh ; Q7
call DataLow ; Q6
call DataLow ; Q5
call DataHigh ; Q4
call DataHigh ; Q3
call DataLow ; Q2
call DataLow ; Q1
call DataLow ; Q0
return
Case11:
pagesel DataHigh
call DataHigh
call DataHigh
call DataHigh
call DataLow
call DataLow
call DataHigh
call DataHigh
call DataLow
call DataLow
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SetActiveBaseLED
; lights the appropriate LED (red or blue) depending on an admiral command to the helm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SetActiveBaseLED:
;
banksel PORTC
bcf PORTC,4
banksel PORTB
bcf PORTB,5
TestRed:
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
btfss LED_data,4 ; test the state of the Red Base LED bit
goto TestBlue
banksel PORTC
bsf PORTC,4 ; set PORTC, 4 line high to turn on Red Base LED
goto exit_set_LED
TestBlue:
btfss LED_data,5
goto exit_set_LED ; this shouldn't happen
banksel PORTB
bsf PORTB,5 ; set PORTB, 5 line high to turn on Blue Base LED
exit_set_LED:
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CalculateSpeed
; When a timer overflow has occurred, its time for the speed to be calculated :)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CalculateSpeed:
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
SpeedCalculation:
movlw STOP_COUNT
xorwf switch_count,W
btfsc STATUS,Z ; if Z = 1 then switch_count = 0
goto StopSpeed
movlw SLOW_COUNT
subwf switch_count,W
btfss STATUS,C ; if C = 1 then switch_count >= SLOW_COUNT
goto SlowSpeed
movlw MEDIUM_COUNT
subwf switch_count,W
btfss STATUS,C ; if C = 1 then switch_count >= MEDIUM_COUNT
goto MediumSpeed
goto FastSpeed
StopSpeed:
bsf NAV,3 ; write STOP (x08) to NAV direction nibble (will swapf later)
nop
bcf NAV,2 ; write bit-wise as to not affect
nop
bcf NAV,1 ; assignments to NAV in the direction
nop
bcf NAV,0 ; nibble
goto ExitCalculateSpeed
SlowSpeed:
bsf NAV,3 ; write SLOW (x0A) to NAV direction nibble (will swapf later)
nop
bcf NAV,2 ; write bit-wise as to not affect
nop
bsf NAV,1 ; assignments to NAV in the direction
nop
bcf NAV,0 ; nibble
goto ExitCalculateSpeed
MediumSpeed:
bsf NAV,3 ; write MEDIUM (x0C) to NAV direction nibble (will swapf later)
nop
bsf NAV,2 ; write bit-wise as to not affect
nop
bcf NAV,1 ; assignments to NAV in the direction
nop
bcf NAV,0 ; nibble
goto ExitCalculateSpeed
FastSpeed:
bsf NAV,3 ; write FAST (xFF) to NAV direction nibble (will swapf later)
nop
bsf NAV,2 ; write bit-wise as to not affect
nop
bsf NAV,1 ; assignments to NAV in the direction
nop
bsf NAV,0 ; nibble
goto ExitCalculateSpeed
ExitCalculateSpeed:
clrf switch_count ; reset the value of switch count = 0
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
clrf speed_calc ; reset the value of speed calc
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetMicrophone
; Poles port A2 to see if it is high (the microhpone is triggered for pump to be on)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetMicrophone:
banksel PORTA
btfsc PORTA,2 ; test the state of Port A2
goto NoMic ; the microphone input is not high
goto Mic ; the microphone input is high
NoMic:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bcf MicValue,0 ; clear bit 1 of MicValue, no input
return
Mic:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bsf MicValue,0 ; set bit 1 of MicValue, input
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GetExtraButtons
; Poles ports C2 and C3 to see the state of the special function buttons (for controlling other boats)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GetExtraButtons:
TestButton1:
banksel PORTC ; test the state of extra button 1
btfss PORTC,2
goto Extra1Low ; if low, go to Extra1Low
goto Extra1High ; if high, go to Extra1High
Extra1Low:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bcf SpecialButton1,0 ; clear SpecialButton1 bit 0
goto TestButton2
Extra1High:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bsf SpecialButton1,0 ; set SpecialButton1 bit 0
goto TestButton2
TestButton2:
banksel PORTC ; test the state of extra button 2
btfss PORTC,3
goto Extra2Low ; if low, go to Extra2Low
goto Extra2High ; if high, go to Extra2High
Extra2Low:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bcf SpecialButton2,0 ; clear SpecialButton1 bit 0
return
Extra2High:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
bsf SpecialButton2,0 ; set SpecialButton1 bit 0
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GRAB_ADC
; determines the direction we want to go
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GRAB_ADC:
;This simply grabs ADC and stores it.
call LONGNOP
banksel ADCON0
BSF ADCON0,1 ; Starts the conversion
BTFSC ADCON0,1 ; Is the conversion done?
GOTO $-1 ; No, test again.
banksel ADRESH
movf ADRESH,w
movwf ADC_DATA
;This converts the ADC from 8bit data to a 4bit nibble.
movlw 0x27
subwf ADC_DATA, f ; subtract: ADC - 39, store back into ADC_DATA
movlw 0x02
movwf temp_reg1
MULTIPLY ADC_DATA,temp_reg1,temp_reg2 ; multiply (ADC-39) * 2 into temp_reg2
DIVIDE temp_reg2,d'11',ADC_DATA
bcf STATUS,RP0
bcf STATUS,RP1
bcf NAV,4
bcf NAV,5
bcf NAV,6
bcf NAV,7
btfsc ADC_DATA,0
bsf NAV,4
btfsc ADC_DATA,1
bsf NAV,5
btfsc ADC_DATA,2
bsf NAV,6
btfsc ADC_DATA,3
bsf NAV,7
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GeneratePacket
; Generates the NAV and SPECIAL bytes to send back to the xBee helm pic
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
GeneratePacket:
; Generate the special byte
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
clrf SPECIAL ; initially clear the special byte
CheckWater:
bcf STATUS,RP0
bcf STATUS,RP1 ; switch to bank 0
btfss MicValue,0 ; see if MicValue bit 0 is set (water requested)
goto CheckSpecial1
bsf SPECIAL,0 ; set bit 0 (the only bit WE care about)
bsf SPECIAL,1 ; auto-set these for other boats
bsf SPECIAL,2 ; auto-set these for other boats
bsf SPECIAL,3 ; auto-set these for other boats
goto CheckSpecial1
CheckSpecial1:
bcf STATUS,RP0
bcf STATUS,RP1
btfss SpecialButton1,0 ; test to see if bit 0 of SpecialButton1 is set
goto CheckSpecial2
bsf SPECIAL,4 ; set bit 4 for special functions
goto CheckSpecial2
CheckSpecial2:
bcf STATUS,RP0
bcf STATUS,RP1
btfss SpecialButton2,0 ; test to see if bit 0 of SpecialButton2 is set
goto exit_generate
bsf SPECIAL,5 ; set bit 5 for special function
exit_generate:
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; LONGNOP
; creats a brief pause
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
LONGNOP:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
return
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ISR
; Handles timer overflow and input capture interrupts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InterruptServiceRoutine:
Push:
movwf W_TEMP ; Copy W to TEMP register
swapf STATUS, W ; Swap status to be saved into W
movwf STATUS_TEMP ; Save status to STATUS_TEMP register
InterruptSourceTest:
banksel PIR1
btfsc PIR1,CCP1IF ; test to see if the input capture flag was set
goto HandleSwitch ; handle the input capture
goto TimeoutTest ; else a timer overflow occured
TimeoutTest:
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
incf overflow_count
movlw TIMER_OVERFLOWS ; move 150 into W register
xorwf overflow_count,W
btfsc STATUS,Z ; if Z = 1, then overflow_count = 150
goto ResetTimer
banksel PIR1
bcf PIR1,TMR1IF ; clear the timer 1 overflow flag
goto Pop
HandleSwitch:
banksel PIR1
bcf PIR1,CCP1IF ; clear the input capture flag
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
incf switch_count ; increment the number of switch hits
goto Pop
ResetTimer:
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
movlw 0x01
movwf speed_calc ; set the value of speed_calc = 1, time to calculate speed
bcf STATUS,RP0
bcf STATUS,RP1 ; move to bank 0
clrf overflow_count ; clear the overflow counter
banksel PIR1
bcf PIR1,TMR1IF ; clear the timer 1 overflow flag
goto Pop
Pop:
swapf STATUS_TEMP, W ; swap nibbles in STATUS_TEMp register and place result in W
movwf STATUS ; Move W into STATUS register (sets bank to original state)
swapf W_TEMP, F ; Swap nibbles in W_TEMP and place result into W_TEMP
swapf W_TEMP, W ; Swap nibbles in W_TEMP and place result into W
retfie
END