View previous topic :: View next topic |
Author |
Message |
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
Can someone confirm my WDT code? |
Posted: Wed Apr 13, 2011 11:06 am |
|
|
I just need to be sure I understand this correctly, I've looked at the example files and CCS manual and this is the best I could come up with for a WDT wake-up timer:
Code: | #fuses WDT
main()
{
setup_wdt(WDT_2304MS);
while (TRUE)
{
do_something();
restart_wdt(); //restart before sleep, timeout will trigger wake up?
sleep(); //sleep for 2304MS
}
} |
Thanks! _________________ Vinnie Ryan |
|
|
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: Can someone confirm my WDT code? |
Posted: Wed Apr 13, 2011 11:57 am |
|
|
It seems fine to me but I don't do a lot of WDT stuff.
But, why don't you just... you know... try it. I mean, what would it take, like 2 minutes to compile and flash it onto a chip? There's a lot of questions in this forum that could be answered this way. I'm not trying to single you out. Maybe you have a reason why you can't just compile and test. Otherwise, just try it out and see what happens. Most PIC chips support a whole bunch of flash writes. And, yes, I do practice what I preach. I do a whole bunch of compile/flash/test cycles when developing.
vinniewryan wrote: | I just need to be sure I understand this correctly, I've looked at the example files and CCS manual and this is the best I could come up with for a WDT wake-up timer:
Code: | #fuses WDT
main()
{
setup_wdt(WDT_2304MS);
while (TRUE)
{
do_something();
restart_wdt(); //restart before sleep, timeout will trigger wake up?
sleep(); //sleep for 2304MS
}
} |
Thanks! |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Wed Apr 13, 2011 12:35 pm |
|
|
collink is right on the money. NOTHING like a real world test to confirm whether code works or fails!
Just have your 'dosomething()' function say toggle an LED for 100ms.
Be aware though that the WDT times are NOT carved in stone ! Read the documentation and you'll see a +-50-100% variation in 'timing'.
I've never lost a PIC due to the 'code-burn-test-adnausem'. Easy to have 50-60 'progressive versions' of a program on file. And never ever trust any 'simulator'. NONE work right! |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Wed Apr 13, 2011 6:39 pm |
|
|
Thanks for the confirmation! I did try it and it seemed to work fine, but this was my first WDT wake up program and I really wanted to make sure I wasn't missing anything crucial that would bite me in the rear later on. It's for a show prototype so I need to be 110% certain. I've written programs that work fine in the past, but then one day would randomly freeze the PIC or something to that effect simply because a #define was out of range that one time, or a fuse was incorrect. I realize the WDT isn't 100% accurate, it just needs to wake up an RF receiver once every few seconds so that's not an issue.
Thanks again! :D _________________ Vinnie Ryan |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Apr 14, 2011 2:04 am |
|
|
There is one 'tiny' thing, that might cause problems later.
Code the sleep as:
Code: |
sleep();
delay_cycles(1);
|
The instruction _after_ the sleep, is 'prefetched' when you go to sleep. Doesn't matter at all if it is a simple jump (as in your original example), _but_ if it is something like a input from a pin, or a test, you may well get the wrong result...
The delay_cycles instruction, puts a single 'NOP' instruction after the sleep, and ensures there will not be a problem because of the prefetch.
Best Wishes |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Thu Apr 14, 2011 5:22 pm |
|
|
Perfect! Thank you so much, my program will be much more complex using many inputs and comm functions. I'll certainly add that in!
Cheers _________________ Vinnie Ryan |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Mon Apr 18, 2011 12:03 pm |
|
|
I am having one problem, whenever WDT is enabled, my program seems to go to sleep after a certain amount of time (about 2 seconds) even if I don't call the sleep(); command. Why would this be? This is very strange especially because the only code I'm using is:
Code: | #fuses WDT
void main()
{
while(1)
{
SETUP_WDT(WDT_OFF);
}
} |
EDIT: Actually it's not sleeping, but rather whenever the WDT fuse is enabled, my program resets after so many frames... It seems to be about every 2 seconds.. _________________ Vinnie Ryan
Last edited by vinniewryan on Mon Apr 18, 2011 12:14 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 18, 2011 12:11 pm |
|
|
I just scanned the thread and you've never told us what PIC you're using
or what your compiler version is.
And if you don't specify the oscillator fuse, the compiler defaults to the
RC oscillator setting. It won't run. You've got to specify the important things. |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Mon Apr 18, 2011 12:17 pm |
|
|
Sorry, I forgot about that. PIC16f684, compiler 4.119, Oscillator = 4Mhz
I can tell the program is resetting because all variables are resetting to zero after so many frames. I would love to post the program but it's 532 lines and I know the problem exists only when WDT fuse is set, even if there's no other code, or if I disable the WDT. It seems just calling the WDT fuse shouldn't have any effect until I call a function that uses the WDT? _________________ Vinnie Ryan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 18, 2011 12:40 pm |
|
|
Quote: | #fuses WDT
void main()
{
while(1)
{
SETUP_WDT(WDT_OFF);
}
}
EDIT: Actually it's not sleeping, but rather whenever the WDT fuse is enabled, my program resets after so many frames... It seems to be about every 2 seconds.. |
The 16F684 data sheet describes this exact behavior:
Quote: |
12.6.2 WDT CONTROL
When the WDTE bit in the Configuration Word register
is set, the SWDTEN bit of the WDTCON register has
no effect.
If WDTE is clear, then the SWDTEN bit can be used
to enable and disable the WDT. Setting the bit will
enable it and clearing the bit will disable it. |
You have the WDT fuse enabled, so the first paragraph applies.
It means that software on/off won't work. That's exactly what
you're seeing. Should I say it ? (rtfm) |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Mon Apr 18, 2011 1:58 pm |
|
|
Thank you PCM, I'm still very slow when it comes to comparing CCS functions to data sheet information. I did read that paragraph but I wasn't sure how to determine which bit the WDT was setting when the fuse is declared. Do you have any advice to help me practice referencing between CCS and datasheets? I'm not even sure where to look to find the registers set when #fuses are used..
Thanks! _________________ Vinnie Ryan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 18, 2011 2:47 pm |
|
|
Here's one way to do it, which I have used:
Printf the page(s) in the PIC data sheet that show the bit layout of the
Config Bits registers. In most data sheets, this will be in the section
called "Special Features of the CPU". Here's the 16F684 data sheet:
http://ww1.microchip.com/downloads/en/DeviceDoc/41202F.pdf
It's this diagram, on page 98 (page 100 in Acrobat reader):
Quote: | REGISTER 12-1: CONFIG: CONFIGURATION WORD REGISTER |
Then compile your program in MPLAB and look at the bottom of the .LST
file, where it shows the "Configuration Fuses" that were created by your
#fuses statement.
For example, I compiled the following program with vs. 4.119:
Code: |
#include <16F684.h>
#fuses INTRC_IO, WDT
#use delay(clock=4M)
void main()
{
while(1)
{
SETUP_WDT(WDT_OFF);
}
} |
The Config Bits at the end of the .LST file are:
Quote: | Configuration Fuses:
Word 1: 3FEC INTRC_IO WDT PUT MCLR NOPROTECT NOCPD BROWNOUT IESO FCMEN
|
Then convert 0x3FEC into binary notation:
Code: |
0011 1111 1110 1100 |
Now write those numbers above the boxes in the bit diagram that you
printed from the 16F684 data sheet. Then it will look like this:
Code: |
REGISTER 12-1: CONFIG: CONFIGURATION WORD REGISTER
0 0 1 1 1 1 1 1 = 0x3F
- - - - FCMEN IESO BOREN1 BOREN0
bit 15 bit 8
1 1 1 0 1 1 0 0 = 0xEC
CPD CP MCLRE PWRTE WDTE FOSC2 FOSC1 FOSC0
bit 7 bit 0
|
Now you can just look at the page, and see what each bit is set to.
You can then look at the descriptions lower down on the page and see
what that particular setting does. In the case of the WDTE bit, a '1'
means "WDT enabled". You can also read what a 0 does. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Mon Apr 18, 2011 3:42 pm |
|
|
PCM programmer wrote: | ....
Printf the page(s) in the PIC data sheet .... |
No disrespect, but you need a vacation to get your mind off of CCS and PICs. |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Mon Apr 18, 2011 3:45 pm |
|
|
This makes perfect sense, thank you! I've always wondered how you seem to have access to information which I have no idea where to find, I never thought to read these registers after programming the chip. I'll do a few tests to make sure I understand. _________________ Vinnie Ryan |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 18, 2011 4:05 pm |
|
|
lol, nice catch |
|
|
|