EEVblog Electronics Community Forum
Electronics => Microcontrollers => Topic started by: newtekuser on October 16, 2023, 12:10:44 am
-
Hello All,
I am trying to reset my PIC16F887 from software to no avail. Have tried disabling i2c, disabling interrupts and timers, but my MCU hangs when calling the RESET function. What am I doing wrong?
The setup is fairly simple consisting of a 16x2 LCD and DS3231 chip connected to the micro-controller. I also have a push button connected to the external interrupt INT0 pin (RB0).
void reset()
{
INTCONbits.GIE = 0;
PIE1bits.TMR1IE = 0;
INTCONbits.INTE = 0;
INTCONbits.PEIE = 0;
T1CONbits.TMR1CS = 0;
T1CONbits.TMR1ON = 0;
SSPCON &= 0xDF;
RESET();
}
Thanks!
-
IIRC there's no reset instruction in the pic16, so the program actually makes a jump to reset vector, not a good way to reset.
https://onlinedocs.microchip.com/oxy/GUID-BB433107-FD4E-4D28-BB58-9D4A58955B1A-en-US-5/GUID-06B80226-9C00-4067-B659-E0D3760CDA94.html
You could use the WDT for a real reset:
void reset()
{
OPTION_REGbits.PSA = 0; // Make sure the PS prescaler is not used for the WDT
WDTCON=1; // pre = 32, WDT on
while(1); // wait for reset (About 1ms)
}
-
IIRC there's no reset instruction in the pic16, so the program actually makes a jump to reset vector, not a good way to reset.
https://onlinedocs.microchip.com/oxy/GUID-BB433107-FD4E-4D28-BB58-9D4A58955B1A-en-US-5/GUID-06B80226-9C00-4067-B659-E0D3760CDA94.html
To issue a true reset you could configure the WDT for the shortest time and start it (Inside the reset function).
Afterwards stay forever in a while (1); loop until the watchdog resets the device.
That's very clever, many thanks! :-+ I'll try it out.
-
If you switch to the very similar with respect to code enhanced midrange PIC, e.g., 16F1829, you will have a RESET instruction. That might be of use, if for some reason you need to distinguish a WDT reset from something done in code, e.g., user initiated reset.
-
You can still detected the reset reason in the 887 (Brown-out, WDT, etc).
-
Now I arrived home I could check what RESET() actually does. It's defined in xc8debug.h :
#if defined(_PIC14E) || defined(_PIC14EX) || defined(_PIC18)
#define RESET() asm("reset")
#else
#define RESET() asm("ljmp $")
#endif
asm("ljmp $") jumps to current PC address, basically a while(1);, that explains why it was hanging.
Maybe it was expecting the WDT to be active? Meh, just don't use it in PIC16! ::)