This is a common issue encountered. Some settings I have used for STOP2 mode. You may also want to set up Low Voltage detection and only enable peripheral clocks that are needed. Also use RTC to periodically kick out of stop/wait mode.
// Watchdog disabled. Stop Mode Enable. Background Pin enable. RESET pin enable
SOPT1 = SOPT1_BKGDPE_MASK | SOPT1_STOPE_MASK;
SPMSC2 = SPMSC2_LPWUI_MASK | SPMSC2_PPDE_MASK ;
INTC_WCR = 0x80; // needed to wake from stop mode
// interrupt (not reset) with errors
SPMSC1 = 0;
and depending on other needs you may want to set CPUCR
// ISR vectors not in FLASH, moved to RAM
asm ( move.l #0xD2000000, D0)
asm ( movec D0, CPUCR)
Also deriviatives.h file:
/*
* Note: This file is recreated by the project wizard whenever the MCU is
* changed and should not be edited by hand
*/
/* Include the derivative-specific header file */
#include <MCF51QE128.h>
#include <hidef.h>
#define _Stop asm ( mov3q #4,d0; bclr.b d0,SOPT1; stop #0x2000; )
/*!< Macro to enter stop modes, STOPE bit in SOPT1 register must be set prior to executing this macro */
#define _Wait asm ( mov3q #4,d0; bset.b d0,SOPT1; nop; stop #0x2000; )
/*!< Macro to enter wait mode */
We also use the RTC as a timer tic to exit STOP2 or WAIT modes:
void krnl_init_rtc(bool slow)
{
SCGC2_RTC = 1;
// use 1kHZ LPO
// RTIF[7], RTCLKS[6:5], RTIE[4], RTCPS[3:0}
// RTCLKS[6:5] = 01 = external 38.4KHz oscillator
// RTCLKS[6:5] = 00 = internal 1KHz LPO
// RTIE[4] = 1
// RTCPS[3:0] = 1000 = Div 1 prescaler for internal LPO
if (slow)
{
RTCSC = 0x1F; // 1 kHZ LPO clock, interrupt enable, divide by 1000
}
else
{
#if RTC_TIC_RATE_MS == 1
RTCSC = 0x18; // 1 kHZ LPO clock, interrupt enable, divide by 1
#elif RTC_TIC_RATE_MS == 2
RTCSC = 0x19; // 1 kHZ LPO clock, interrupt enable, divide by 2
#elif RTC_TIC_RATE_MS == 4
RTCSC = 0x1A; // 1 kHZ LPO clock, interrupt enable, divide by 4
#elif RTC_TIC_RATE_MS == 10
RTCSC = 0x1B; // 1 kHZ LPO clock, interrupt enable, divide by 10
#else
#error invalid RTC scale factor
#endif
}
// Note: the mod register = 0 is correct for 1mSec timer.
RTCMOD = 0x00; // RTCMOD == 0 configures to interrupt every ~1ms
}
interrupt VectorNumber_Vrtc void Real_Time_ISR(void)
{
RTCSC_RTIF = 1; // Clear the RTC flag
systemTimeMs += RTC_TIC_RATE_MS;
//...
}