View previous topic :: View next topic |
Author |
Message |
arrow
Joined: 17 May 2005 Posts: 213
|
Peculiar restart from the beginning? |
Posted: Wed Aug 02, 2006 10:08 am |
|
|
Hi
I am new to the 18 series PICs- I am using the 18F4550.
What happens once the program finishes executing, is that it starts from the top. In fact every time it sees a "return" it starts from the top.
Can someone please tell me what I am doing wrong. (I have not encountered this type of problem before).
My code looks something like this:
Code: |
void main(){
//some stuff
if(i<20){
....
return;
}
....
....
sleep();
return;
}
|
I feel really stupid asking this question.
Thank you in advance.
a. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 02, 2006 10:37 am |
|
|
Have you ever seen any code on this forum where people stick 'return'
statements in the middle of main() ? |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Aug 02, 2006 10:53 am |
|
|
Thinking it otherwise, the program is running in the main body... if return... to where?
it does not even have any sense from the point of view of the flow of the program.
Humberto |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Aug 02, 2006 11:13 am |
|
|
Think of the statement 'return' as if you are going to 'return' from a sub routine and go back to the main body.
Last edited by rnielsen on Wed Aug 02, 2006 11:15 am; edited 1 time in total |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Aug 02, 2006 11:15 am |
|
|
I think what they're trying to tell you is that you are using RETURN incorrectly. RETURN is used to return a value from a function. For instance:
Code: |
int8 my_function(int8 passed_value) {
int8 returned_value = 0;
returned_value = passed_value * 10;
RETURN(returned_value);
} |
I would be willing to bet that your improper usage is generating garbage when you compile. The pros may even know what the ramifications are of your improper usage.
Lookup RETURN in a good C referrence and try to figure out how to use it correctly. That should solve your problem... or at least remove one known problem.
John |
|
|
Guest
|
|
Posted: Wed Aug 02, 2006 2:28 pm |
|
|
Humberto wrote: | Thinking it otherwise, the program is running in the main body... if return... to where?
it does not even have any sense from the point of view of the flow of the program.
Humberto |
I'm not sure I agree. If the program just ended, you know, last line, all done, finished, where does it go? It RETURNS to it's "caller". For example, calling a program from a shell, the RETURN would return control to the shell because the program is done. So inserting a RETURN within main makes complete sense.
A RETURN statement performs the same routine shutdown "stuff" as a routine ending naturally.
Now the question about a routine having more then 1 return in its body....
~Kam (^8* |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Aug 02, 2006 3:26 pm |
|
|
Quote: |
I'm not sure I agree. If the program just ended, you know, last line,
all done, finished, where does it go? It RETURNS to it's "caller".
For example, calling a program from a shell, the RETURN would return
control to the shell because the program is done. So inserting a RETURN
within main makes complete sense. |
Do you believe that a CCS PIC program has a "shell" to return to ?
Quote: |
A RETURN statement performs the same routine shutdown "stuff" as a
routine ending naturally. |
Do you believe that a 'return' statement performs routine shutdown
stuff if you place it at the end of main() in a CCS program ?
Look at the .LST file to see what it does. |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Wed Aug 02, 2006 11:19 pm |
|
|
Hi
Thank you for all your explanations.
I have a different question then:
If I would like the program to stop within the "if loop" how do I do that?
Should I use a "goto" statement?
What is the equivalent to "abort(5)" in PIC C?
Will "sleep()" do?
Regards
a. |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Aug 03, 2006 1:20 am |
|
|
Hi
I have now removed the "return" in main
and I still have the program restart after it completes.
I have traced the problem to the line:
Code: | disable_interrupts( GLOBAL ); |
which is close to the end of the program.
I wanted to disable all interrupts in one line.
If I remove this line, and disable the individual interrupts, eg
Code: | disable_interrupts( INT_TIMER2); |
then the whole problem goes away, and I do not restart from the beginning upon completion.
Can someone please tell me if this makes sense?
Thank you for all your help.
Regards
a. |
|
|
Ttelmah Guest
|
|
Posted: Thu Aug 03, 2006 3:05 am |
|
|
There is a very important 'understanding' thing, that needs to be made here. If you write a program in any language, that runs under an 'OS', then when the program is complete, you can 'return' from this program, or in most cases, simply 'run off the end', and the code will go back to the calling OS, and this will once more take control of the computer. However if you write a _standalone_ program (which is what you are doing on the PIC), _you_ have the responsibility to handle everything. The code sequence must never 'leave' your program, or unexplained things will happen. This is what is being pointed out in various ways by the posters. Now a couple of examples may help:
Code: |
void main(void) {
printf("This is a test/n");
}
|
This is an almost 'classic' failure on a PIC. The 'reason', is that if you use the hardware UART, when the code finishes, there are still characters in the hardware buffer, waiting to send. The program drops 'off the end', goes to sleep, and these characters get lost...
Code: |
void inner_loop(void) {
//some stuff
if(i<20){
....
return;
}
....
....
sleep();
return;
}
void main(void) {
while (TRUE) {
inner_loop();
printf("Fallen through\n");
delay_ms(100);
}
}
|
Now this shows (using your example), how to organise things to use 'return' on the PIC. _You_ provide a 'body' function, which replaces the 'OS', call your function, and then handle the possible types of return (if applicable) in your main function.
'Disable_interrupts(GLOBAL)', _will_ disable the interrupt operation fine. The fact that this affects things, suggests that something much more major is going on. I'd suspect, that you possibly have the hardware watchdog enabled, are resetting the watchdog in an interrupt routine, and hence when you stop doing this, the processor resets...
Best Wishes |
|
|
arrow
Joined: 17 May 2005 Posts: 213
|
|
Posted: Thu Aug 03, 2006 3:40 am |
|
|
Hi Ttelmah
Thank you- you have explained it very well.
I have NOWDT in the #fuses.
Can it be the Watch dog still?
It does work if I just disable the particular interrupts (but not the GLOBAL one).
In order to stop the PIC within an "if" loop, can I use sleep()?
Or is there a better way of doing it (I dont want to use "goto end" as I am currently doing, if possible).
Regards
a. |
|
|
|