Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Weird problem with WDT on PIC18F2420

Status
Not open for further replies.

Mr RB

Well-Known Member
Hi, this little problem has me pulling hair out and I can't work out why! :)

I have a PIC 18F2420 running on 8MHz xtal HS mode, and it needs to be a low power app that sleeps most of the time and wakes up on the WDT timeout, performs a few mS of code, and back to sleep.

The test code for the moment is literally as simple as this;
Code:
main
{
  TRISB = 0;		// outputs for test LEDs

  LATB.F4 = 1;	// test LED on
  Delay_mS(20);
  LATB.F4 = 0;	// test LED off

  asm SLEEP;		// back to sleep
}

The result on the 'scope looks like this;
1. LED on for 20mS, 2.5mA
2. SLEEP for 272mS, approx 0mA
3. Powers up, 2.0mA, for 272mS, before code execution starts
(The 272mS period is the correct WDT period for the WDT /64 setting in the config.)

It should do this;
1. LED on for 20mS, 2.5mA
2. SLEEP for 272mS, approx 0mA

So, apparently after osc powers up it is stuck for ANOTHER WDT timeout period, before code execution starts! This is terrible as I need it to sleep for a WDT for about 10 seconds, then be awake for a couple mS.

Testing everything I can think of showed both the periods match, and both are the WDT timeout period.

I have messed with the majority of the settings, FSCM, 2speed startup, PWRT on/off etc and it does not matter what settings are used, there is always a delay of 1 WDT timeout after power up and BEFORE code execution starts! As you can understand this is killing my low power application as the best power reduction I can get is 50:50 by time (sleep/powered).

Changing osc type does not help, even on the internal osc block the WDT problem is identical.

If anyone has a suggestion (like I have forgotten something really silly) then please speak up!
 
Code:
main
{
  TRISB = 0;		// outputs for test LEDs
 
  LATB.F4 = 1;	// test LED on
  Delay_mS(20);
  LATB.F4 = 0;	// test LED off
 
  _asm 
   SLEEP;		// back to sleep
   nop
   nop
   decfsz  name   // temperary file
  goto    $-5    // redo sleep
 _endasm
}


you should be able to check if a bit in the STATUS reg is set to make sure the WDT was the wake up and not something else..ccp,...and check for that also in your code, In the sleep and or watchdog areas of the data sheet it'll explain how to check for the wdt status bit and also how to not do a reset. it's been a while since I needed to due that :) I also used a temp file to increase the time before completing the req'd time I had needed, I put nop's after every sleep otherwise when sleep is started the next line is where it where stay till it wakes up.
 
Thanks for the suggestions guys, I'll check those out after I have some food.

The other test I did was to strip the code to this;
Code:
main()
{
  asm sleep;
}

And it did this on the 'scope;
1. sleep for one WDT period 272mS
2. runs for one one WDT period 272mS
(repeats!)

From what I can see it should not matter whether the WDT wakes up or resets the PIC? In both cases it should run be a reset? ie reset, or run from the end of main (also reset?).
 
you're right, on my one project, I did just that, it would jump to another branch, but then would be reset back to the beginning to start over when that one was finished. Also clearing out some of the files to be reused.
 
Thanks to everyone who offered help, you made me check a couple of things and I found out I made two silly mistakes;

1. I assumed the WDT timeout would cause a reset, because this PIC had no option to select reset/restart on the WDT timeout. I changed all the possible power management config modes etc, and assumed at least one mode would always give a device reset on WDT timeout.

2. I forgot that the MikroC compiler ALWAYS puts an invisible "goto here" at the end of main()!

Code:
// like this;
main()
{
  asm sleep;   // my code
  goto here;   // INVISIBLE
}

Because the WDT did not cause a device reset, it simply woke from sleep and hung totally in the invisible "goto here" until a second WDT reset.

Buried in the datasheet I found info that basically says this;

"The WDT timeout will cause a device reset if the code is executing at the time. If the device is in SLEEP mode, the WDT timeout causes wakeup and code starts running from that point".

So now it makes perfect sense, one WDT period caused the sleep to end, the second WDT period made it break out of the invisible hang.

Not being able to set the WDT to be able to do what I wanted (always reset), the only solution was to force a reset on wakeup from sleep;

Code:
// like this;
main()
{
  asm sleep;   // my code
  asm reset;   // my code
  goto here;   // INVISIBLE
}

Thanks to the people that helped. I feel like a bit of an idiot not catching this immediately, but it was after many hours of coding a tuning other functions, and then at the last minute I thought "right! I'll stick this thing in WDT sleep mode and see the power consumption on the 'scope". One of those late night "I'll just add this ONE thing" moments. ;)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top