View previous topic :: View next topic |
Author |
Message |
jahan
Joined: 04 Apr 2005 Posts: 63
|
can watch dog wake up a processor during sleep? |
Posted: Wed Jul 27, 2005 9:22 am |
|
|
can watch dog wake up a processor during sleep?
I would like to wake up my processor (16F84A) from sleep using WDT.
Is it doable?
Thankx |
|
|
theMagni
Joined: 21 May 2004 Posts: 48 Location: Victoria, BC
|
|
Posted: Wed Jul 27, 2005 10:45 am |
|
|
Yes.
You'll have to read your datasheet to find out what the WDT is going to do. It's under "special features". Check both the WDT and SLEEP specs.
For example, the 16F88 wakes up the PIC and it resumes instruction on the next line. The 10F202 resets on WD timeout. _________________ In the 90's, I promised myself I'd never use a so-called "smiley icon". I hate what I've become. ;) |
|
|
mcafzap
Joined: 07 Sep 2003 Posts: 46 Location: Manchester, UK
|
|
Posted: Wed Jul 27, 2005 2:33 pm |
|
|
This is easy provided you bear in mind the different behaviours of the various devices.
This is not a complete working program for all the usual reasons - I've had to edit it down to a minimum. It wakes up every WDT timeout, but only responds every 3rd time.
Code: |
#include <10F206.h>
#Fuses NOMCLR,NOPROTECT,WDT
#use delay(clock=4000000)
#use fast_io(B)
int8 sleepcount;
void main() {
#asm
// Disable wake-up on pin change, enable weak pull-ups,
// Timer0 source internal, L to H
// Prescaler to WDT, max division 2304mS
movlw 0x8F
OPTION
#endasm
// no comparator output,
CMCON0 = 0x73;
sleepcount++;
if (sleepcount > 2){ //Every 3rd 'sleep' ...
sleepcount = 0;
//do whatever's required.
}
// Falls off the end here because there is no 'while(1)'
// hence it naturally goes to sleep.
|
Alternatively for the 16F629...
Code: |
#use fast_io(A)
int8 sleepcount;
#byte PORT_A = 5
#byte TRIS_A = 0x85
void main() {
setup_wdt(WDT_2304MS);
// set up port/peripherals here
sleepcount=0;
While(1){
if (sleepcount > 2){ //Every 3rd 'sleep' ...
sleepcount = 0;
//do whatever }
sleep();
sleepcount++;
}
} //end main
|
Once again, not a full program, but you'll note the difference that on this device the program stays within the while(1) loop so we can safely initialise sleepcount (it never gets back out to the main() loop).
(My thanks once again to PCM for his invaluable help to me on this subject.)
HTH
Steve |
|
|
jahan
Joined: 04 Apr 2005 Posts: 63
|
|
Posted: Wed Jul 27, 2005 8:57 pm |
|
|
Thankx steve.
I did read the data sheet and getting feed from your code definitly helped me understand the WDT better.
-JJ |
|
|
Guest
|
|
Posted: Mon Aug 08, 2005 6:31 am |
|
|
mcafzap wrote: | Code: |
#include <10F206.h>
#Fuses NOMCLR,NOPROTECT,WDT
#use delay(clock=4000000)
#use fast_io(B)
int8 sleepcount;
void main() {
#asm
// Disable wake-up on pin change, enable weak pull-ups,
// Timer0 source internal, L to H
// Prescaler to WDT, max division 2304mS
movlw 0x8F
OPTION
#endasm
// no comparator output,
CMCON0 = 0x73;
sleepcount++;
if (sleepcount > 2){ //Every 3rd 'sleep' ...
sleepcount = 0;
//do whatever's required.
}
// Falls off the end here because there is no 'while(1)'
// hence it naturally goes to sleep.
|
Steve |
In this example of PIC10F202, "sleepcount" is not initialized. Is it acceptable to assume that it starts with 0 on cold boot? |
|
|
Ttelmah Guest
|
|
Posted: Mon Aug 08, 2005 6:39 am |
|
|
It _is_ initialised!...
if you read the manual, you will find hidden away in there, a note that global variables are initialised to zero. This can be a pain at times (when you want such variables to be maintained on a reboot).
so you can assume that any variable declared in the main 'body' like this (and hence a global variable), is automatically set to '0'.
Best Wishes |
|
|
Guest
|
|
Posted: Mon Aug 08, 2005 10:35 pm |
|
|
Ttelmah wrote: | It _is_ initialised!...
if you read the manual, you will find hidden away in there, a note that global variables are initialised to zero. This can be a pain at times (when you want such variables to be maintained on a reboot).
so you can assume that any variable declared in the main 'body' like this (and hence a global variable), is automatically set to '0'.
|
Then, does it actually increase sleepcount when it wakes up from sleep by WDT?
Code: | int8 sleepcount;
void main() {
|
sleepcount++;
if (sleepcount > 2){ |
|
|
|
Guest
|
|
Posted: Mon Aug 08, 2005 10:35 pm |
|
|
Ttelmah wrote: | It _is_ initialised!...
if you read the manual, you will find hidden away in there, a note that global variables are initialised to zero. This can be a pain at times (when you want such variables to be maintained on a reboot).
so you can assume that any variable declared in the main 'body' like this (and hence a global variable), is automatically set to '0'.
Best Wishes |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 08, 2005 11:53 pm |
|
|
Actually, a global variable is automatically initialized to zero only if you
declare it as static. If it's declared as a global without the static qualifier,
then you have to set it to zero with code:
Code: | int8 sleepcount = 0; |
The manual says this:
Quote: | static: Static variable is globally active and initialized to 0 |
|
|
|
Ttelmah Guest
|
|
Posted: Tue Aug 09, 2005 4:10 am |
|
|
PCM programmer wrote: | Actually, a global variable is automatically initialized to zero only if you
declare it as static. If it's declared as a global without the static qualifier,
then you have to set it to zero with code:
Code: | int8 sleepcount = 0; |
The manual says this:
Quote: | static: Static variable is globally active and initialized to 0 |
|
If you declare a variable as static inside a function, it is also initialised to zero, but in fact all global variables seem to be cleared (even without using 'zero RAM'). This caused me some grief in the past, and I moaned about it to CCS, pointing out that for a system using a 'warm restart' after a watchdog, I wanted global variables to be maintained, unless I specifically cleared them. If you look at this:
Code: |
Variable declared external to main as:
int8 cause;
int8 ctick;
The symbol addresses are:
024 cause
025 ctick
and the asssembler generated at the start of main is:
.................... void main() {
....................
0004: CLRF FF8
0006: BCF FD0.7
0008: CLRF FEA
000A: CLRF FE9
000C: BSF FC1.0
000E: BSF FC1.1
0010: BSF FC1.2
0012: BCF FC1.3
0014: MOVLW 19
0016: MOVWF FAF
0018: MOVLW 26
001A: MOVWF FAC
001C: MOVLW 90
001E: MOVWF FAB
001F: MOVLB 0
0020: CLRF x24
0021: CLRF x25
|
This was with 3.147, which though I have latter versions, I am still using for some code. If they have switched to not clearing globals, unless declared as static, I'll be cheering!... :-)
(I ended up manually generating the required variables in a block of memory, which I took control of).
Best Wishes |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Aug 09, 2005 4:42 am |
|
|
In C++ and in ANSI-C global and static variables are automatically initialized to zero when they are declared. So this is one of those rare situations where CCS does follow the ANSI-C standard. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 09, 2005 12:30 pm |
|
|
I can't make it zero the globals with any version I try.
I'm pretty sure that I saw it do that in the past, but I don't know with
what version. Here is a test program that I compiled with PCH 3.230:
Code: |
#include <18F452.h>
#fuses XT, NOWDT, NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)
int8 cause;
int8 ctick;
//======================================
main(void)
{
cause = 0x55;
ctick = 0xAA;
while(1);
} |
Here is the ASM code:
Code: |
.................... main(void)
.................... {
0004: CLRF FF8
0006: BCF FD0.7
0008: CLRF FEA
000A: CLRF FE9
000C: BSF FC1.0
000E: BSF FC1.1
0010: BSF FC1.2
0012: BCF FC1.3
....................
.................... cause = 0x55;
0014: MOVLW 55
0016: MOVWF 05
.................... ctick = 0xAA;
0018: MOVLW AA
001A: MOVWF 06
....................
.................... while(1);
001C: BRA 001C
.................... }
....................
....................
....................
001E: SLEEP |
========================
If I declare the variables as static, like this:
Code: | static int8 cause;
static int8 ctick; |
Then it puts in two CLRF statements:
Code: | .................... main(void)
.................... {
0004: CLRF FF8
0006: BCF FD0.7
0008: CLRF FEA
000A: CLRF FE9
000C: BSF FC1.0
000E: BSF FC1.1
0010: BSF FC1.2
0012: BCF FC1.3
0014: CLRF 05
0016: CLRF 06
....................
.................... cause = 0x55;
0018: MOVLW 55
001A: MOVWF 05
.................... ctick = 0xAA;
001C: MOVLW AA
001E: MOVWF 06
....................
.................... while(1);
0020: BRA 0020
.................... }
....................
....................
....................
0022: SLEEP |
|
|
|
|