View previous topic :: View next topic |
Author |
Message |
peter-storm
Joined: 26 Jan 2008 Posts: 11
|
PIC16f690 WDT problem |
Posted: Fri Feb 29, 2008 6:22 pm |
|
|
Hi again, I'm having another problem, this time with my watchdog timer.
I want to use the timer in software mode i.e. be able to turn it on/off and change the delay time appropriately.
I want the following code to not reset during the 5 second waiting period, and the wdt to be enabled after, so the pic can wake from sleep.
I know that the command:
Code: | #use delay(clock=8000000, restart_wdt) |
will cause it to not restart during delays, however, my real program has various time-consuming functions instead of the "delay_ms", therefore will restart even with the above #use.
Any advice appreciated.
Code: |
#include <16F690.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT
#use delay(clock=8000000)
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_wdt(WDT_2304MS|WDT_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_8MHZ);
set_tris_c(0x00);
SETUP_WDT(WDT_OFF);
output_toggle(PIN_C0);
delay_ms(5000);
SETUP_WDT(WDT_ON);
} |
|
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Fri Feb 29, 2008 11:11 pm |
|
|
Hi,
You must restructure your code, so that the program does not wait longer than the WDT time.
Also you have not 'terminated' the program properly, after toggling the PIC will go to to an undetermined state as there is no code to execute, you must put a forever do-loop to prevent this.
You could replace delay_ms(5000) with this..
int16 n; //declare this as a global variable
for (n=0;n<5000;n++)
{
output_toggle(PIN_C0);
delay_ms(1);
}
//wdt can remain on.
//This is the forever do-loop, this will prevent restart after toggle operation has ended.
do
{
restart_wdt();
}while (TRUE);
Hope this helps.
thanks
arunb |
|
|
peter-storm
Joined: 26 Jan 2008 Posts: 11
|
|
Posted: Sat Mar 01, 2008 3:58 am |
|
|
Hi arunb,
Thanks for your reply. A couple of things - I want the PIC to enter sleep until the watchdog timer causes an interrupt, and I believe that CCS inserts a sleep command after all code has been executed, therefore my program has been terminated. Inserting a while(true) loop would cause the pic to stay in that loop forever, no?
Also, I cannot restructure my code. I am updating a display that takes approximately 5 seconds, and I want to sleep for 2 seconds. Currently, it restarts when the display has half updated.
Cheers. |
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Sat Mar 01, 2008 4:50 am |
|
|
Hi,
Yes 'while(TRUE)' will prevent the PIC from going to SLEEP. In which case you can remove the while(TRUE).
The WDT timeout has been set to 2304 msec in your code (say around 2.3 seconds), since the display update takes 5 seconds, the PIC restarts in 2.3 seconds.
thanks
arunb |
|
|
peter-storm
Joined: 26 Jan 2008 Posts: 11
|
|
Posted: Sat Mar 01, 2008 5:02 am |
|
|
What I want to do is control the wdt in software as the help suggests I can. The problem is while WDT_OFF works, WDT_ON will not start the wdt and so the device enters sleep and does not return.
Cheers. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Mar 02, 2008 4:49 pm |
|
|
I stripped your program down to something reasonable, and it runs.
It turns the LED on for about 10 seconds, and then off for 10 seconds,
continuously. This was tested with vs. 4.068.
Quote: |
#include <16F690.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT
#use delay(clock=8000000)
void main()
{
setup_wdt(WDT_2304MS);
SETUP_WDT(WDT_OFF);
output_toggle(PIN_C0);
delay_ms(5000);
SETUP_WDT(WDT_ON);
} |
|
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Mon Mar 03, 2008 2:57 am |
|
|
Is there more code to this program ?
As it stands you have a problem.
The compiler adds a sleep instruction after you main code. I have heard that it actually fills the rest of memory with sleep instructions.
Now your current code turns the WDT off, waits 5000ms and then turns the WDT back on and then stops (sleeps). If the WDT is working it will wake the PIC up and the PIC will execute the next instructio after the compiler inserted sleep instruction. This may be another sleep instruction. It may be some random data or part of your program. So it may sleep again or at some point the WDT kicks in and it actually restarts. Anyway, this action is not gauranteed!
Why are you writing this to rely on a restart for your code to work properly ?
You can turn the WDT OFF while you execute your routines or you can insert restart_wdt() at appropriate points to stop the WDT from resetting your code. This may be what you are after though.
Code: |
while (true) {
setup_wdt(WDT_OFF);
output_toggle(PIN_C0);
// Do your stuff
setup_wdt(WDT_ON);
sleep();
}
|
|
|
|
|