Code:
@ __config _XT_OSC & _WDT_OFF & _MCLRE_ON & _LVP_OFF & _CP_OFF
Clear
DEFINE OSC 4
TRISA = $07
TRISB = $05
CMCON = $06
INTCON = $10
OPTION_REG = $C0
UserSetting VAR WORD
Counter VAR BYTE
SampleValue VAR WORD
DataA VAR WORD
RawData VAR WORD [16]
Upd VAR BIT
READ 0,WORD UserSetting ; get user setting
IF UserSetting = 65535 then UserSetting = 0
Counter = 0
SampleValue = 0
Upd = 0
TMR1H = $B1:TMR1L = $E7 ; adjust timer1 to 50Hz @ 4MHz Prescale = 1
; -----------------Power on self test sound ---------------------
sound PORTB.1,[90,5,100,5,105,5,90,5,100,5,105,5,90,5,100,5,105,5,90,5,100,5,105,5]
PORTB.5 = 1 : PAUSE 1000 ; Red ON
PORTB.4 = 1 : PAUSE 1000 ; Red and Green ON
PORTB.5 = 0 : PAUSE 1000 ; Green ON
PORTB.4 = 0 ; all OFF
; ===============================================================
;---------By Darrel Taylor---------------------------------------
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler INT_INT, _SignalFound, PBP, yes
INT_Handler TMR1_INT, _SignalTimeOut, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
@ INT_ENABLE TMR1_INT ; Enable Timer1 Interrupts
@ INT_ENABLE INT_INT ; Enable RB0 Interrupts
;=================================================================
T1CON.0 = 1 ; Start timer1
GOTO Main
Main:
IF Upd = 1 THEN GOSUB UpdReading
IF PORTB.2 = 1 then GOSUB UpdUserSetting
GOTO Main
UpdUserSetting:
@ INT_DISABLE TMR1_INT ; Enable Timer1 Interrupts
@ INT_DISABLE INT_INT ; Enable RB0 Interrupts
pause 10
WRITE 0,WORD SampleValue ; Set this distance as Zero distance
sound PORTB.1,[123,10] ; Beep
UserSetting = SampleValue
@ INT_ENABLE TMR1_INT ; Enable Timer1 Interrupts
@ INT_ENABLE INT_INT ; Enable RB0 Interrupts
Debounce: if PORTB.2 = 1 then debounce
RETURN
UpdReading:
T1CON.0 = 0 ; Stop timer1
; Not in sight so keep the green light on
IF SampleValue-UserSetting < 50000 AND SampleValue-UserSetting >= 15 then
PORTB.5 = 1
PORTB.4 = 0
; Getting close so kep green + red light on
ELSEIF SampleValue-UserSetting < 15 AND SampleValue-UserSetting > 1 then
PORTB.5 = 1
PORTB.4 = 1
; got there so make the light red
ELSEIF SampleValue-UserSetting = 1 then
PORTB.5 = 0
PORTB.4 = 1
; too far, make the red light blink
ELSEIF SampleValue-UserSetting > 50000 THEN
PORTB.5 = 0
toggle PORTB.4
ENDIF
Upd = 0
T1CON.0 = 1 ; Start timer1
RETURN
'---[INT - interrupt handler]------Signal found at RB0, take a reading
SignalFound:
T1CON.0 = 0 ; Stop timer, Don't send burst during calculations
RawData(Counter) = TMR1H * 256 + TMR1L ; Add 15 readings to RaData()
Counter = Counter + 1
if Counter => 14 then
;------[Sort a list of 15 readings]---By Melanie-----------------------
SortArray:
Counter = 0
SortLoop:
If RawData(Counter + 1) < RawData(Counter) then
DataA = RawData(Counter)
RawData(Counter) = RawData(Counter + 1)
RawData(Counter + 1) = DataA
If Counter > 0 then Counter = Counter - 2
ENDIF
Counter = Counter + 1
If Counter < 15 then goto SortLoop
;===============================================================
Upd = 1 ; Set flag to read sample
SampleValue = RawData(7)/100 ; Select the middle guy
For Counter = 0 to 14 ; -------------------------------
RawData(Counter) = 0 ; I probably don't need this part
Next ; -------------------------------
Counter = 0 ; Reset counter
ELSE
T1CON.0 = 1 ; Start timer1
ENDIF
@ INT_DISABLE INT_INT ; Do not take another reading on RB0 untill
; the next burst is sent
@ INT_RETURN
'---[TMR1 - interrupt handler]------TMR1 Overflow, send burst
SignalTimeOut:
HPWM 1,127,40000 ; Send burst DC 50%, 40KHz
PAUSEUS 200 ; length of burst.
CCP1CON = 0 ; Stop sending HPWM
PAUSEUS 500 ; Wait until Tx vibrations stops
T1CON.0 = 0 ; Stop timer1
TMR1H = $B1:TMR1L = $E7 ; adjust timer1 to 50Hz @ 4MHz Prescale = 1
@ INT_ENABLE INT_INT ; enable RB0 interrupt
T1CON.0 = 1 ; Start timer1
@ INT_RETURN
end
Bookmarks