|
|
View previous topic :: View next topic |
Author |
Message |
ac34856
Joined: 14 Dec 2009 Posts: 33 Location: Wales
|
Watchdog timer doesn't turn off 18F4620 PIC |
Posted: Tue Feb 16, 2010 9:44 am |
|
|
I'm having trouble getting the WDT to turn off. The following code
runs but the line setup_wdt(WDT_OFF) doesnt work - in other words the WDT still runs. I would also like to dynamically change the Watchdog timeout prescaler value other than in the fuses.
Compiler 4.057
Any comments appreciated.
Code: |
#include <18F4620.h>
#device PASS_STRINGS=IN_RAM
#fuses HS // High speed oscillator
#fuses WDT // Watchdog timer enabled
#fuses WDT1024 // Watchdog timer prescaler
#fuses NOPROTECT
#fuses BROWNOUT // Has protection for recovery from low Vcc
#fuses PUT // Has power up timer
#fuses NOLVP // No Low voltage programming
#fuses MCLR
#fuses NODEBUG
#use DELAY(clock = 20000000, RESTART_WDT)
#use RS232(baud=115200, XMIT=PIN_C6, RCV=PIN_C7, ERRORS, STREAM=USB, RESTART_WDT)
TYPEDEF unsigned int16 UINT16;
UINT16 reason;
static UINT16 count;
void main(void)
{
reason = restart_cause();
switch(reason)
{ case WDT_TIMEOUT:
{ fprintf(USB, "\r\n Watchdog timed out - CPU Reset ! ");
break;
}
case NORMAL_POWER_UP:
{ fprintf(USB, "\r\n CPU Started normally !");
break;
}
default:
fprintf(USB, "\r\n Miscellaneous Restart (%04Xh)", reason);
break;
}
setup_wdt(WDT_OFF); // !!! Why doesnt this line work ??
while(1)
{
++count;
fprintf(USB, "\r\n A - Sleeping until WDT (Count: %Lu)", count);
delay_ms(10);
while(1); // Stop here waiting for WDT to test .. ..
// sleep(); // Go to sleep and wait for WDT to wake-up
fprintf(USB, "\r\n Woken up !");
// restart_wdt();
delay_ms(300);
}
} |
|
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 16, 2010 11:20 am |
|
|
Read the data sheet.....
Critical line:
"PIC18F2525/2620/4525/
4620 devices have a Watchdog Timer, which is either
permanently enabled via the configuration bits or
software controlled (if configured as disabled)."
You can only _software control_the watchdog timer, if it is _disabled_ in the fuses. If you set it to enabled in the fuses, it will _always_ run.
If you want to software control the 'effective' watchdog time, then have a timer interrupt, at a slightly higher frequency than your programmed watchdog time. Have an internal global variable called (say) wdog, then in the timer interrupt have:
Code: |
if (wdog) {
--wdog;
restart_wdt();
}
|
You can then in your code at any point set 'wdog' to a value, and have this many beats of the timer interrupt, plus the hardware watchdog time, till the watchdog will trigger.
Best Wishes |
|
|
ac34856
Joined: 14 Dec 2009 Posts: 33 Location: Wales
|
|
Posted: Wed Feb 17, 2010 10:37 am |
|
|
Thanks .. that is an excellent piece of information ! |
|
|
|
|
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
|