5
\$\begingroup\$

Currently my datalogger is running at 12Mhz, and sleeps 90% of the time. When it's active its mostly blocked by I/O like SD-card or UART.

I suspect the system would still work at 6 Mhz, but how do you know whats reasonable? I can decrease the clock untill weird bugs starting to occur, but that seems too fuzzy. I can count all assembly instructions and calculate the value, but thats too exact (and way too much work).

So are there some rules of the thumb to make a reasonable estimation?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Please tell us exactly what microcontroller you are using and post a schematic. What are you trying to achieve by lowering the clock? If it's lower power consumption, there are other - more promising - ways of doing that. \$\endgroup\$
    – Christoph
    Commented Mar 11, 2013 at 14:05
  • \$\begingroup\$ Start by considering what inflexible timing constraints you might miss, and to what degree use of buffering and interrupts might make them flexible. \$\endgroup\$ Commented Mar 11, 2013 at 14:22
  • \$\begingroup\$ @Christoph Yes Im trying to lower power consumption. \$\endgroup\$
    – Maestro
    Commented Mar 11, 2013 at 14:44
  • \$\begingroup\$ @Joshua And what about the microcontroller type and schematic? The more information you provide, the better our answers can be. \$\endgroup\$
    – Christoph
    Commented Mar 11, 2013 at 15:00
  • \$\begingroup\$ @Christoph It's a Cortex M0, I didnt want to make the question too specific. \$\endgroup\$
    – Maestro
    Commented Mar 11, 2013 at 19:45

5 Answers 5

2
\$\begingroup\$

If your code isn't working as the clock speed reduces it sounds like you're keeping all the interupt sources alive (nested interupts) when your servicing an interupt routine. With all the interupts enabled all the time, you will jump out of some code and into a higher order interupt if one occurs, only returning to a lower order interupt once the highest order one has finished.

This can lead to major timing issues if the interupt priorities aren't properly managed especially with communication ports such as a UART & SD CARD. If one assumes the GPIO are connected to the outside of your box, then the GPIO interupts will happen "at will" in a data logger and can't be predicted so keeping these routines very short is advantageous.

This may lead to setting a maximum GPIO toggle rate for these external pins so your code remains valid (maximum 100Hz on any external Input pin, and a maximum of 2 KHz across all inputs for example).

If you want to reduce current then you run in active mode at a higher clock speed, by altering the code so that all routines are event driven and go into a sleep or wait mode for the rest of the time to reduce the supply current. A few microcontrollers have extremely low current Wait modes by 75% of active mode (CPU off, peripherals on) but most only reduce the current by ~20-30% from active mode.

One or two micro vendors can even keep the peripherals running in deep sleep modes with fast wake-up, but most micro's usually turn off all the peripherals in deep sleep and only allow the the GPIO, WDT, POR, BOR or an RTC to wake up a micro.

\$\endgroup\$
1
  • \$\begingroup\$ Most peripherals depend on Clk to derive baud rates. One cannot simply reduce the Clk without reconfiguring the UART to operate at the same baud for the new Clk \$\endgroup\$
    – AlphaGoku
    Commented Jan 23, 2018 at 10:36
1
\$\begingroup\$

Provided you don't have to spend time busy-waiting within your CPU, total charge (energy) consumption by the CPU core will be a function of the total number of instructions you need to execute, rather than the clock speed at which they are executed. The amount of power spent by a CPU core which is active 10% of the time at 24MHz will often be roughly comparable to that of a CPU core which is active 20% of the time at 12Mhz.

If the chip has a programmable internal VDD, and can only operate at higher speeds with higher VDD settings, using those higher settings will likely increase the per-instruction charge consumption regardless of the speed at which the CPU actually executes those instructions. Thus, cranking up the CPU beyond a threshold that requires a higher VDD will have a much better effect on charge consumption than cranking it up to a point just below such a threshold.

My recommendation would be to figure out roughly what speed you need, figure out from that what VDD and other settings one will need, and set the CPU clock to be as fast as possible given those constraints. Then once you've done that, focus on making the CPU be idle as much of the time as possible.

\$\endgroup\$
1
\$\begingroup\$

supercat's answer is pretty much what I would have suggested, but also check your circuit for other consumers that draw current when they don't need to.

  • If there are external ICs, see if they provide a power down mode (one candidate is your UART: if you have a level shifter, it might be possible to switch it off at least partially during sleep).
  • Voltage dividers, pull-ups or pull-downs, check anything. Passive components are often ignored because "they don't do anything", but they do draw current.

Provided that you have external components, chances are that these draw more current than your microcontroller even before you have optimized voltage, frequency and active time. If this is just a prototype, see if you can redesign it for optimized power consumption.

\$\endgroup\$
0
\$\begingroup\$

With a duty cycle of 10:90 cycle at 12MHz, then about 1.2 MHz should give a 100% duty cycle with no margin for error. Pick a factor of safety within your comfort level and multiply it by 1.2MHz.

If 10:90 is an estimate you could raise an output bit when the MCU wakes and lower it again just before it sleeps. You can then find the run time with a scope or a DVM that can measure frequency and duty cycle. Make the above adjustment and measure again. Repeat until it meets your duty cycle, power consumption, or other goal.

\$\endgroup\$
0
\$\begingroup\$

My strategy of choice when dealing with this type of application, is to make the code event-driven (or asynchronous) and not worry too much about clock frequency. If you drive the system with interrupts (for instance via timers or peripherals), you may be able to lower the MCUs power-level to some sort of hibernation setting as the default action and only do something else on interrupts. Several of the Atmel MCUs have levels of sleep that will enable/disable certain interrupts for wakeup. ARM Cortex M-series MCUs also have advanced interrupts abilities that goes well with power savings.

When the event queue is empty, do the default action: go to low-power mode for some time. That way, the clock frequency isn't important, as you're only powered up and using power when you have anything to do.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.