View previous topic :: View next topic |
Author |
Message |
Static
Joined: 03 Apr 2007 Posts: 8
|
CPU reset after wake from sleep |
Posted: Tue Apr 03, 2007 3:00 pm |
|
|
I'm using a 10F200 and attempting to use the sleep and wake on change. However, everytime the chip wakes up from a "wake-on-change" it does a reset and starts from the beginning of code instead of continuing the code after sleep. Any suggestions?
In the following code the "IF" statements do not get executed after a wake on change:
Code: | //Sleep Test
//Compiled on IDE version 3.249
#include <10F200.h>
#fuses NOMCLR,NOPROTECT,NOWDT
#use delay(clock=4000000)
#define set_options(value) {#ASM \
MOVLW value \
OPTION \
#ENDASM}
#byte OSCCAL = 0x05 //define address of oscillator calibration
short B1,B3;
void main()
{
set_options(0b01010111); //enable wake on change and disable pullups
OSCCAL = 0x00; //set osccal - disable intosc output
set_tris_b(0b00001010); //set GPIO - B0,B2 outputs and B1,B3 inputs
output_low(PIN_B0); //set output
output_low(PIN_B2); //set output
while(1)
{
B1 = input(PIN_B1);
B3 = input(PIN_B3);
Sleep();
if(!input(PIN_B1)) //button input 1, goes low when pushed
{
output_high(PIN_B2);
delay_ms(1000);
output_low(PIN_B2);
}
if(!input(PIN_B3)) //button input 2, goes low when pushed
{
output_high(PIN_B0);
delay_ms(1000);
output_low(PIN_B0);
}
}
}
|
I appreciate any advice anyone can give. |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Tue Apr 03, 2007 3:08 pm |
|
|
It's supposed to do that.
Look on page 19 of the datasheet and there is a bit in the STATUS register, GPWUF you have to test it to see what kind of reset it was.
EDIT: That's funny I was going to say the same thing about it being a different than a typical PIC.
Point is read the data sheet over and over and over on this one...
Last edited by kevcon on Tue Apr 03, 2007 3:19 pm; edited 1 time in total |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Apr 03, 2007 3:11 pm |
|
|
I ran into a similar problem.....
From the data sheet:
Quote: | 9.9.2 WAKE-UP FROM SLEEP
The device can wake-up from Sleep through one of
the following events:
1. An external Reset input on GP3/MCLR/VPP pin,
when configured as MCLR.
2. A Watchdog Timer time-out Reset (if WDT was
enabled).
3. A change on input pin GP0, GP1 or GP3 when
wake-up on change is enabled.
4. A comparator output change has occurred when
wake-up on comparator change is enabled.
These events cause a device Reset. |
The 10F parts are a different animal.
John
EDIT: Beat me to it while cutting and pasting. That was going to be the next suggestion... code trickery to make a RESET appear more like a standard PIC wake up. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Tue Apr 03, 2007 3:17 pm |
|
|
I attempted to find the cause of reset using the reset_cause() using the following:
Code: | y=restart_cause();
for(x=0;x<8;++x)
{
output_bit(PIN_B0,shift_right(&y,1,0));
output_high(PIN_B2);
delay_ms(3000);
output_low(PIN_B2);
delay_ms(1000);
}
|
But, I only get the /PD and C bits of the STATUS register set. The GPWUF bit doesn't get set. Anybody know why the GPWUF bit won't set when there's a wake on change? |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Tue Apr 03, 2007 3:22 pm |
|
|
Are you using the simulator or running it on a chip?
I went round and round with microchip about the simulator not working correclty for this chip a while back, and I don't know if they ever fixed it. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Tue Apr 03, 2007 3:24 pm |
|
|
I'm running it on the chip not a simulator. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Tue Apr 03, 2007 3:40 pm |
|
|
I think I understand. Are you telling me that the code for checking the status has to be before the sleep?
Example:
Code: | while(1)
{
y=restart_cause();
GPWUF = bit_test(y,7);
if(GPWUF)
{
output_high(PIN_B0);
delay_ms(1000);
output_low(PIN_B0);
delay_ms(500);
}
B1 = input(PIN_B1);
B3 = input(PIN_B3);
Sleep();
}
|
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Apr 03, 2007 3:43 pm |
|
|
Put the sleep() after you read your inputs.... that should at least give you a working test...
Right now all it does is wake up and go back to sleep before the pins get read.....
John
EDIT: DOH! Beat me to it again.... Yes. Try that, but in your original test program. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Tue Apr 03, 2007 3:50 pm |
|
|
It works! Thanks for the help! |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Tue Apr 03, 2007 6:52 pm |
|
|
You might want to go through your code again, you have atleast one potential bug.
you are writing over the factory OSCCAL value. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Wed Apr 04, 2007 6:15 am |
|
|
Yes, I'm purposely writing over the OSCCAL to set bit 0 (FOSC4) to 0. Would it be better to use the #bit instead?
For example:
#bit FOSC4 = 0x05.0
...
FOSC4 = 0;
I'm unsure which one to use or if one way is better than the other. |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Wed Apr 04, 2007 6:40 am |
|
|
Yes a bit set would be better, that way you won't overwrite the factory OSCCAL value. |
|
|
Static
Joined: 03 Apr 2007 Posts: 8
|
|
Posted: Wed Apr 04, 2007 6:48 am |
|
|
Is there anyway to save variable data after sleep?
For example, having a variable (like a counter) that gets updated once every push of a button, and keep that variables value, even after sleep or reset.
My counter variable is initialized to 0 at the beginning of the code but sleep is resetting all variables. |
|
|
kevcon
Joined: 21 Feb 2007 Posts: 142 Location: Michigan, USA
|
|
Posted: Wed Apr 04, 2007 7:13 am |
|
|
This is just one of the many ways to do this but your should look somthing like this.
Kevin
Code: |
#include <10F200.h>
#case
#fuses NOMCLR
#fuses NOPROTECT
#fuses NOWDT
#use delay(clock=4000000)
void main( void )
{
unsigned int8 counter;
switch ( restart_cause( ) ) {
case NORMAL_POWER_UP :
counter = 0;
break;
case PIN_CHANGE_FROM_SLEEP :
counter++;
break;
}
}
|
|
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Apr 04, 2007 7:45 am |
|
|
No. Not the way you are waking the part.
Read 9.3 in the datasheet. |
|
|
|