View previous topic :: View next topic |
Author |
Message |
JohnKennedy
Joined: 12 May 2004 Posts: 38
|
Forcing a restart |
Posted: Tue Jun 21, 2005 4:45 am |
|
|
I have a requirement that when a set of circumstances occur I need to goto the start of my program is their a way of doing this in software?
The only way I can see of doing it is with a goto statement, is there a better way?
Thanks
JFK |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Tue Jun 21, 2005 5:14 am |
|
|
The 18F family has a native reset instruction _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
JohnKennedy
Joined: 12 May 2004 Posts: 38
|
|
Posted: Tue Jun 21, 2005 5:53 am |
|
|
Unfortunately I'm using a 16F818 |
|
|
Guest Guest
|
|
Posted: Tue Jun 21, 2005 6:41 am |
|
|
I have the same problem... I want to restart the whole program on press.
That should be exactly like connecting to MCLR.
My reset switch is not connected to MCLR... |
|
|
Ttelmah Guest
|
|
Posted: Tue Jun 21, 2005 6:50 am |
|
|
There is no 'simple' answer on the 16 family. CCS, implement a 'reset_cpu' instruction, which jumps you to address 0, but if the stack contains values when you use this, eventually you will get a stack overflow. Also the jump does no put the default registers back to their reset state. One way you could implement a similar ability, would be to enable the watchdog, then in your code, ensure this is reset, but when the button is pushed, stop clearing the watchdog. Depending on the prescaler selected, a little while latter, the watchdog will timeout, and you will get as close to a power on reset, as the hardware allows.
So if (for instance), you program the watchdog to nominally 36mSec, then have a timer interrupt that occurs every 10mSec say, which has something like:
Code: |
int1 wdog_reset_flag=false;
#int timer_2
void timer_event(void) {
if (!wdog_reset_flag) restart_wdt();
}
|
Then in your main code, when the button is pushed, you have:
wdog_reset_flag=true;
The code will reset a few mSeconds later.
Now I suggest 36mSec, because of the very large 'spread' that you can see on the watchdog. On some chips, the shortest watchog timeout on a 36mSec setting, is just 14mSec, allowing a little margin for a 10mSec interrupt driven reset.
Best Wishes |
|
|
Guest Guest
|
|
Posted: Tue Jun 21, 2005 7:55 am |
|
|
how about this:
I check my time and if the time is not set one new value ( if the time has reached 10 hours ) , can i restart wdt then?
So the wdt should be restarted if some time has passed ( 10 Hours )... |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Tue Jun 21, 2005 10:01 am |
|
|
Why not attach a GPO pin to MCLR and drive it low to reset the pic? |
|
|
Guest Guest
|
|
Posted: Tue Jun 21, 2005 2:35 pm |
|
|
No, it wont go.. it must be done thru wdt...
Have you some solution how to make this ( after 10 hours )
It should act like the ttelmah sayed accept i have to define some flag and if the flag is 10 hours hit the wdt...
Could this be done on this way? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 21, 2005 3:06 pm |
|
|
Quote: |
but if the stack contains values when you use this, eventually you will get a stack overflow. |
I don't think that's true. The 16F877 data sheet says the stack
is a circular buffer.
Quote: |
The stack operates as a circular buffer. This means that
after the stack has been PUSHed eight times, the ninth
push overwrites the value that was stored from the first
push. The tenth push overwrites the second push (and
so on). |
So it shouldn't matter what the stack pointer is set to, when the
program re-starts. When the program re-starts, it doesn't use
or need any of the previously pushed stack values. It will start
using the stack at whatever location the SP happens to be set to. |
|
|
Ttelmah Guest
|
|
Posted: Wed Jun 22, 2005 2:51 am |
|
|
A good point PCM Programmer. I am so used to always trying to keep 'inside' the stack, and keep things balanced, that it didn't occur to me to check this. However there is a big caveat, if you are using ICD. The ICD system, uses one stack location, and I suspect this would cause silly behaviour if combined with the use of the jump to address zero, with the stack unbalanced...
So the possibilities are:
For normal use, _provided_ your initialisation code makes no assumptions about the initial states of the registers, a 'reset_cpu' instruction should work.
To get a full reset, either add hardware, or use the watchdog.
Best Wishes |
|
|
|