View previous topic :: View next topic |
Author |
Message |
aefelgate Guest
|
PIC18F2520 IDLE mode current consumption |
Posted: Tue Jul 17, 2007 1:56 pm |
|
|
All,
I cannot eliminate an extra 300 microamps of current consumption when putting the PIC18F2520 into IDLE mode.
In IDLE mode, using the internal oscillator at 31KHz, and operating my chip at +5 V I measure 348 microamps; if I simply change one line in my program to go into sleep mode, rather than IDLE, the current drops to 33 microamps. I played around with my output pin setting to get the low sleep mode current consumption, so I don't believe the current is being drawn external to the PIC via one of the port pins. I think there must be some additiional peripheral internal to the PIC that operates in IDLE mode, but gets turned OFF in sleep mode.
Here is my FUSE setting:
#FUSES INTRC_IO,NOWDT,NOLVP,NOPROTECT,NOBROWNOUT
#USE DELAY(CLOCK=31250)
The following is my initialization sequence. Calling sleep() the current measured is 33 microamps; calling a function to put the chip in IDLE mode results in 348 microamps being consumed. I believe I have all the chips peripherals turned off (I did this one at a time, with no change in the IDLE mode current).
Any ideas/thoughts?
Art
void main()
{
// setup_uart( 0 );
disable_interrupts( INT_RDA );
disable_interrupts( GLOBAL );
// Set the direction for the I/O ports.
set_tris_a( 0B00001011 );
set_tris_b( 0B00000000 );
set_tris_c( 0B00000000 );
port_b_pullups(FALSE);
// Output a low on unused I/O pins to conserve power:
output_low(PIN_A6);
output_low(PIN_A7);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
output_low(PIN_C0);
output_low(PIN_C1);
output_low(PIN_C2);
output_low(PIN_C5);
output_low(PIN_C6);
output_high(PIN_C7);
setup_adc_ports(AN0_TO_AN1);
setup_adc( ADC_OFF );
set_timer1( g_nTimer1Value );
setup_timer_1( T1_DISABLED );
setup_wdt(WDT_OFF); |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jul 17, 2007 2:15 pm |
|
|
Quote: | calling a function to put the chip in IDLE mode results in 348 microamps being consumed
| Post this function.
The data sheet tells how to enter the Idle mode. I don't where in
your code that you're doing this:
Quote: | 3.4.3 RC_IDLE MODE
In RC_IDLE mode, the CPU is disabled but the periph-erals
continue to be clocked from the internal oscillator
block using the INTOSC multiplexer. This mode allows
for controllable power conservation during Idle periods.
cleared.
From RC_RUN, this mode is entered by setting the
IDLEN bit and executing a SLEEP instruction. If the
device is in another Run mode, first set IDLEN, then set
the SCS1 bit and execute SLEEP. Although its value is
ignored, it is recommended that SCS0 also be cleared;
this is to maintain software compatibility with future
devices. |
|
|
|
aefelgate Guest
|
|
Posted: Tue Jul 17, 2007 2:34 pm |
|
|
Here is my call to the function to shift the chip to IDLE mode (also, you can see where I simply commented out the alternate call to go to sleep mode, instead).
// When not using the modem shift down to
// slower IDLE speed to conserve power:
shift_speed( SPEED_IDLE );
// sleep();
delay_cycles( 1 );
Here is the shift mode function:
//==========================================================================
void shift_speed(unsigned speed)
{
if (SPEED_IDLE == speed)
{
// Configure device to run in Slow IDLE speed (turn OFF CPU)
// Now SET the IDLE bit
setup_oscillator( OSC_31KHZ | OSC_NORMAL | OSC_IDLE_MODE | OSC_31250 );
// Must execute a SLEEP to enter IDLE mode
sleep();
}
else if (SPEED_RUN == speed)
{
// Configure device to run at FAST Running speed (CPU On)
setup_oscillator( OSC_1MHZ | OSC_INTRC );
#USE DELAY(CLOCK=1000000, RESTART_WDT)
g_nTimer1Value = 0xf63b;
}
} |
|
|
Bill Boucher
Joined: 04 Feb 2005 Posts: 34 Location: Chatham,ON,CA
|
|
Posted: Tue Jul 17, 2007 5:59 pm |
|
|
Just a possibly dumb thought here (pardon me, I didn't go read the datasheet) but if in idle mode the internal clock remains running, wouldn't that draw some power? I wonder if that clock keeps running even when some or all peripherals are shut off. |
|
|
aefelgate Guest
|
|
Posted: Wed Jul 18, 2007 9:19 am |
|
|
Bill,
Yes, the clock does keep running to pace the internal peripherals. However, the data sheet specifies that I should be able to run the chip in IDLE mode with just Timer 1 and the watchdog timer at < 100 uA, easily. There must be some peripheral running inside the chip.
Any help from the CCS folks about their compiler? I am using version 4.012. Does it automatically turn on some of the internal peripherals?
As I said, if I change the call to the shift_speed function to a sleep, instead (NOT setting the IDLE bit), and rely upon the watchdog timeout to wake up the chip only draws 33 microamps. This to me indicates that the I/O ports are not drawing power, unless the state of these pins changes in sleep mode versus IDLE mode.
CCS folks/moderator: Can you answer this question?
Should I just blindly turn off every peripheral I can think of (not a very good solution)?
Thanks,
Art |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed Jul 18, 2007 11:57 am |
|
|
Quote: | I am using version 4.012. | For me support stops there.
Check the v4 sticky thread in the top of this forum. v4.012 is one of the very first v4.0xx _beta_ releases and very unreliable. We are now at v4.044, a whopping 32 releases newer. Things are getting better but officially it is still a beta version. V3.249 is the last stable release. |
|
|
aefelgate Guest
|
CCS Compiler Wizard confirms high IDLE mode current |
Posted: Wed Jul 18, 2007 1:59 pm |
|
|
I used the CCS Project Wizard to generate header and initialization code. I get pretty much the exact same result:
<50> 500 microamps using the internal oscillator.
It appears the CCS compiler version 4.012 is NOT correctly putting the PIC18F2520 into IDLE mode at the specified frequency, even when using the Project Wizard to generate the code.
Has anyone been able to run the 18F in IDLE mode at < 100 microamps? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 18, 2007 2:02 pm |
|
|
Use the CCS #byte directive to declare the address of the OSCCON
register and any other relevant registers. Then write directly to the
registers to setup the correct mode. Do this instead of using the
CCS function. |
|
|
|