CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC10F206 doesn't wake up after sleep

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PIC10F206 doesn't wake up after sleep
PostPosted: Fri Mar 26, 2010 6:45 am     Reply with quote

Hello,

I have a 10F206 with a Push Button on B0.
A FET (BS170) at B1.
A servo at B2, and a pull-up (100k) at MCLR to VDD.

Let it do some stuff with a servo and put it to sleep.

Have some strange issues:
Sometime after programming it draws 250mA (turning it off and back on solves this....??). At that moment nothing is connected. No servo no switch. Only a pull-up at the MCLR pin.

What happens.... well when I introduced the sleep instruction.. nothing.
I program the chip and let it run it will NOT wake up when I change a pin.
When I remove the sleep instruction and the PinChangeFlag it will control the servo and the FET. It looks like it will not wake up.
Code included.
Code:

#include <10F206.h>

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES MCLR                     //Master Clear pin: enable
#FUSES NOPROTECT                  //No code protected from reads

#use delay(clock=4000000)

#byte STATUS = 0x003
#bit  GPWUF = STATUS.7

int1 PinChangeFlag;
int   i;

#define SWITCH    PIN_B0
#define FET      PIN_B1
#define SERVO   PIN_B2

main()
{
    PinChangeFlag = GPWUF;
    setup_comparator(NC_NC_NC_NC);

    while(1)
    {
   SET_TRIS_b(0x01);

         if(!PinChangeFlag)
      {
         output_high(FET); //servo enable
         for(i=0; i <40;i++)//linksom
          {
             output_high(SERVO);
             delay_us(500);
             output_low(SERVO);
             delay_ms(20);
          };
         for(i=0; i <40;i++)//rechtsom
          {
             output_high(SERVO);
            delay_us(2500);
             output_low(SERVO);
             delay_ms(20);
          }
      }
   output_low(FET); //servo disable
   sleep();
    }
}

Regards,
Jody
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 7:53 am     Reply with quote

Three separate things:
First, on these chips, 'wake up', triggers a restart of the program. You need to read 'restart_cause' at the start of your program, and according to what this returns, either perform a normal start, or go straight into your program. The resturned values for this function, are defined in the chip's include file. Test for 'PIN_CHANGE_FROM_SLEEP', to know when you have woken this way. You are trying to do this by directly reading the GPWUF bit, but technically, you are meant to test both bit 4, and bit 7. The compiler instruction does this for you.

Then, you should read the input bit you want to wait on, immediately before sleeping.

Finally, wake up on pin change, needs to be enabled.
setup_counters(T0_INTERNAL,PIN_CHANGE_FROM_SLEEP);

What you post would probably work, if this last is done, but in some circumstances could give anomalous results.

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 26, 2010 8:20 am     Reply with quote

Hello Ttelmah,
Thanks for you help....!

first thing: Yes I know that the wake up is a reset. And I want to test why we wakes up... But what do you mean by 'PIN_CHANGE_FROM_SLEEP' is it a compiler function?? I thought that I had to test the bit myself...

second: I now read all the bits but no change about waking up (keeps asleep)

third:setup_counters(T0_INTERNAL,PIN_CHANGE_FROM_SLEEP); is this also a compiler function?

Thanks so far,
Jody
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 26, 2010 8:36 am     Reply with quote

Oke, what I have so far:
Code:

#include <10F206.h>
#use fast_io(B)
#FUSES NOWDT                      //No Watch Dog Timer
#FUSES NOMCLR                     //Master Clear pin: enable
#FUSES NOPROTECT                  //No code protected from reads

#use delay(clock=4000000)

//#byte STATUS = 0x003
//#bit  GPWUF = STATUS.7

int1 PinChangeFlag, read_b0, read_b1, read_b2, read_b3;
int   i, RESTART;

#define SWITCH    PIN_B0
#define FET      PIN_B1
#define SERVO   PIN_B2
#define MCLR   PIN_B3

main()
{
   RESTART = RESTART_CAUSE();
//    PinChangeFlag = GPWUF;
   setup_counters(RTCC_INTERNAL,PIN_CHANGE_FROM_SLEEP);
    setup_comparator(NC_NC_NC_NC);

    while(1)
    {
   SET_TRIS_b(0x01);
         if(RESTART == 0x90)
      {
         output_high(FET); //servo enable
         for(i=0; i <40;i++)//linksom
          {
             output_high(SERVO);
             delay_us(500);
             output_low(SERVO);
             delay_ms(20);
          };
         for(i=0; i <40;i++)//rechtsom
          {
             output_high(SERVO);
            delay_us(2500);
             output_low(SERVO);
             delay_ms(20);
          }
      }
   output_low(FET); //servo disable
   read_b0 = input(PIN_B0);
   sleep();
    }
}


Is this the correct way??
It is not working at this moment but I am working on it.....
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 9:05 am     Reply with quote

The normal way to use the restart_casue, is like this:
Code:

void main(void) {
   int8 demo_value;
   int8 restart_val;
   restart_val=restart_cause(); //You must move the value into a
   //variable, since on some processors, the flags are reset by the
   //function.

   if (restart_val==PIN_CHANGE_FROM_SLEEP) {
       //Do your 'I have woken' code here
       demo_value++;
       if (demo_value==10) {
          //do a demo to show we have woken up ten times

       }

   }
   else {
       //Here the 'reset for other reasons' code - normally you would
       //do things like initialise variables etc.
       demo_val=0;

   }
   sleep();
}


Key point is that a variable is only 'initialised', when declared, if it is given a value. If not, the compiler leaves it unchanged. So here, I test the restart_cause value, and if it is a 'PIN_CHANGE_FROM_SLEEP', don't initialise the demo_value variable. However in all other cases (watchog, MCLR, power_up etc.), I initialise the value. Then after ten 'wake-ups', I can do something.
This is just to show the 'idea', but gives the basis of how to treat a normal, and a 'sleep' wake-up' differently.
A lot of things don't have to be done when you wake. For instance, TRIS remains set as it was. The comparator remains setup, the wake up ability itself remains enabled. They won't do any harm in your code, but waste time, and in some circumstances might matter.
Also use the defined names, not numbers. Somebody looking at the code later (yourself included), is going to have to work out what '0x90' means, whereas 'PIN_CHANGE_FROM_SLEEP', is largely self documenting....

Best Wishes
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Fri Mar 26, 2010 9:25 am     Reply with quote

mmmh something like this???:
Code:

#include <10F206.h>

#FUSES NOWDT                      //No Watch Dog Timer
#FUSES NOMCLR                     //Master Clear pin: enable
#FUSES NOPROTECT                  //No code protected from reads

#use delay(clock=4000000)

#define SWITCH    PIN_B0
#define FET      PIN_B1
#define SERVO   PIN_B2
#define MCLR   PIN_B3

main()
{
   int1 read_b0;
   int   i, RESTART;

   RESTART = RESTART_CAUSE();

   setup_counters(RTCC_INTERNAL ,PIN_CHANGE_FROM_SLEEP);
    setup_comparator(NC_NC_NC_NC);
   SET_TRIS_b(0x01);
   
    while(1)
    {
         if(RESTART == PIN_CHANGE_FROM_SLEEP)
      {
         output_high(FET); //servo enable
         for(i=0; i <40;i++)//linksom
          {
             output_high(SERVO);
             delay_us(500);
             output_low(SERVO);
             delay_ms(20);
          };
         for(i=0; i <40;i++)//rechtsom
          {
             output_high(SERVO);
            delay_us(2500);
             output_low(SERVO);
             delay_ms(20);
          }
      }
   output_low(FET); //servo disable
   output_low(SERVO);
   read_b0 = input(PIN_B0);
   sleep();
    }
}


but still it is not working...... pulling mine hairs out.............
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Mar 26, 2010 5:45 pm     Reply with quote

The test program shown below works. If I press a switch which connects
pin B0 to ground, the PIC wakes up from sleep and flashes an LED.
Then it goes back to sleep. Internal pull-ups are enabled, so there is
no external pull-up on the switch. This was tested with PCB vs. 4.073
which comes with MPLAB for free. The code was tested in hardware.

If it doesn't work, make sure that you disconnect your ICD2 from the
board before you do the test. That's necessary. Also make sure that
you haven't accidently clobbered the Calibration Memory value at the
end of the PIC's ROM address. If you're using MPLAB, it will warn you
if this happened, and you can re-program the value back again. Also
be aware that when this PIC wakes up from Sleep, it does a reset.
It doesn't start running from where it went to sleep. It resets.
Code:

#include <10F206.h>
#fuses NOMCLR
#use delay(clock=4000000)

#define SWITCH  PIN_B0
#define LED     PIN_B2

#define set_options(value)   {#ASM         \
                              MOVLW  value \
                              OPTION       \
                              #ENDASM}

//================================
void main()
{
setup_comparator(NC_NC);

// Enable pull-ups, wake-up on change, and Pin B2 for normal i/o.
set_options(0x1F);

output_high(LED);  // Flash an LED
delay_ms(500);
output_low(LED);
   
sleep();         
   
while(1);   
}
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Sat Mar 27, 2010 7:18 am     Reply with quote

THANK!!!

As soon I get back into the office I will test it..

Keep you informed!!!
Jody



Joined: 08 Sep 2006
Posts: 182

View user's profile Send private message Send e-mail

PostPosted: Mon Mar 29, 2010 6:14 am     Reply with quote

Great it works....

During sleep the uC draws abour 2mA..... is it possible to reduce this??

Regards,
Jody
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Mar 29, 2010 8:25 am     Reply with quote

It depends on a lot of things.
First, and pin that is 'driving' something, will result in the chip drawing what it needs to drive this target. So you must turn all output pins to the state where they are drawing the least power.
Second, you need to be careful, to not to leave input pins 'floating'. They need to be either resistor biased to the supply rails, connected to something else that does this, or switched to being outputs, if this can be safely done.
Third, how is your power being generated?. Regulator IC?. If so, what does _this_ draw. Many draw several mA, even with no output load. You need to be looking at ultra low quiescent consumption regulators. However you then have a 'caveat', that many of these are more prone to oscillation than the traditional designs, meaning great care must be taken with the layout round these.
Then you need to turn off any peripherals in the PIC, that are still left running. Many go 'off' automatically, but some parts like the ADC, if running off it's own RC clock, still run, and will draw power. In your case, are you using the watchdog when asleep?. If not, then this needs to be switched off. Same applies to the comparator.
You should be able to get consumption of a very few uA.
Look at table 12.1.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group