SLEEP Command and Interupts 16F648A


Closed Thread
Results 1 to 9 of 9
  1. #1
    ghoot's Avatar
    ghoot Guest

    Default SLEEP Command and Interupts 16F648A

    Here's another issue i've been running into. I'm using the PortB.0 interrupt in my program to wake up from sleep. Outside of the interrupt handler, I'm using the sleep command as seen below and disabling the 0 interrupt to force it to sleep a certain amount of time (TimeDely). If "timedely" is 300, I would expect it to sleep for 5 minutes, but its more like 1 and a half minutes. Could it be that some other interrupt is waking it up from sleep? This is using the internal ossilator also.
    ghoot

    GIE=0 'turn off global interupts.
    While GIE=1:GIE=0:Wend ' make sure they are off
    Input PORTB.0 ' Set PortB.0 as an Input
    RBPU=0 ' Enable PortB Pullup Resistors
    INTEDG=0 ' Trigger on the falling edge of RB0
    NTF=0 ' Clear the RB0/INT interrupt flag
    RBIF=0 ' Clear the PORTB[4..7] interrupt flag
    INTE=1 ' Enable RB0/INT interrupt
    RBIE=1 ' Enable PortB[4..7] interrupt
    ON INTERRUPT GoTo myint
    '+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++
    lowpower:
    INTE=0 ' Disable RB0/INT interrupt
    Sleep TimeDely
    INTEDG=0
    INTF=0 ' Clear the RB0/INT interrupt flag
    INTE=1 ' Enable RB0/INT interrupt
    Sleep 7200 - TimeDely
    'DO SOME OTHER STUFF HERE
    GoTo lowpower
    '+++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++
    Disable
    myint:..............

  2. #2
    Join Date
    May 2004
    Location
    New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Hi ghoot,
    I'm just a beginner with PBP (lots of fun! :-), so keep that in mind ....

    Noticed that the B4-7 interrupt is left enabled during the "lowpower" section. Could a B4-7 pin state change be causing the early wakeup?

    Might also try using the "disable" instruction before the "lowpower" section instead of turning your interrupt enable bits on and off. Then just clear the flag[s] as needed before re-enabling interrupts.

    Something like this...
    ON INTERRUPT GoTo myint
    ;
    ;Some code here
    ;
    Disable ; Turn PBP interrupt checking Off.
    lowpower:
    Sleep TimeDely
    INTF=0 ; Clear the RB0/INT interrupt flag (what about the B4-7 flag??).
    Enable ; Turn PBP Interrupt checking back on.
    Sleep 7200 - TimeDely
    'DO SOME OTHER STUFF HERE
    GoTo lowpower


    Should save a bit of code space, as PBP will not insert the statements that check to see if an interrupt occured (inserted before every command when "OnInterrupt" is enabled).

    Archilochus

  3. #3
    ghoot's Avatar
    ghoot Guest


    Did you find this post helpful? Yes | No

    Default

    Hi Arch,
    On this one, I'm wanting to allow an interrupt from switches on B6 or B7, during the "Sleep TimeDely" line and not from B0 (or anywhere else). I think it may be one of those "anywhere elses" that's getting me. I like what you're saying about saving code space with the Dissable command...hadn't thought about that. I've been looking at the data sheet for this, some of it makes sense and some of it don't. :-) After looking at the data sheet on page 110, I'm really confused.

  4. #4
    Join Date
    May 2004
    Location
    New England
    Posts
    164


    Did you find this post helpful? Yes | No

    Default

    Hi ghoot,
    Ohh... to allow the B4-7 interrupt, guess you couldn't use the 'disable' there.

    Where is the value for "TimeDely" coming from? Could it be getting mis-read (from EEPROM??) or something - causing the shorter than expected sleep time?

    Which part # are you using??

    "Disable" is a PBP 'compile time' (for lack of a better term) instruction. It just tells PBP not to insert the bits of code that check for interrupts. The info on it wouldn't be in the PIC's data sheet.

    >>>>>>>
    Archilochus

  5. #5
    ghoot's Avatar
    ghoot Guest


    Did you find this post helpful? Yes | No

    Default

    Hello Arch,
    I'm using the 16F48A. We're moving right now, so I haven't had a chance to get back on this for a few days. The part in the data sheet that is confusing is where it is talking about hoe it acts differently if the GIE bit is 1 or 0. I have it set to 0.

    Further down in the program, I'm setting "timedely" to a number, such as; 300 for a 5 minute delay. I'm thinking that the B4-7 flag may be getting changed somewhere. That would cause it to wake up wouldn't it?

    Thanks,
    ghoot

  6. #6
    ghoot's Avatar
    ghoot Guest


    Did you find this post helpful? Yes | No

    Default

    Well, this is very odd to me, but will probably end up being a no-brainer. I finally found out that a 2 minute delay works fine, but when I go 5 or more minutes, it goes flaky and may only delay for a few seconds. Since the 2 minute is a value of 120 (stored in "TimeDely") and the 5 minute is a value 0f 300, I tried changing it from a BYTE to a WORD and then the 5 minute delay worked! The longest delay that I need is an hour which will be 3600, but when I use that value I'm back to the same problem.

    Should't I be able to have a value over 32,000 in a BYTE without any problems?

  7. #7
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    Uhhh... a byte had eight bits last I looked... which gives 255 (256 if you include zero) combinations.

    Remember binary math...

    # Bits - Max Value

    1 - 1
    2 - 3
    3 - 7
    4 - 15
    5 - 31
    6 - 63
    7 - 127
    8 - 255
    9 - 511
    10 - 1023
    11 - 2047
    12 - 4095
    13 - 8191
    14 - 16383
    15 - 32767
    16 - 65535

    For counts of up to 32,767 you can see you need 15 bits...

    A word (16 bits) can hold a count from zero up to 65535.

    Melanie

  8. #8
    ghoot's Avatar
    ghoot Guest


    Did you find this post helpful? Yes | No

    Default

    Melanie,
    Thanks for correcting me on that. Since I have the var declared as a WORD now, I don't see why 3600 isn't working. One thing I'm doing that may be causing a problem is that I'm writing "TimeDely" to memory so that the value will be saved when the circuit is powered off.

    I notice on the WRITE command that you have to save the upper and lower portion of a WORD, and I didn't have that in the code, so that could be my problem. What I'm wondering is if that could cause the problem since I only READ that value when the circuit is powered up, after that, if the user changes the value in "TimeDely", the value is written, but not read from memory again, it's just read from the variable during normal use, unless power is turned on and off (which I'm not doing during the test).

  9. #9
    Join Date
    Jul 2003
    Posts
    2,358


    Did you find this post helpful? Yes | No

    Default

    The best thing to do is to post your offending code here (with some comments as to what you're trying to achieve within), so we can review it It's difficult to second-guess what's happening otherwise as my crystal ball is on the fritz...

    When saving to EEPROM, you must save the highbyte and lowbyte of the WORD individually into separate addresses. Then when reading back, you also have to read the highbyte and lowbyte back (again as two operations) to reassemble the word.

Members who have read this thread : 1

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