Log in

View Full Version : PIC18F4550 rebooting



RubenR
- 26th September 2005, 17:20
Hello,

I'm trying to write a program that checks for a timeout. When there is no timeout the program has to return to the place it came from. No problems so far when I use a PIC16F877A. Now I compiled the program for PIC18F4550. It looks to work fine, but after 28 timeouts the processor resets. I guess there is somthing wrong with the settings in the include file. I use Microchip ICD2 programmer and MPLAB v7.11.


This is the include file I use:

NOLIST
ifdef PM_USED
LIST
"Error: PM does not support this device. Use MPASM."
NOLIST
else
LIST
LIST p = 18F4550, r = dec, w = -311, f = inhx32
INCLUDE "P18F4550.INC" ; MPASM Header
;20MHZ
__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L

;HS
__CONFIG _CONFIG1H, _FOSC_HS_1H
__CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
__CONFIG _CONFIG3H, _PBADEN_OFF_3H
__CONFIG _CONFIG4L, _LVP_OFF_4L & _ICPRT_OFF_4L & _XINST_OFF_4L
NOLIST
endif
LIST
EEPROM_START EQU 0F00000h
BLOCK_SIZE EQU 32

Darrel Taylor
- 26th September 2005, 22:25
It sounds like the Stack is overflowing.

If the Timeout is being detected inside a subroutine. Make sure that it doesn't GOTO somewhere outside the subroutine.

Preferably, it should goto a label just before the RETURN for that routine. Or, just return directly from that spot.

Or, you can GOTO another routine to handle the timeout, ONLY IF that routine has a RETURN at the end

Bruce explained how it can work on a 16F and not on an 18F in this post
http://www.picbasic.co.uk/forum/showthread.php?p=2686#post2686
<br>

RubenR
- 27th September 2005, 08:49
Thanks for the help so far.
I disabled the stack overflow reset and indeed the program stops working after 28 times. It looks like a stack overflow to me. This is the code I used:

How could I change it, so it works on an 18F?

Include "modedefs.bas"

DEFINE OSC 20 ' Set Xtal freq.

DEFINE DEBUG_REG PORTD ' Set Debug pin port
DEFINE DEBUG_BIT 4 ' Set Debug pin bit
DEFINE DEBUG_BAUD 9600 ' Set Debug baud rate
DEFINE DEBUG_MODE 1 ' Set Debug mode: 0 = true, 1 = inverted

Timeout VAR BYTE
Pushbutton VAR BYTE


Startup:
DEBUG 10,13,10,13," !!! Startup !!!!",13,10,13,10
goto Main

Main:
Pushbutton = 1 ' Usually 'Pushbutton' is an input-pin
IF Pushbutton = 1 THEN
GOTO FunctionD ' If the pushbutton is pushed execute FunctionD
ENDIF
GOTO Main

FunctionD:
GOSUB Timeout2
DEBUG "Function D",10,13
' Execute some function
GOTO FunctionD

Timeout2:
PAUSE 100
Timeout = Timeout + 1
IF Timeout > 4 THEN
DEBUG 10,13,"Timeout",10,13
Timeout = 0
GOTO Main ' Timeout occured -> go back to Main
ENDIF
RETURN

END

RubenR
- 27th September 2005, 09:19
Little code change and it seems to work fine now! The golden rule is:*
Calling a subroutine using GOSUB and jumping out of that subroutine using GOTO before the end (RETURN) of the subroutine is reached will cause a stack overflow.

* Thanks to Ralph!

Include "modedefs.bas"

DEFINE OSC 20 ' Set Xtal freq.

DEFINE DEBUG_REG PORTD ' Set Debug pin port
DEFINE DEBUG_BIT 4 ' Set Debug pin bit
DEFINE DEBUG_BAUD 9600 ' Set Debug baud rate
DEFINE DEBUG_MODE 1 ' Set Debug mode: 0 = true, 1 = inverted

Timeout VAR BYTE
Pushbutton VAR BYTE
Exit Var bit


Startup:
DEBUg 10,13,10,13," !!! Startup !!!!",13,10,13,10
goto Main

Main:
Pushbutton = 1 ' Usually 'Pushbutton' is an input-pin
Exit = 0
If Pushbutton = 1 THEN
goto FunctionD ' If the pushbutton is pushed execute FunctionD
ENDIF
Goto Main

FunctionD:
GOSUB Timeout2
If Exit = 1 then
GOTO Main
ENDIF
DEBUG "Function D",10,13
' Execute some function
Goto FunctionD

Timeout2:
Pause 100
Timeout = Timeout + 1
if Timeout > 4 then
DEBUG 10,13,"Timeout",10,13
Timeout = 0
Exit = 1
ENDIF
RETURN

NavMicroSystems
- 27th September 2005, 11:19
The golden rule is:*
Calling a subroutine using GOSUB and jumping out of that subroutine using GOTO before the end (RETURN) of the subroutine is reached will cause a stack overflow.

* Thanks to Ralph!

RETURN

And thanks to Bruce!