View previous topic :: View next topic |
Author |
Message |
nmeyer
Joined: 09 Jul 2004 Posts: 70
|
WDT Issue on 12F683 |
Posted: Wed Apr 07, 2010 4:27 pm |
|
|
I am having an issue with a the WDT and timer0 on the 12F683. I have a timer0 INT that i want to use to count seconds and after a preset time, turn off my output and put the chip to sleep. I want to use the WDT to wake up the chip every so often and check to see if it should be active again or go back to sleep. If the WDT is off, my second counter works fine. However, if i turn the WDT on, the PIC just locks up.
Compiler V. 4.086
Code: |
#include <12F683.h>
#device *=16 ADC=10
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR,BROWNOUT
#use delay(clock=500000)
#define RAND_MAX 255
#define dusk 970
#define INTS_PER_SECOND 240 //976
#include <stdlib.h>
int8 count,loop_int,rand_start=1,loop_var;
long ambient_light;
long seconds,hour,minute,int_count;
////////////////////////////////////////////////////////////////////////////////
#int_timer0
void clock_isr(void)
{
if(--int_count==0) //decrement counter until 0
{
++seconds; //count up seconds
int_count=INTS_PER_SECOND; //reset counter
if (seconds>=65000)
seconds=65000;
}
}
////////////////////////////////////////////////////////////////////////////////
void main()
{
setup_wdt(WDT_OFF);
//setup_wdt(WDT_2304MS);
setup_oscillator(osc_500khz);
setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_timer_2(T2_DIV_BY_1, 127, 1);
set_adc_channel(0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(0);
enable_interrupts(INT_RTCC);
/*setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(0);
enable_interrupts(INT_TIMER1);*/
enable_interrupts(GLOBAL);
int_count=INTS_PER_SECOND; //used for timer
seconds=0; //clear out variable
minute=0; //clear out minute counter
hour=0; //clear low voltage counter for seconds
/* Main Program */
while (TRUE)
{
if (rand_start==254)
rand_start=1;
else rand_start++;
srand(rand_start); // everytime this is called the seed will be initialized and the random sequence will be started
loop_var=rand();
ambient_light=read_adc();
if(seconds>=5)
//if (ambient_light>=dusk)
{
loop_var=0;
setup_ccp1(CCP_OFF);
sleep();
//seconds=0;
//setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
}
for (loop_int=0;loop_int<loop_var;loop_int++)
{
count=rand();
if(count<20)
count=20;
set_pwm1_duty(count);
delay_ms(100);
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Apr 07, 2010 5:43 pm |
|
|
Can you make a smaller test program ? If you could get rid of about
90% of the code it would be a lot easier to spot the problem.
No, I'm serious. A smaller program makes it easier for us to solve the
problem by inspection.
Also, you don't need this line, because RAM in the 12F683 doesn't extend
beyond address 0xFF. You only need 16 bit pointers if you want to use
RAM at addresses 0x100 and above. (This option applies to 12F and 16F
PICs only. 18F PICs always use 16-bit pointers). |
|
|
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Thu Apr 08, 2010 1:55 am |
|
|
2 things,
Some PICs restart on a WDT from sleep have you checked your datasheet ?
When enabled it looks like you are using a 2304 ms WDT, you have a delay of 100 ms in your for loop, if loo_var > approx 23 this will cause your loop to take longer than 2304 ms and the WDT will restart your pic.
You can fix it by placing
restart_wdt()
in your loop or
#use delay (clock=500000, restart_wdt) |
|
|
nmeyer
Joined: 09 Jul 2004 Posts: 70
|
|
Posted: Thu Apr 08, 2010 3:50 pm |
|
|
Here is a shorter version. If the WDT is set to Off and the setup_wdt(wdt_2304ms) is commented out, the program will count up to 5 seconds and turn on the LED and go to sleep, but since the wdt is not turned on, it will stay asleep. If i change the fuse to WDT and use the setup_wdt(wdt_2304ms) the program no longer functions.
Code: |
#include <12F683.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOMCLR,BROWNOUT
#use delay(clock=500000)
#define INTS_PER_SECOND 240 //976
int a;
long seconds,hour,minute,int_count;
////////////////////////////////////////////////////////////////////////////////
#int_timer0
void clock_isr(void)
{
if(--int_count==0) //decrement counter until 0
{
++seconds; //count up seconds
int_count=INTS_PER_SECOND; //reset counter
if (seconds>=65000)
seconds=65000;
}
}
////////////////////////////////////////////////////////////////////////////////
void main()
{
setup_wdt(WDT_OFF); //I am chaning these two lines only and WDT
//setup_wdt(WDT_2304MS); //fuse from NOWDT to WDT
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(0);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
int_count=INTS_PER_SECOND; //used for timer
seconds=0; //clear out variable
output_low(PIN_A2);
/* Main Program */
while (TRUE)
{
if(seconds>=5)
{
output_high(PIN_A2);
for(a=0;a<10;a++)
{
delay_ms(100);
}
sleep();
seconds=0;
}
else
output_low(PIN_A2);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 08, 2010 4:20 pm |
|
|
It looks to me like I was working on this problem for you back in 2007, LOL.
See my post at the end of this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=33089
In that program, WDT_TIMES_4 is used to give a 69ms timeout.
To get the 2304ms timeout, change it to WDT_TIMES_128.
Try the test program in the link above and see if that works. |
|
|
nmeyer
Joined: 09 Jul 2004 Posts: 70
|
|
Posted: Thu Apr 08, 2010 4:33 pm |
|
|
Yeah, I remember that. I was never able to get the WDT and the int_timer0 to work on that one either. I ended up turning off the WDT totally. I am reading that some parts share RTCC and WDT and I am wondering how that affects the set up and use. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 08, 2010 4:40 pm |
|
|
I probably tested the code in that link in hardware. Did you try that
exact code and it failed ? |
|
|
nmeyer
Joined: 09 Jul 2004 Posts: 70
|
|
Posted: Fri Apr 09, 2010 9:27 am |
|
|
Yes, that code does work. I have gone and stripped my code down and started adding things back in. I have it working as I intend for it to work at this point. I am not really sure what is different from what I posted the other day to what I have now, some slight differences in the code. But I do not see what caused it not to work the other day and let it work now. Thanks |
|
|
|