Won't go back to SLEEP after 1st Interrupt


Closed Thread
Results 1 to 33 of 33

Hybrid View

  1. #1
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378

    Thumbs down Won't go back to SLEEP after 1st Interrupt

    Usin PIC16F690 in PICkit2 LPDM board with PBASICPro. My below listed code places the MCU into SLEEP mode after powerup as intended. I confirmed this by connecting an ampmeter and it reads only 400 uamps on powerup after executing the sequence at the Main label thru the @SLEEP statement. However, after the 1st interrupt is received and it is awakened, it doesn't go back into deep SLEEP after the Int_handler is completed. I can see this as confirmed by the ampmeter reading of 2.2 mAmps after the interrupt. The way my code is structured, once the Int_handler is serviced and it resumes back to the Main label, it should go back into deep SLEEP and only be consuming 400 uamps again.
    Can anyone see why it isn't going back into SLEEP mode after the interrupt as intended?
    ---------------
    Code:
    ' -----[ Device Declaration ]----------------------------------------------
    '
    @ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _MCLRE_OFF & _CP_OFF
    ' For PM assembler only use following instead
    '@device pic16F690, intrc_osc_noclkout, bod_off, pwrt_off, wdt_off, mclr_off,
    ' protect_off   
     
    ' -----[ Revision History ]------------------------------------------------
    ' Version 1.0.4 on 6/16/2009: Includes changes to minimize power during Sleep
    
    ' -----[ 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
    open_valve    VAR PORTC.2   ' Set RC2 as valve solenoid open command
    close_valve   VAR PORTC.3   ' Set RC3 as valve solenoid close command
    
    ' -----[ Declare Constants ]----------------------------------------
    '
     k             CON 10   ' Calibration factor for flow meter...# pulses per gal
     Vthr          CON 3    ' Assumes Low Battery Monitor threshold = 3 volts
     
    ' -----[ 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 pullups disabled, TMR0 clock source is RA2, 
                               ' high-to-low transitions, prescaler to TMR0
      TMR0 = 256 - k           ' preload TMR0 to overflow after k counts
      
    ' Initialization of inputs/outputs..commented out..duplicated in Int_handler
      open_Valve = 0    ' Initialize RC2 (open_valve) at Low value
      close_valve = 0   ' Intialize RC3 (close_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)
    IOCA = %00001000             ' Enable RA3 as on-change-INT
    
    ' -----[ Main Code ]-------------------------------------------------------
    'Set INT Handler
    ON INTERRUPT GOTO Int_handler   
    
    'Start...normal code here
    MAIN:
        ' Perform following steps to save power during Sleep mode
        VRCON = %00100000   ' Set Voltage Reference for minimum power consumption
                            ' Disable CVref during Sleep to save power
        ANSEL= %11111011    ' Set PortA to Analog I/O to save power during Sleep but
                            ' leave Bit2 as digital for RA2 pulse count interrupt.                    
        ANSELH= %11111111   ' Analog module enabled to save power during Sleep
        TRISB = %11111111   ' Set all PORTB pins to inputs during Sleep
        TRISC = %11111111   ' Set all PORTC pins to input during Sleep
        PortA = %11111111   ' Set TOCK1, MCLR and all PortA pins High before Sleep 
                            ' to save power
        @ sleep
        @ NOP
        ' 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
     
      DISABLE
    Int_handler:
     'Initialize registers for interrupt 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 = %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 for LEDs
        PORTA = %00000000   ' PortA pins all set to Low
        PORTC = %00000000   ' LEDs off, PULSOUT RC3 provides a high-going pulse 
       
      High bat_mon      ' For testing..simulate battery monitor input is Low or High
      DEFINE WRITE_INT 1
      'Write 13, bat_mon   ' Remove comments on Write statements 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
        PAUSE 3000        ' Light Low Battery LED for 3 secs as warning
      ENDIF                                            
      'Write 5, bat_mon           ' Remove comment for test only 
      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 for switch opening 
        Until flush = 1 
        PULSOUT open_valve,2000   ' Generate 20 msec pulse to RC3 to open valve
        HIGH led1            ' Light indicator that valve is open & water flowing
        Pause 1000   
        '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.
            'PULSOUT close_valve,2000 ' Generate 20 msec pulse to RC4 to close valve       
        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 close_valve,2000 ' Generate 20 msec pulse to RC4 to close valve  
        'WRITE 11, TMR0      ' Write TMR0 value..remove comment for test only
        dummy = TMR0         ' Clear mismatch condition
        TMR0_INT_FLAG = 0    ' clear overflow flag
        TMR0 = 256 - k       ' reload TMR0 to overflow after k counts
        '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

  2. #2
    Join Date
    Jan 2009
    Posts
    78


    Did you find this post helpful? Yes | No

    Default use DT_interrupts

    ...use DT_interrupts...

    ...for low power consumption why you didn`t use timer1+external_32.768khz_crystal instead of timer0...the pic will stay more in sleep (timer1=16bit)

  3. #3
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default Don't quite understand??

    Appreciate your inputs, but don't know what you mean by DT_Interrupts. Could you explain?
    I am using the TMR0 overflow interrupt to count pulses up to a maximum of 256 pulses. That is adequate for my application. Why would I want to change over to TMR1 interrupt for 16 bits if 8 bits is enough?
    I do understand your suggestion to reduce clock speed from my current use of internal clock at 4 MHz. However I don't want to add the costl of an external crystal and capacitors. Is there a way for me to reduce clock speed at the Main code just before SLEEP and then reset clock to 4 MHz when it enters interrupt?? My understanding from the data sheet is that the clock speed has to be part of the @ config statement that is read by the compiler and can't be changed during runtime.
    Any suggestions from anyone on how to modify this code just before the @ SLEEP statment to reduce power would be appreciated. The current 400 uamps seems excessive for SLEEP mode....most posts indicate SLEEP mode for nanoWatt MCU like 16F690 should be more like a few uamps...not hundreds of uamps. >>>>

  4. #4
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default Back to the real problem

    I forgot to mention in my last post that the real problem I am looking for advice on is why my code doesn't put the MCU back into SLEEP mode after servicing the interrupts. Can anyone advise me? It is in SLEEP mode on power up, but after servicing the 1st interrupt will never go back into SLEEP mode as indicated by 400 uamps consumption.

  5. #5
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    967


    Did you find this post helpful? Yes | No

    Default

    How about clearing the interrupt flags before you 'Sleep' ? Also, I think you need to read RB3 to clear the flag.

  6. #6
    Join Date
    Mar 2009
    Location
    Colorado
    Posts
    378


    Did you find this post helpful? Yes | No

    Default I thought my code does clear interrupts???

    Jerson, thanks for your comments. However, your comments confuse me slightly: 1) I thought my code does clear the mismatch condition for both types of interrupts at the end of each IF-THEN block for each interrupt before RESUME where i read the Ports (dummy = flush or dummy = TMR0);
    2) I also thought my code does clear the intterupt flags for both types( FLUSH_INT_FLAG = 0 and TMR0_INT_FLAG = 0).
    Your comment about reading RB3 also confuses me since I am not using the RB3 as an intterupt.
    Can you please take another look at my interrupt service routine and clarify whether these coded statements are actually clearing the interrupts? Thanks!

Similar Threads

  1. Pin won't stay high during Repeat...Until loop??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 16th August 2009, 23:57
  2. Battery powered applications
    By NavMicroSystems in forum Off Topic
    Replies: 7
    Last Post: - 22nd June 2009, 07:12
  3. Can't ID interrupt source with this IntHandler??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 3rd June 2009, 02:35
  4. Using Sleep
    By elec_mech in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 17th August 2008, 04:05
  5. USART interrupt not interrupting right
    By Morpheus in forum mel PIC BASIC Pro
    Replies: 12
    Last Post: - 6th March 2005, 01:07

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts