program restarting itself

Thread Starter

Macabra

Joined May 31, 2008
49
Hi, I have a problem in which for some unknown reason, my program resets itself when it is running (after flashing the code into the PIC). I'm using PIC24H. The program works fine, It receives input from user and stores it into a character array. After a while, the program does not do anything with that buffer but the values which were stored in that array just dissappear. It just looks like the program restarts for some reason. I have nothing that would call the main to re-initialize the system.

thanks
 

mik3

Joined Feb 4, 2008
4,843
Also, there is a MCLR pin (pin 13). You have to pull up it to positive supply voltage via a 1K resistor otherwise the pin will float and make arbitrary decisions about its logical state (1 or 0).
 

futz

Joined Dec 14, 2008
23
Also, there is a MCLR pin (pin 13). You have to pull up it to positive supply voltage via a 1K resistor otherwise the pin will float and make arbitrary decisions about its logical state (1 or 0).
1K is pretty low. That's a very strong pullup. Will his programmer be able to overcome it? I'm only asking because I don't really know. :p

I use a 33K, but anything between 10K and 33K is fine.
 

Thread Starter

Macabra

Joined May 31, 2008
49
thanks everyone who replied to me, I really appreciate it.

Futz, I'm turning off the WDT, the code that does this is this:

_FWDT( FWDTEN_OFF & WINDIS_OFF & WDTPOST_PS32768 );

I also put this through one of the functions:
RCONbits.WDTO=0; //watchdog timer time-out flag bit
RCONbits.SWDTEN=0; //disables WDT

Mik3, I do have the MCLR pin pulled to 3.3V with a pull-up resistor :). Thanks for your suggestion.

hgmjr, it's not the first time that I've heard something like this, however, I don't know how to make sure that it is that let alone how to fix that. How can I determine if it is a stack pointer overflow? Since the code goes through a while loop all the time, it makes perfect sense that it could be this.

Thanks everyone for your ideas :)
 

hgmjr

Joined Jan 28, 2005
9,027
The stack lives in ram along with all of the program variables.

Two possible problems can arise with this arrangement.

One source of a stack-pointer overflow is too many nested subroutine calls when C-language is used. Another problem is the number of program ram variables exceeds the portion of memory available and collides with the area of ram allocated to the stack. This over-writes the return from subtroutine pointers that have been stored in stack memory and the program crashes.

In the case of Assembly language, the key is to make sure that the stack pointer is initialized with adequate stack memory capacity. Too many nested subroutine calls can also cause the stack pointer to be incremented passed the end of the stack and then the program execution flow is thrown into chaos. Eventually the program counter execution ends up pointing to the program memory location containing the jump to the start of your program.

hgmjr
 

Thread Starter

Macabra

Joined May 31, 2008
49
thanks

I'm sorry for not mentioning this before, I am using C. I think my function is doing a whole lot of stuff and maybe i need to break it up a bit ..especially since it's got several loops. Something that you mentioned could be the source of the problem :rolleyes:

Thanks again for your help, I'll fix these problems and post here again if I found some problem :)
 

hgmjr

Joined Jan 28, 2005
9,027
Good Luck with your software debugging.

I can't promise anything but if you can attach your source code file, I or one of the other more PIC knowledgeable members might be able to spot a weakness.

hgmjr
 

Thread Starter

Macabra

Joined May 31, 2008
49
ok, I'd reckon it'll be quite an eyesore, but I'll give it a kick..
Here is a cropped out version of the Menu() which is the recursive function.

void Menu(void)
{
if(cellnum[0] == NULL) //checks if character buffer is empty if it is then set flags
{
...
}
//***********CHECKS FOR INPUTS HERE******************//

while(PORTBbits.RB2) //If this input pin gets a high then do this
{
//Goes to some function here
//turns on LEDs
//counter here..for a loop
if(counter == 12) //120 seconds (2 minutes) each text message sent
{
SMS_send('P'); //SEND P to Telit (every 2 minutes)
counter = 0; //resets counter
}
if(PORTBbits.RB2 == 0) //if this pin gets a low signal
{
//Turns off LEDs
SMS_send('D'); //function send to display normal status
Menu(); //exits loop ;refresh screen to show current temperature recursive function here
}
y = inputx(); //HERE looks for user input from a 4x4 keypad
if(y == 'D') //if it's a "D"
{
//turns off LED's and other stuff
Menu(); //Go to Menu function to exit loop; refresh screen
}
}//close while(portBbits.rb2)

if(s == 0)
{
while((PORTAbits.RA0) &&(y!='D')) //if smoke is detected
{
...
... //Here it does the same thing as above, except it checks a different pin
...
}//end while
}//end if(s=0)

if(c == 0)
{
while((PORTAbits.RA1)&&(y!='D')) //Here same thing..it is just checking to see if the pin is "high" and if so then it does the following
{
y = inputx();
if(y == 'D') //breaks out of the while loop when someone presses D on keypad
{
Menu(); //goes to Menu
}
}//end while
}//end if(c == 0)

if(t == 0)
{
while(((_temper > max) || (_temper < min)) && (y!= 'D') && (PORTBbits.RB2 == 0)) //does the same thing ..checks for this input
{
...
...
...
if((PORTBbits.RB2)&&(p == 0)) //checks for this pin and does stuff
{
}
if((PORTAbits.RA0)&&(s == 0)) //checks for this pin
{
}
if((PORTAbits.RA1)&&(c == 0)) //checks for this pin
{
}
}//end while
}//end if (t = 0)

//*********STOPS CHECKING INPUT PINS*****************//

DELAY_US(500);
y = inputx();

switch(y)
{
case '1': phone(); //goes to this function then back to Menu ..this is where inputs are stored in cellnum[].
break;
case '2': temp(); //goes to this then back to Menu
break;
case '3': phonebook(); //goes to this then goes to Menu
break;
case '*': //RESET
{
...
...
...
}
default: //if user didnt press 1,2,3, or * then it just goes to Menu
{
Menu(); //recursive function, return to menu and loops
}
}//End Case Statement
} //END MENU FUNCTION

///////////////////////////////////////////////////////////////////
int main ()
{
init(); // initalize register pins and the UART
initA2D(); // initialize A2D converter
U1STAbits.UTXBF = 1; // sets the TX ON
i2cInit(); // sets the I2C

Menu(); //Here goes to Menu();

return 0;
}//Main

So hopefully, if it was not too much code which was unbearable to look at, the menu loops to itself because on the case statement by default if none of the required buttons are pressed the function calls itself and so the whole thing repeats itself.

I hope that helps, I'm re-organizing it this moment. Much thanks hgmjr and everyone.
 

futz

Joined Dec 14, 2008
23
ok, I'd reckon it'll be quite an eyesore, but I'll give it a kick..
Here is a cropped out version of the Menu() which is the recursive function.
Here's a nice tip for you Macabra. When posting code, always use Code tags. You do this by clicking on the # icon just before pasting your code. Alternately you can type [code] before your code and [/code] after it. This holds the formatting (indentation) on your code so it's still readable after posting.

Here's your code reformatted and posted with tags:
Rich (BB code):
void Menu(void)
{
    if(cellnum[0] == NULL) //checks if character buffer is empty if it is then set flags
    {
        ...
    }
    //***********CHECKS FOR INPUTS HERE******************//

    while(PORTBbits.RB2) //If this input pin gets a high then do this
    {
        //Goes to some function here
        //turns on LEDs
        //counter here..for a loop
        if(counter == 12) //120 seconds (2 minutes) each text message sent
        {
            SMS_send('P'); //SEND P to Telit (every 2 minutes)
            counter = 0; //resets counter
        }
        if(PORTBbits.RB2 == 0) //if this pin gets a low signal
        {
            //Turns off LEDs
            SMS_send('D'); //function send to display normal status
            Menu(); //exits loop ;refresh screen to show current temperature recursive function here
        }
        y = inputx(); //HERE looks for user input from a 4x4 keypad
        if(y == 'D') //if it's a "D"
        {
            //turns off LED's and other stuff
            Menu(); //Go to Menu function to exit loop; refresh screen
        }
    }//close while(portBbits.rb2)

    if(s == 0)
    {
        while((PORTAbits.RA0) &&(y!='D')) //if smoke is detected
        {
            ...
            ... //Here it does the same thing as above, except it checks a different pin
            ...
        }//end while
    }//end if(s=0)

    if(c == 0)
    {
        while((PORTAbits.RA1)&&(y!='D')) //Here same thing..it is just checking to see if the pin is "high" and if so then it does the following
        {
            y = inputx();
            if(y == 'D') //breaks out of the while loop when someone presses D on keypad
            {
                Menu(); //goes to Menu
            }
        }//end while
    }//end if(c == 0)

    if(t == 0)
    {
        while(((_temper > max) || (_temper < min)) && (y!= 'D') && (PORTBbits.RB2 == 0)) //does the same thing ..checks for this input
        {
            ...
            ...
            ...
            if((PORTBbits.RB2)&&(p == 0)) //checks for this pin and does stuff
            {
            }
            if((PORTAbits.RA0)&&(s == 0)) //checks for this pin
            {
            }
            if((PORTAbits.RA1)&&(c == 0)) //checks for this pin
            {
            }
        }//end while
    }//end if (t = 0)

    //*********STOPS CHECKING INPUT PINS*****************//

    DELAY_US(500);
    y = inputx();

    switch(y)
    {
        case '1': phone(); //goes to this function then back to Menu ..this is where inputs are stored in cellnum[].
            break;
        case '2': temp(); //goes to this then back to Menu
            break;
        case '3': phonebook(); //goes to this then goes to Menu
            break;
        case '*': //RESET
        {
            ...
            ...
            ...
        }
        default: //if user didnt press 1,2,3, or * then it just goes to Menu
        {
            Menu(); //recursive function, return to menu and loops
        }
    }//End Case Statement
} //END MENU FUNCTION

///////////////////////////////////////////////////////////////////
int main ()
{
    init(); // initalize register pins and the UART
    initA2D(); // initialize A2D converter
    U1STAbits.UTXBF = 1; // sets the TX ON
    i2cInit(); // sets the I2C

    Menu(); //Here goes to Menu();

    return 0;
}//Main
 

hgmjr

Joined Jan 28, 2005
9,027
The use of recursive functions is a good way to blow through the finite stack size in the microcontroller.

hgmjr
 
Top