If you don't want to use a power managed mode with peripherals clocked during sleep, use an external 32,768 watch crystal for Timer1.
If you don't want to use a power managed mode with peripherals clocked during sleep, use an external 32,768 watch crystal for Timer1.
Thanks for your help Bruce - it has clarified my (mis)understanding - looks like an external Xtal for Timer 1 is the way to go.
BTW in case anyone is mislead by:
into thinking Timer0 could be used to wake the 18F4550 from sleep, I noticed this in the datasheet:Also Timer1/Timer0 will only operate from the internal clock during sleep if you're using a power managed mode that clocks peripherals while the CPU sleeps
I would have preferred to use timer0 for my clock as I could get that down to 1 Hz with its 1:256 prescaler otherwise . I suppose this is probably also true of Timer1 (without external Xtal) and should have given me the answer Bruce so clearly gave!Since Timer0 is shut down in Sleep mode, the TMR0 interrupt cannot awaken the processor from Sleep.
Peter
Sleep & Power managed modes can be a little confusing.
With IDLEN = 0 the SLEEP instruction shuts down everything except for the watchdog timer if it's enabled. This stops all internal clocks by stopping the main oscillator. The internal 31kHz that the WDT uses is still operating so the WDT can timeout and wake it from sleep.
PRI_RUN, SEC_RUN, and RC_RUN are the only 3 modes that don't require execution of the SLEEP command to enter.
These are selected by changing bits in the OSCCON register. These modes let you change the oscillator. SEC_RUN would switch to the oscillator on Timer1.
This keeps everything running, but on the lower power osc that's connected to the Timer1 osc pins.
RC_RUN switches to the internal RC oscillator. Both can consume less power than most external crystals. PRI_RUN operates from whatever oscillator you have selected in config.
The IDLE modes PRI_IDLE, SEC_IDLE, and RC_IDLE are entered by setting the IDLEN bit, then selecting the oscillator with OSCCON bits 1,0 then executing the SLEEP instruction. If you already have the oscillator selected for the idle mode you want, then just setting IDLEN before executing the SLEEP instruction is all that's required.
IDLE modes just put the CPU to sleep, but keep clocks available for all peripherals.
SEC_IDLE or RC_IDLE would normally be the lowest power options. It would run all peripherals from the LP oscillator on Timer1, or the internal RC oscillator "set for 31kHz".
Look in the Electrical Characteristics section of the datasheet under Power-Down and Supply Current for various modes & power consumption.
The key is the IDLEN bit. When this bit is clear, it doesn't matter what oscillator or mode is selected. The execution of a SLEEP instruction will shut everything down except for the WDT if enabled.
When the IDLEN bit is set, and the SLEEP instruction is executed, then it enters one of the 3 IDLE modes with the CPU shut down, and peripheral clocks provided by whatever osc you have selected in OSCCON bits 1,0.
Last edited by Bruce; - 21st August 2010 at 16:03.
Thanks for all your help Bruce - this is a followup to report that an external 32 KHz crystal and two 33 pF caps have sorted my sleep problems - for the record this works a dream:
with a TMR1 interrupt (RTCupdate) of:Code:T1CON = %00001110
and a sleep inducing routine of:Code:asm TMR1Const = 8000h ADD2_TMR1 macro BCF T1CON,TMR1ON, 0 ; Timer OFF MOVLW LOW(TMR1Const) ; +1 ADDWF TMR1L,F, 0 ; +1 BTFSC STATUS,C ; +1/2 INCF TMR1H,F, 0 ; +1 MOVLW HIGH(TMR1Const) ; +1 ADDWF TMR1H,F, 0 ; +1 endm RELOAD_TMR1 macro ADD2_TMR1 BSF T1CON,TMR1ON, 0 ; +1=7 cycles overhead before Timer ON endm LOAD_TMR1 macro MOVE?CT 0, T1CON,TMR1ON MOVE?CB 0, TMR1L MOVE?CB 0, TMR1H ADD2_TMR1 endm endasm RTCupdate: @ RELOAD_TMR1 Seconds = Seconds + 1 dSecs = 1 if (Seconds < 60) then IHdone Minutes = Minutes + 1 Seconds = 0 if (Minutes < 60) then IHdone Hours = Hours + 1 Minutes = 0 if (Hours < 24) then IHdone Days = Days + 1 Hours = 0 IHdone: 'Restore context and RETFIE @ INT_RETURN
PeterCode:gosleep: lcdout $FE, $C0, "USB LP, SLEEP " T0CON.7 = 0 ' Disable USBservice interrupts @ INT_DISABLE TMR0_INT @ clrf UCON ; Disable USB & detach from bus @ clrf UIE ; Mask all USB interrupts lowpower: IF dSecs = 1 THEN dSecs = 0 lcdout $FE, $02, "Time ", dec2 Hours, ":", dec2 Minutes, ":", dec2 Seconds, " " ENDIF OSCCON.7 = 0 'Clear IDLEN - switch to SLEEP @ SLEEP @ NOP goto lowpower
Since our production circuit board has been professionally produced, there is not room for an extra Xtal and caps to drive TMR1 so I am trying to get the WDT to do the wake from sleep but with only partial success. In particular it doesnt seem to matter what I put as a postscaler value the WDT seems to cycle at a fixed period of around 578 mSec (suspiciously similar to Nap 5 frequency!). I am setting CONFIG2H by using this instead of the corresponding (commented out) line in 18F4550.INC:
and then:Code:asm __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_256_2H ;must comment out in 18F4550.INC, or change there, else duplicate error endasm
and i increments 128 in 74 secs (period = 578mSec), but different values of _WDTPS_1024_2H etc. make no difference. What am I missing here? It makes no difference whether I make the CPU sleep or idle (except to the current consumption 3 or 15 mA - most of the 3 lost in the 9v voltage regulator).Code:i = 0 lowpower: lcdout $FE, $02, "WDT ", hex2 i, i = i + 1 ' Do all the other stuff here (read ADC, store to Mem) clearwdt WDTCON = 1 'SWDTEN ' OSCCON.7 = 0 'Clear IDLEN - switch to SLEEP OSCCON.7 = 1 'Set IDLEN - switch to SEC_IDLE @ SLEEP @ NOP WDTCON = 0 ' WDT off goto lowpower
DEFINE NO_CLRWDT 1 makes no difference and the CLEARWDT also seems to make no difference!
I would like to have the ability to control the frequency as expected and am thinking I can sleep for most of the 1 second I want and fine tune with another timer while awake - PAUSE would be the simplest. Any ideas gratefully received!
Peter
PS It just occurs to me that I am using a Bootloader - could this mean that the Postscaler is set by the bootloader and not changed by my program - if so can I do anything to change this ??edit the bootloader somehow.
Last edited by FinchPJ; - 25th August 2010 at 21:36. Reason: Postscript
Most bootloaders will not allow you to change config settings, but the Microchip USB loader will, or you can change WDT config settings at runtime.
See these threads:
http://www.picbasic.co.uk/forum/showthread.php?t=4093
http://www.picbasic.co.uk/forum/show...ghlight=config
Or just open the loader .HEX file, make your changes, save it, and reprogram the PIC with the new loader firmware.
Last edited by Bruce; - 26th August 2010 at 19:09.
Bookmarks