Thanks, Joe. Am going to study the instant interrupts to see how to use them.
I did finally get the OnInterrupt version working so that the Int_handler would determine which type of interrupt occurred and service them accordingly. Only thing I haven't yet got working is the SLEEP mode, even after turning WDT on as you pointed out. Intention is to put the MCU into SLEEP mode for 45 secs on power up while waiting for the first interrupt from the Flush switch. However, when I do this, the Flush switch interrupt works, but the RA3 OnChange interrupt doesn't work. Can't figure out why. If I use a PAUSE 1 statement instead of SLEEP 45 everything works correctly. Any ideas on how to solve this?
I am posting all of my current code below in case anyone wants to see how the overall interrupt structure does work for use with both types of interrupts.
------------------
Code:
*
' -----[ Program Description ]---------------------------------------------*
' This Program is for a PIC16F690 installed in a PICkit2 Starter Kit *
' Purpose: *
' 1) Monitor an input for an external Interrupt from flush *
' 2) On Interrupt, command latching solenoid to open valve *
' 3) Measure flow meter output to determine when 1.6 *
' gallons have passed *
' 4) On 1.6 gallons, command latching solenoid to close *
' 5) Put Microcontroller back in Sleep State to await next *
' Flush Interrupt *
' *
' This Program uses the PIC16F690 and simulates control of a solenoid operated
' water valve and measures the volume of water flowing through a flow meter.
' A normally open, momentary push button switch is installed on the PICkit2
' LPDM board between pin RA2 and ground to simulate the flow meter pulse input.
' This program places the MCU in sleep mode most of the time until it receives
' an interrupt from the activation of the flush handle that closes a
' contact limit switch that grounds an input pin of the microcontroller as an
' interrupt. I/O pin connections to the PIC16F690 MCU are as follows:
'
' RA0...is connected as ICSPDAT when used for ICSP and also to a low battery
' monitor R/C circuit for normal ops.
' RA1...is connected as ICSPCLK when used for ICSP.
' RA2...is connected to the external Flush contact limit switch as TMR0 input.
' During testing it is connected to a momentary switch on the PICkit2
' board as a clock input for TMR0 counting of pulses as interrupt.
' RA3...During testing it is connected to a momentary switch on the PICkit2
' board as a manually simulated On_interrupt from the FLUSH switch.
' RA4...is connected to pin 6 of the ICSP header for use during programming.
' RC0...is connected as an output to an LED and is on when the valve
' is open.
' RC1...is connected as an output to an LED and is flashed when battery is low
' RC3...is connected as an output to the latching solenoid that opens or
' closes the valve. During program testing with the PICkit2 demo
' board it is connected to an LED to show when the pulse is sent.
' RC4...is connected to pin PDN on the TRM-XXX-LT transceiver.
' RC5...is connected to pin DATA on the TRM-XXX-LT transceiver.
' RC6...is connected to pin RSSI on the TRM-XXX-LT transceiver.
' RB4...is connected via a 10 ohm resistor to provide power to Wireless option.
' RB5...is connected to Hall Effect sensor circuit #2.
' RB6...is connected to Hall Effect sensor circuit #1.
' RB7...is connected to pin R/T SEL on the TRM-XXX-LT transceiver.
' the PICkit2 board momentary switch to simulate Meter pulse inputs.
' -----[ Device Declaration ]----------------------------------------------
'
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
'@device pic16F690, intrc_osc_noclkout, bod_off, pwrt_off, wdt_off, mclr_off,
' protect_off ' For PM assembler only
' -----[ Revision History ]------------------------------------------------
'
' -----[ Declare Variables & Aliases ]-----------------------------
'
diff VAR Byte ' Difference between bat_mon and Vthr
dummy VAR Byte ' For read of on-interrupt port & clear mismatch condition
flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int
i VAR Byte ' Index used in Gallon counter loop
led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing
led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery
bat_mon VAR PortA.0 ' Set RA0 as battery low power monitor
meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt
valve VAR PORTC.3 ' Set RC3 as valve solenoid open/close command
' -----[ Declare Constants ]----------------------------------------
'
k CON 10 ' Calibration factor for flow meter...# pulses per gal
Vthr CON 3 ' Aasumes Low Battery Monitor threshold = 3 volts
' -----[ Initialization ]--------------------------------------------------
' 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 pullups disabled, TMR0 clock source is RA2,
' high-to-low transitions, prescaler to TMR0
TMR0 = 256 - k ' preload TMR0 to overflow after k counts
'A/D & Comparators disabled
ANSEL=0 ' Set PortA to digital I/O
ANSELH=0 ' Analog module disabled
CM1CON0=0
CM2CON0=0
'Port Settings
Init:
PORTA = 0 ' PortA pins all set to Low
PORTC = 0 ' LEDs off, PULSOUT RC3 provides a high-going pulse
TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used
TRISB = %00000000 ' Set all PORTB pins to outputs
TRISC = %11110000 ' Set lower 4 pins of PartB as outputs
PORTC = %00000000 ' Pre-set PORTC pins low, turning LEDs off
' Initialization of inputs/outputs
Valve = 0 ' Initialize RC3 (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
meter = 1 ' Initialize RA2 (meter) at High for METER pulse inputs
' RA2 = TMR0 clock input for simulated meter pulse inputs
flush = 1 ' Initialize RA3 (flush) at High value for flush interrupt
'Interrupts Settings
FLUSH_INT_FLAG VAR INTCON.0 ' RA3 (FLUSH) On-change-interrupt flag bit
TMR0_INT_FLAG VAR INTCON.2 ' Timer0 overflow flag bit
INTCON = %10101000 ' Enable global, TMR0 & RABIE (RA3 on-change-INT)
'INTCON = %10100000 ' enable global & Timer0 interrupt only
IOCA = %00001000 ' Enable RA3 as on-change-INT
' -----[ Main Code ]-------------------------------------------------------
'Set INT Handler
ON INTERRUPT GOTO Int_handler
'Start...normal code here
MAIN:
Pause 1 ' Works when SLEEP statement doesn't work!!
'SLEEP 45 ' Put MC in Sleep state at power up for 45 secs..doesn't work!!
Low led2
' Microcontroller is in Sleep State waiting for external FLUSH Interrupt
' Valve should be closed at this point and no water flowing
' Put code here to test if flow meter has stopped as an indication that
' no water is flowing...is a double check on valve closure.
GOTO Main ' Loop to Main to wait for next Flush interrupt on RA3 change
DISABLE
Int_handler:
High bat_mon ' Simulate battery monitor input is Low
DEFINE WRITE_INT 1
'Write 5, bat_mon ' Remove comment for test only
IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change
PULSOUT valve,1000 ' Generate required 10 msec pulse to RC3 to open valve
HIGH led1 ' Light indicator that valve is open & water flowing
'Write 7, flush ' Write RA3 (FLUSH) value during testing
' 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.
'Goto Shutvalve
REPEAT
' Wait until the external Flush interrupt is at high level...limits
' interrupt to switch closure only and not for switch open
Until flush = 1
dummy = flush ' Clear mismatch condition
FLUSH_INT_FLAG = 0 ' Clear interrupt flag & enable
'INTCON = %10001000 ' global & RABIE (RA3 on-change-INT)
' ..preclude TMRO overflow interrupt..test only
Endif
IF TMR0_INT_FLAG = 1 Then ' Interrupt was a TMR0 overflow..volume reached
PULSOUT valve,2000 ' Generate required 20 msec pulse to RC3..close valve
'WRITE 11, TMR0 ' Write TMR0 value..remove comment for test only
'Write 13, bat_mon ' Remove comment for test only
'Write 15, Vthr
diff = Vthr - bat_mon
'Write 17, diff
If diff > 2 Then 'Battery is low
'Light the low battery monitor light
HIGH led2
ENDIF
dummy = TMR0 ' Clear mismatch condition
TMR0_INT_FLAG = 0 ' clear overflow flag
TMR0 = 256 - k ' reload TMR0 to overflow after k counts
LOW led1 'Turn off LED indicators
'INTCON = %10100000 ' global & TMR0 interrupts..preclude RA3 interrupt..
' test only
ENDIF
RESUME
ENABLE
' If the user program ends by getting to the last statement of the program
' at an END instruction, the MCU will SLEEP and await a wakeup.
END
Bookmarks