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

problem with sleep mode.

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



Joined: 03 Oct 2012
Posts: 242
Location: chennai

View user's profile Send private message

problem with sleep mode.
PostPosted: Mon Jan 27, 2014 9:55 pm     Reply with quote

Code:
#include <18F4620.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=6144000)

#define LED1 PIN_A0

// global flag to send processor into sleep mode
short sleep_mode;

// external interrupt when button pushed and released

#INT_EXT
void ext_isr() {
static short button_pressed=FALSE;

   if(!button_pressed)        // if button action and was not pressed
   {
      button_pressed=TRUE;    // the button is now down
      sleep_mode=TRUE;        // activate sleep
       ext_int_edge(L_TO_H);   // change so interrupts on release
   }
   else                       // if button action and was pressed
   {
      button_pressed=FALSE;   // the button is now up
      sleep_mode=FALSE;       // reset sleep flag
      ext_int_edge(H_TO_L);   // change so interrupts on press
   }
   if(!input(PIN_B0))         // keep button action sychronized wth button flag
      button_pressed=TRUE;
   delay_ms(100);             // debounce button
}

// main program that increments counter every second unless sleeping
void main()   {
   sleep_mode=FALSE;          // init sleep flag

     ext_int_edge(H_TO_L);      // init interrupt triggering for button press
    enable_interrupts(INT_EXT);// turn on interrupts
      enable_interrupts(GLOBAL);

   while(1)
   {
      if(sleep_mode)          // if sleep flag set
         sleep();             // make processor sleep

      output_high(LED1);      // LED ON
         delay_ms(500);         // every second
      output_low(LED1);
      delay_ms(500);
   }
}


measuring current using multimeter. Always shows 7.70mA when i button pressed or not. Why it is not going into sleep mode?
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Jan 28, 2014 2:00 am     Reply with quote

There are several things 'problematical' about this.

Buttons rarely give simple on/off edges. When pressed, you normally get several short make/break pulses over a few uSec. You need to design your hardware, to give clean make/break pulses to have any hope of the current approach working. Now you have a long delay in the interrupt (too long), but the problem is that flags will have been set on the first edge, even if this is not the actual edge the button ends up giving, and worse, this results in interrupts being disabled in the main code during the led on/off delays....

Step back.
Either design the hardware to give clean edges (hardware filtering on the buttons), or rethink, and have the button 'event', trigger an interrupt based delay, and _then_ re-sample. The code needs to only be triggering the sleep, once it _has_ verified that the button is cleanly made.

Then put a 'delay_cycles(1)' after the sleep. The instruction after the sleep is 'pre-fetched' when you go to sleep. ideally it should be a nop (which is what a single cycle delay generates).

Best Wishes
jgschmidt



Joined: 03 Dec 2008
Posts: 184
Location: Gresham, OR USA

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Jan 28, 2014 5:39 pm     Reply with quote

I'm assuming you are trying to achieve low power sleep. I've had some experience and good results with that and I have several suggestions:

1) To verify that you are truly sleeping, you might just try straight-line code that doesn't require a button press. Do a delay_ms(10000) after main() so you can get a steady reading and then call sleep().

2) You will probably see a reduction in current but less than the spec sheet claims, even if you don't have any other hardware connected. See some suggestions for that below.

3) For detecting button presses I generally use a polled I/O check in my main processing loop. For Inputs held high, I check for an input held low for several consecutive loops. Once that is detected I go and process that button.

4) Once you get your button working you'll need to do several things before calling sleep(). For systems like this I have two functions - HWSetup() to setup the environment for running and HWSleep() to arrange for minimal current sleeping. Depending on what else you have connected to your processor, you need to turn off UARTs, timers, voltage references and ADCs, set the I/O ports so current doesn't flow in or out of the processor, etc. Turn off power to peripherals via relays or pFETs. Set up your conditions for waking up, usually an interrupt and then call sleep().

For my power on/off applications that is followed by interrupt resets and a reset_cpu(), still within the HWSleep() function. The first call in main() is to HWSetup and my application is off and running. You can check to see if you started from a reset or a true cold start with restart_cause().

Microchip publishes some guidance for low power systems and there are posts here and on the Microchip forums related to sleep() which will help you achieve low current sleeping.
_________________
Jürgen
www.jgscraft.com
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