PIC24FJ Sleeping for duration controlled by software

Thread Starter

Robin66

Joined Jan 5, 2016
281
Hi. I'm in the process of converting on of my projects from a PIC16F18323 to a PIC24FJ64GA705 and some functionality seems to have dropped out. Whereas for the PIC16F I could control the sleep period like so...
Code:
        if(armStage==INIT)
            WDTCONbits.WDTPS   = 0b10000;  // if we've just turned on the MOTIONMODULE, sleep for 1 minute
        else if(isAlerting)
            WDTCONbits.WDTPS   = 0b01000; // try again quickly
        else
            WDTCONbits.WDTPS   = 0b01100;   // 4s: short period

        WDTCONbits.SWDTEN  = 1; // enable
        SLEEP();
        WDTCONbits.SWDTEN = 0; // disable
...for the PIC24FJ the config bits that control the WDT period are not accessible during run-time.

Code:
FWDTbits.WDTPS = 0x9; // 2^9   * 4ms = 2 secs

C:/Users/Robin/MPLABXProjects/SensorSirenPIC24F.X/main.c:538:13: error: 'FWDTbits' undeclared (first use in this function)
Is there a way to achieve sleep (for power saving purposes) for a desired period in the PIC24FJ family? I could use the config bits to set the WDT period to 1sec and sleep in a loop multiple times but this seems like a fudge and I expect there's a better way to do what I want.
 

Picbuster

Joined Dec 2, 2013
1,057
What I normal do;
a: use timer1 with xtal 32768Khz. This timer/counter will always run when PIC is in sleep mode. ( it might run from internal osc see manual)
b:set wake-up counter to zero and put pic in sleep.
the pic wakes up when an overflow occurs. ( see trm1 settings).

Picbuster
 

Thread Starter

Robin66

Joined Jan 5, 2016
281
Ah right ok. I'm not using a rtc crystal but I can point a spare timer to the onchip LPRC (31kHz) and enable the interrupt on that timer thus waking the PIC from sleep whenever I like provided the WDT is set to Inf (or as close as I can get).
 

Thread Starter

Robin66

Joined Jan 5, 2016
281
Unfortunately I couldn't get this to work. I pointed timer2 to the LPRC (31kHz) and demonstrated that it was interrupting at 1Hz when I set PR2 to 121 with a 1:128 prescaler (121*128*2 = 31kHz)

Code:
    // set T2 with 1sec tick.  Use as WD Timer
    T2CONbits.TCS   = 1; // specify clock source
    T2CONbits.TECS  = 0b10; // LPRC: 31kHz
    T2CONbits.TCKPS = 3; // 1:128 prescale, tf 121Hz tick. 1 tick = 4ms, max delay = 542secs (9 mins)
Code:
void __attribute__((__interrupt__, auto_psv )) _ISR _T2Interrupt (void)
{
    _T2IF = 0;
    LED^= 1;
}
the further down...
Code:
            short sleepSec = 10;
            TMR2    = 0;
            // test code
            T2CONbits.TON   = 1;
            PR2             = 121;
            __delay_ms(5000);
However when I put the device to sleep with WDT enabled to ensure LPRC continued to run the device sleep for the full WDT duration. My conclusion is that LPRC is running (because it does eventually wake) but Timer2 has been turned off despite what it says in the datasheet
Code:
            RCONbits.SWDTEN = 1; // enable WD, required to keep LPRC active
            __delay_ms(1);
            Sleep();
            RCONbits.SWDTEN = 0; // disable WD
            T2CONbits.TON = 0;
 
Top