I dont think its related to MCLR or the configuration bits but it is related to the compiler or the code itself. If you import the hex file into MPLAB and then have a look at the program memory, you will find a few odd things. Below is a disassembly listing of the relevant parts of the memory:
000 BSF STATUS, RP0 ; Select Bank 1
001 CALL 0x3FF ; Call to last memory cell to get oscillator calibration
002 MOVWF T1CON ; Save to oscillator
003 BCF STATUS, RP0 ; Bank 0
004 GOTO 0x3F6
005 ADDLW 0xFF (Empty memory)
...
3F6 CLRF STATUS
3F7 GOTO 0x3F8 ;
Same as 2xNOP
3F8 MOVLW 0xFD ; Load WREG with 0XFD = 0b11111101
3F9 BSF STATUS, RP0 ; Bank 1
3FA MOVWF GPIO ; Load WREG to TRIS
3FB BCF STATUS, RP0 ; Bank 0
3FC BSF GPIO, 1 ; Make GPIO1 go high
3FD GOTO 3FD ; Loop forever
3FE GOTO 0 ; Goto address 0
3FF ADDLW 0xFF ; Should be RETLW 0x**, (calibration value)
If the programmer erases all the memory, including the last word containing the calibration value, before programming, then the program will hang forever. From reset at 0x3FF, roll over to 000 and then perform a call to 3FF. As there is no return or retlw there, the program counter will roll over to 000 again and then make a new call 3FF and so on. Eventually the built in return stack will only be pushed but never popped. On a PIC18, that would have caused a stack overflow reset.
Possible workaround? Add an assembler instruction at address 0x3FF with a RETLW and some value. Here is how I got it to work:
1. Add a function prototype before the void main line
void MyOscCal(void);
2. Inside main, but after the while(1) loop, add a call to function MyOscCal
void main()
{
while(1)
{....
}
MyOscCal();
}
3. Create a function located at 0x3FF containing just one single RETLW instruction
void MyOscCal(void) @ 0x3FF
{
asm("retlw 0x80"); // Change 0x80 to something else if the oscillator is way off
}
On the other hand I think the generated assembly code is missing a lot compared to the C code you attached. Here are some examples:
TRISIO = ... is totally off with the wrong value
The while loop is completely absent
The missing while loop is very strange and I managed to get the same result with:
while(1)
{
i++;
}
The complete while loop was missing and I got a message about that i was never used.