PDA

View Full Version : SLEEP Command and Interupts 16F648A



ghoot
- 5th May 2004, 16:52
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:..............

Archilochus
- 8th May 2004, 16:11
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

ghoot
- 12th May 2004, 00:13
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.

Archilochus
- 16th May 2004, 18:14
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

ghoot
- 17th May 2004, 14:56
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

ghoot
- 28th May 2004, 15:45
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?

Melanie
- 28th May 2004, 17:30
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

ghoot
- 28th May 2004, 17:51
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).

Melanie
- 28th May 2004, 18:35
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.