reset.c - Demonstrates software reset, idle, sleep, watchdog timer operationΒΆ
Program that tests some of the ways that a PIC24 can be reset, as well as sleep mode, idle mode, and the watchdog timer. Intended to be used in a laboratory exercise in which the current draw of the processor is monitored before/after the power down modes.
#include "pic24_all.h"
/** This function puts the PIC24 in low-power mode by:
* - Configuring all digital I/O pins as inputs
* - Configuring all analog I/O pins shared with
* digital I/O pins to be digital only
* - Enables pullups on all pins not used by the
* oscillator.
*
* WARNING: if pullups are enabled on pins used by
* the oscillator, the clock typically stops running.
* Currently, this code works for demo purposes with
* the FRC oscillator when used in the reset.c program.
*/
//this function is processor specific
#if (defined(__PIC24HJ32GP202__))
void configPinsForLowPower(void) {
Configure all digital I/O pins for input.
TRISB = 0xFFFF;
TRISA = 0xFFFF;
AD1PCFGL = 0xFFFF;
The primary oscillator is not used, so turn on all the pull-ups.
CNPU2 = 0xFFFF;
The secondary osciallator is not used, so turn on all the pull-ups.
CNPU1 = 0xFFFF;
}
#else
# warning "Using dummy function for configPinsForLowPower() in common/pic24_util.c."
void configPinsForLowPower(void) {
}
#endif
uint8_t printMenuGetChoice() {
uint8_t u8_c;
outString("'1' enable watchdog timer\n");
outString("'2' enter sleep mode\n");
outString("'3' enter idle mode\n");
outString("'4' enable watchdog timer and enter sleep mode\n");
outString("'5' doze = divide by 2\n");
outString("'6' doze = divide by 128\n");
outString("'7' execute reset instruction\n");
outString("Choice: ");
u8_c = inChar();
outChar(u8_c); //echo character
outString("\n"); //newline
return(u8_c);
}
//persistent variables are not touched at reset
_PERSISTENT uint8_t u8_resetCount;
int main(void) {
configClock(); //clock configuration
configPinsForLowPower(); //config pins for low power since we are measuring current
configHeartbeat(); //heartbeat LED
configDefaultUART(DEFAULT_BAUDRATE); //serial port config
outString(HELLO_MSG); //say Hello!
if (_POR) {
u8_resetCount = 0; // if power on reset, init the reset count variable
} else {
u8_resetCount++; //keep track of the number of non-power on resets
}
if (_WDTO) {
_SWDTEN = 0; //If Watchdog timeout, disable WDT.
}
printResetCause(); //print statement about what caused reset
//print the reset count
outString("The reset count is ");
outUint8(u8_resetCount);
outString("\n");
while (1) {
uint8_t u8_c;
u8_c = printMenuGetChoice();
DELAY_MS(1); //let characters clear the UART before executing choice
switch (u8_c) {
case '1': //enable watchdog timer
_SWDTEN = 1; //WDT ENable bit = 1
break;
case '2': //sleep mode
asm("pwrsav #0"); //sleep
outString("after sleep\n"); //never executed.
break;
case '3': //idle mode
asm("pwrsav #1"); //idle
outString("after idle\n"); //never executed.
break;
case '4':
_SWDTEN = 1; //WDT ENable bit = 1
asm("pwrsav #0"); //sleep
outString("after WDT enable, sleep.\n"); //executed on wakeup
break;
case '5':
_DOZE = 1; //chose divide by 2
_DOZEN = 1; //enable doze mode
break;
case '6':
_DOZE = 7; //chose divide by 128
_DOZEN = 1; //enable doze mode
break;
case '7':
asm("reset"); //reset myself
break;
default:
break; //ignore
}
} // end while (1)
return 0;
}