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 support@ccsinfo.com

sleep and wakeup

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







sleep and wakeup
PostPosted: Wed May 18, 2005 11:29 am     Reply with quote

How to put 16C924 to sleep and how to wake him up ?
I know i must use sleep() but how to make him wake up?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 18, 2005 11:53 am     Reply with quote

Look at the CCS example file: EX_WAKUP.C

The file is in this folder: c:\Program Files\Picc\Examples
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

PostPosted: Wed Jun 22, 2005 12:09 pm     Reply with quote

I have looked at the EX_WAKUP.C, the Feb 2005 manual, and the FAQs.

According to MicroChip's datasheet on the 18F8720:
"...can wake-up the processor from Sleep if bit INTxIE was set prior to going into Sleep."

So how do I set the INTxIE bit with CCS? The manual, header file, and example make no mention of wake up from sleep. Is the INTxIE bit always set? If so, they should mention that in their docs. If not, what am I missing?

-Kyle
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Jun 22, 2005 12:59 pm     Reply with quote

The manual says "The user can wake from
Sleep through external Reset, Watchdog Timer Reset
or through an interrupt." Thus, I think you want to look into some sample code that triggers off of a external interrupt. The bit they talk about is set with enable_interrupts(INT_EXT); Or maybe IE is interrupt Enable set with the enable_interrupts(GLOBAL); Here is some code for 18F452
Code:
#INCLUDE <18F452.H>
#CASE
#USE DELAY(CLOCK=16000000)
#FUSES HS,NOWDT,NOPROTECT,NOLVP
#DEFINE VER_MAJOR 1
#DEFINE VER_MINOR 00
#USE RS232(BAUD=19200,XMIT=PIN_E0,INVERT,STREAM=DEBUG)
#ZERO_RAM
int8 debounce_count;
int8 keypad_debounce;
int8 lastkey;
#include "C:\ccs\Projects\ME_Lab\new_kpd.c"
#use fast_io (c)

int1 KEYPRESS;
//======================= MAIN ============================//
void main(void)
{
  int8 key;
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  fprintf(DEBUG,"\n\r");
  fprintf(DEBUG,"STARTING New Keypad Test.\n\r");
  fprintf(DEBUG,"FIRMWARE VERSION %u.%02u\n\r",VER_MAJOR,VER_MINOR);
  KEYPRESS=FALSE;
  kpd_init();
  enable_interrupts(INT_EXT);
  ext_int_edge(H_TO_L);
  enable_interrupts(GLOBAL);
  do
  {
    if(KEYPRESS)
    {
      key=kpd_getc();
      KEYPRESS=FALSE;
      fprintf(DEBUG,"%C ",key);
    }

  } while (TRUE);
}
//=======================RXisr============================//
#INT_EXT
void EXT_ISR(void)
{
KEYPRESS=TRUE;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 22, 2005 1:29 pm     Reply with quote

Quote:
I have looked at the EX_WAKUP.C, the Feb 2005 manual, and the FAQs.

According to MicroChip's datasheet on the 18F8720:
"...can wake-up the processor from Sleep if bit INTxIE was set prior to going into Sleep."


I feel like you left out quite a bit from the sentence in the data sheet,
or maybe you have an old version. In the data sheet I have, it says
this in Section 9.6:
Quote:

All external interrupts (INT0, INT1, INT2 and INT3)
can wake-up the processor from Sleep if bit INTxIE
was set prior to going into Sleep.


Then if you look in the 18F8720.H file, it lists the CCS parameters
that can be used to enable those interrupts with the enable_interrupts()
function:
Code:

#define INT_EXT                   0xF210
#define INT_EXT1                  0xF008
#define INT_EXT2                  0xF010
#define INT_EXT3                  0xF020


You will also need to make an interrupt service routine (function).
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

PostPosted: Wed Jun 22, 2005 2:01 pm     Reply with quote

Thanks for the quick reply, but I feel like you missed the whole point of my post. Perhaps I was not clear. Sad

I have made many ISRs with CCS.

When I posted my question, I was trying to find out if CCS sets INTxIE so the processor wakes up from sleep on external interrupts. CCS neither specifies which way they set the bit, nor do they offer a way to change it from whichever way they have chosen in the header file.

I have spent a few man hours experimenting and researching and at this point I see they set it (wake from sleep) on all external interrupts. I wish they had either:
1) Specified this in the documentation for simplicity
2) Allowed me to choose if I wanted to wake from sleep using a bit OR operation like they do with everything else (timers, ccp, rtc, spi, etc.) for consistency.

-Kyle
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 22, 2005 2:34 pm     Reply with quote

I think that you've got the idea that the CCS sleep() function
does something with interrupts. It doesn't. It just puts in
a single SLEEP instruction in ASM code. Anything that's done
with interrupts, such as enabling them, is done by you, with code.
Example:
Code:

enable_interrupts(INT_EXT1);

sleep();

#asm
nop
#endasm
Newbee
Guest







PostPosted: Thu Jun 23, 2005 12:45 am     Reply with quote

I have similar question regarding wdt and wakeup on button switch ( which is not on INT pin ) and no one want's to answer....
If it's so easy to do then show us ( to us who dont know as much as you )...

http://www.ccsinfo.com/forum/viewtopic.php?t=23324
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Thu Jun 23, 2005 1:05 am     Reply with quote

Newbee wrote:
I have similar question regarding wdt and wakeup on button switch ( which is not on INT pin ) and no one want's to answer....
If it's so easy to do then show us ( to us who dont know as much as you )...


Okay. Shocked

Here's an example program I gave to a class. It uses an external interrupt, not the RB interrupt (sorry), but I'm not changing it to use the RB interrupt just for you (I guess I'm not sorry.)

This was written for use with the Micro Engineering Labs Lab-X1 board. You can find it (and a schematic) at www.melabs.com

Have fun with it.

Code:
#include <18F452.h>
#device adc=8
#fuses WDT,WDT128, XT, NOPROTECT, NOOSCSEN, BROWNOUT, BORV20, PUT, STVREN, NODEBUG, NOLVP, NOWRT, NOWRTD, NOWRTB, NOWRTC, NOCPD, NOCPB, NOEBTR, NOEBTRB
#use delay(clock=4000000,RESTART_WDT)

#use fast_io(B) // set up port b

#include "i:\ELEN\LCD Task\lcd_driver.c"

int8 number_of_sleeps, wakeup_cause;
int16 total_time_asleep;

// the watchdog has been set up to timeout every 2.3 sec or so
// I want to put the pic to sleep for about 23 seconds, then wake up and do something

// a button press (external interrupt) will reset the total_time_asleep
// any of the buttons in the top row will trigger this interrupt

#int_EXT
EXT_isr() {
   total_time_asleep = 0;
   restart_wdt();
   lcd_putc("\fTotal time reset!");
}

void main() {
   wakeup_cause = restart_cause(); // see what woke us up right away, as the data may be corrupted if we wait
                           // also beware the "#zero_ram" directive
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_wdt(WDT_ON);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   enable_interrupts(INT_EXT); // external interrupt on pin B0
   ext_int_edge(0,H_TO_L); // falling edge causes interrupt
   set_tris_b(0x01); // all output except pin b0
   output_b(0x00); // all pins except b0 are low
   port_b_pullups(TRUE); // make pin b0 high
   // note that enabling the pullups will cause your current drain to be higher than you'd like
   enable_interrupts(GLOBAL);

   set_tris_e(0x00); // need this for the lcd

   switch (wakeup_cause) { // what woke us up?
      case NORMAL_POWER_UP: { // a plug-in from dead
         // the first time it powers up, set number_of_sleeps to 10
         number_of_sleeps = 10;
         total_time_asleep = 0;
         lcd_init();
         lcd_putc("\fReady for bed!"); // stupid powerup message for us to determine if it's working correctly or not
         break;
      }
      case WDT_TIMEOUT: { // watchdog woke us up
         // if the watchdog woke it up, go ahead and decrement number_of_sleeps
         if (--number_of_sleeps == 0) {
            number_of_sleeps = 10; // reset the count
            total_time_asleep = total_time_asleep + 23;
            // print the total time it's been asleep
            printf(lcd_putc,"\fBeen asleep for \n%lu:%02lu", total_time_asleep/60, total_time_asleep % 60);
         }
         break;
      }
   }
   sleep();
   delay_cycles(1); // the next instruction is prefetched - it may be a good idea
   // to insert a nop after the sleep
   while (TRUE){ // a way of ensuring that the pic doesn't get to the hidden sleep() at the end of main
   }
}
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

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

PostPosted: Thu Jun 23, 2005 1:32 am     Reply with quote

Newbee wrote:
I have similar question regarding wdt and wakeup on button switch ( which is not on INT pin ) and no one want's to answer....
If it's so easy to do then show us ( to us who dont know as much as you )...

http://www.ccsinfo.com/forum/viewtopic.php?t=23324


"Newbee" does not appear as the author of any thread section in the thread you pointed to therefore it is difficult to respond to this point. However, after having reread the entire thread all outstanding points were answered with the exception of the one from guest, guest who wanted to delay 10 hours then "hit" the wdt. If you are refering to this particular requirement then two things, you do not understand what a watchdog timer does, and the second you are asking for a specific implementation that has to be written for you.

The WDT is a free running timer that once runing will eventually reset the processor unless the WDT is cleared under program control. Clearing the WDT simply resets the count. The WDT timer will keep running and will eventually reset the CPU is not continually reset. Therefore you do not "hit" the wdt after 10 hours to cause a reset, instead you must "hit" it continuously to stop it reseting the CPU and, in your case, stop "hitting" it after 10 hours which will result in the WDT timing out and reseting the CPU. But why stuff around doing this on a 16F processor when you can achieve virtually the same effect by resetting the code and data pages to 0 and doing a goto 0?
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!


Last edited by asmallri on Thu Jun 23, 2005 7:18 am; edited 1 time in total
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

PostPosted: Thu Jun 23, 2005 7:11 am     Reply with quote

PCM programmer wrote:
I think that you've got the idea that the CCS sleep() function
does something with interrupts. It doesn't. It just puts in
a single SLEEP instruction in ASM code. Anything that's done
with interrupts, such as enabling them, is done by you, with code.


I am a senior programmer with long PIC experience (including ISRs) going back to the early 90s. This is the first project where I have had the experience of sleeping a processor that has ISRs on external pins. I was confused about it. MicroChips docs fueled the confusion, and CCS's docs don't do anything to clear the confusion. Looking at the numerous threads on the forum I believe I am not the only one to be confused about mixing sleep and interrupts.

MicroChip should probably change their wording a bit to indicate the interrups WILL wake the device from sleep instead of that they CAN wake them from sleep if this bit is set. I, like most others, infer that this is a "wake from sleep on interrupt" bit that CCS has not given the programmer control of. It was not until I got to the bit level of what #define INT_EXT1 was setting that I figured it out. CCS does not explain the settings, they simply give them to you, expect you to know the processor, know the language, and make a leap of faith on how the header files are created. I can live with the first two, but the leap of faith on the defines often proves problematic. If one needs to understand which bits are being set to what values (as in this case), there is no documentation that I am aware of to show how they map things like:
#define INT_EXT1 0xF008
into the actual registers of the processor.

I doubt they will help us out by making and publishing a map. But since this is particular case is clearly a point of confusion, CCS could help their programmers out by mentioning (or being more clear) in either the ENABLE_INTERRUPTS() or SLEEP() section, that devices who support external interrupts will be woken from sleep automatically when an external interrupt occurs, if that interrupt is left enabled when the sleep function is called. It would be just that simple if they would be willing to make the effort.

Many thanks for helping me wade through this issue, Mr. or Mrs. "PCM Programmer".

-Kyle
Guest
Guest







PostPosted: Thu Jun 23, 2005 8:51 am     Reply with quote

I don't know if its better to write newbee or guest cuz am both of this:-)

This is the question:
Quote:

I have the same problem... I want to restart the whole program on button press. That should be exactly like connecting to MCLR. (restart_wdt and make reset). My reset switch is not connected to MCLR...
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Jun 23, 2005 9:03 am     Reply with quote

If it s a PIC18 use reset_cpu()
if not then use reset_cpu() and know that the registers also need to be reset.
see documentation on reset_cpu()

OR

tie an output pin to mclr and lower that pin on the button press.
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