Code:
' -----[ Device Declaration ]----------------------------------------------
@ __config _INTRC_OSC_NOCLKOUT & _BOR_OFF & _FCMEN_OFF & _WDT_OFF & _MCLRE_OFF & _CP_OFF
' -----------------[ Declare Variables & Aliases ]
ADINPUT VAR WORD ' Stores VP6 value as sampled by the A/D
b0 VAr vdd.byte1 ' LSB of VDD when right justified
b1 var VDD.Byte0 ' MSB of VDD when right justified
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
ext_pwr VAR PORTC.3 ' Set RC3 to control RL2 as RL1 power control source
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
LED_Grn VAR PORTC.0 ' Set RC0 (Green LED) for valve open..water flowing
LED_Red VAR PORTC.1 ' Set RC1 (Red LED) for solenoid cmnd or low battery
meter VAR PORTA.2 ' Set RA2 as input for HS1 meter pulse Interrupt
sol_valve VAR PORTC.2 ' Set RC2 as valve solenoid open/close command
Vdd VAR WORD ' Stores Vdd value as converted from ADINPUT
Vthr CON 32 ' Set threshold (3.2v) to trigger low voltage warning
' -----[ Declare Constants ]
k CON 10 ' Calibration factor for flow meter...# pulses per gal
' -----[ Initialization ]
Init:
' Setup Timer0 as an 8-bit counter with the clock input on RA2.
' 1:1 TMR0 prescaler
' TMR0 counts on high-to-low transitions
OPTION_REG = %00111000 ' PORTA/B pullups enabled, Interrupt on falling
' edge of RA2/INT, TMR0 clock source is RA2,
' increment on high-to-low transitions, prescaler to
' TMR0, TMR0 Rate 1:2
TMR0 = 256 - k ' preload TMR0 to overflow after k counts
' Initialization of inputs/outputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
ext_pwr = 0 ' Intialize RC3 at low value to turn off external power
sol_valve = 0 ' Initialize RC2 (sol_valve) at Low value
TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0
TRISA.3 = 1 ' Set RA3 as input port for sensing Flush switch closure
' Interrupts Settings
TMR0_Enable VAR INTCON.5 ' Alias for On_Off switch of TMR0 counter
FLUSH_INT_FLAG VAR INTCON.0 ' Alias RA3(FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Alias Timer0 overflow flag bit
' Set INT Handler
ON INTERRUPT GOTO Int_handler
'-----[ Main Code Starts Here ]
MAIN:
' Perform following steps to save power during Sleep mode
ext_pwr = 0 ' Turn off external power after interrupt is over
OPTION_REG.7 = 1 ' Disable PortA/PortB pull-ups
OSCCON = %0100011 ' Switch to 1 MHz internal oscillator
VRCON = %00100000 ' Set Voltage Reference for minimum power consumption
' Disable CVref
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 pulse count
' TMR0 overflow interrupt & RA3 On-Change intterupt.
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
CM1CON0.7 = 0 ' Turn off comparators during Sleep
CM2CON0.7 = 0
PCON.4 = 0 ' Turn off BOR during Sleep
WDTCON = %00010110 ' Turn WDT off to SLEEP indefinitely
TRISA = %00001101 ' Set RA0, RA2 & RA3 as inputs
TRISB = %11111111 ' Set all PORTB pins to inputs during Sleep
TRISC = %11111111 ' Set all PORTC pins to input during Sleep
PortA = %11111111 ' Write Port A all High to clear mismatch and save
' power during SLEEP
PortB = %11111111 ' Set all Port B and C pins High to save power
PortC = %11111111 ' in Sleep mode
' Interrupt Settings
INTCON = %10001000 ' Enable interrupts: GIE & RABIE but TMR0 disabled
IOCA = %00001000 ' before SLEEP. Enable RA3 as RABIE on-change-INT
@ sleep
@ NOP ' @ NOP statement here makes no difference
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change
'------{ Begin Interrupt Handler }
DISABLE ' Disable interrupts during interrupt handler
Int_handler:
'Initialize registers upon Interrupt wakeup from Sleep
OPTION_REG.7 = 0 ' Enable PortA/PortB Pullups
WDTCON = %0001000 ' Turn WDT on for ops
' A/D & Comparators disabled
ANSEL=0 ' Set PortA to digital I/O for use with RA2 and RA3
ANSELH=0 ' Analog module disabled
CM1CON0=0 ' Disable comparators
CM2CON0=0
' Port Settings
'TRISA = %00001000 ' Per JoeS to save power
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
TRISB = %00000000 ' Set all PORTB pins to outputs
'TRISC = %00000000
TRISC = %11110000 ' Set lower 4 pins of PortC as outputs for LEDs
PORTA = %00000000 ' PortA pins all set to Low
PORTC = %00000000 ' LEDs off, PULSOUT RC3 provides a high-going pulse
HIGH ext_pwr ' Turn on power to RL1 and to external power during
' the Interrupt Service Routine
DEFINE WRITE_INT 1
IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change
REPEAT
' Wait until the external Flush interrupt is at high level...limits
' interrupt to switch closure only and not also for switch opening
Until flush = 1
PULSOUT sol_valve,2000*10 ' Generate 100 msec RC2 pulse to RL1 to
' open valve
'Write 7, flush ' Write FLUSH value..remove comment for test only
' Put code here to start a timer to run for 50 secs as a fail safe
' to prevent overflow of toilet tank in case of sensor failure.
'PULSOUT relay_off,2000 ' Generate 20 msec
' pulse to RL2 to turn off power to RL1
Endif
TMR0_Enable = 1 ' Enable the TMR0 pulse counter for overflow interrupt
' Valve is open and water is flowing
REPEAT ' Execute this loop while waiting for flow to reach 1.6 gallons.
' Set registers for using A/D converter
' Set ADCON registers for A/D converter
ADCON0 = %10110101
' ADCON0.7 = ADFM = 1 ' 10-bit result is right justified
' ADCON0.6 = VCFG = 0 ' Set VREF+ to Vdd
' CHS<3:0> = 1101 ' Select 0.6V Ref channel
ADCON1 = %00110000 ' Select FRC as A/D conversion clock source
' Set FOSC=1MHz to stay inside recommended TAD range when not in SLEEP mode
OSCCON = %01000001
' Set ANSEL register to make RA1 analog input
ANSEL= %11110011 ' Set PortA to Analog I/O to save power during Sleep but
' leave Bits 2 & 3 as digital for RA2 and RA3 interrupts
ANSELH= %11111111 ' Analog module enabled to save power during Sleep
DEFine ADC_BITS 10
' Flash Green flow light while water flowing until pulse counter overflows.
LED_Grn = 1
Pause 125
LED_Grn = 0
Pause 500
' If Battery is low..flash low battery monitor light while water flowing
VRCON.4 = 1 ' Turn 0.6V reference ON
PAUSEUS 100 ' Allow VP6 to settle
ADCIN 13,ADINPUT ' Get VP6 analog reading (10-bit)
VRCON.4 = 0 ' Turn 0.6V reference OFF
WRITE 11,ADINPUT
'A/D scale for 0.6 volts is 0.6 * 1024 Full Scale = 6138
VDD = 6138/ADINPUT ' convert input reading to Vdd voltage
' Vdd now holds the measured Vdd voltage * 10 (i.e., 3.4V = 34)
' The formula is the same for any Vdd voltage. Assume normal
' Vdd = +3.95vdc direct from fully charged battery pack input.
WRITE 13,b0 ' Remove comments on Write statements for test only
WRITE 14,b1
Write 17,Vthr
IF Vdd <= Vthr THEN ' If Vdd less than or equal to 3.2v flash the
LED_Red =1 ' Blink RED LED for warning to replace batteries.
PAUSE 125
LED_Red = 0
Pause 500
EndIF
Until TMR0_INT_FLAG = 1 ' Loop ends w/ flow meter pulse counter overflows
PULSOUT sol_valve,2000*10' Generate 100 msec pulse to RC2 & Blink LED_Red
LED_Red = 1 ' Blink RED LED one time to indicate close command
PAUSE 125
LED_Red = 0
Pause 500
'WRITE 19, TMR0_INT_FLAG ' Write TMR0 value..remove comment for test only
dummy = flush ' Clear mismatch condition
FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable RA3 on interrupt
TMR0_INT_FLAG = 0 ' Clear overflow flag
TMR0 = 256 - k ' Reload TMR0 to overflow after k counts
RESUME ' Resume Main Program
ENABLE
'-------{ End of Interrupt Handler }
END
Bookmarks