LOGO パソコン制御をもっと気軽に  
電子制御をもっと気楽に

低速CPUクロックによる省電力化

Arduino RP2040 2026/01/10

CPUクロックを 2MHz,4MHz,12MHz,40MHz,80MHz,120MHz に設定できます。
PowerSaveHelper.hppに書いてある電流値は Waveshare RP2040Zero でのtypeCの実測値です
download ZIP( 14Kbyte )

Viewer

PowerSaveHelper/src/PowerSaveHelper.hpp
/*
    実際はSleepでは無く clockを遅くして消費電流を少なくするだけです
    2025/01/22 現在 RP2040 専用です
	2025/01/26 RP2350にも対応しました
*/

#pragma once

#if defined(ARDUINO_ARCH_RP2040)
// suport RP2040 RP2350 only

#include "arduino.h"
//#include "hardware/clocks.h"
#include "hardware/pll.h"
//#include "hardware/resets.h"

#include "hardware/xosc.h"

#if defined( PICO_RP2350 )
  // RP2350 only
  #include "hardware\structs\ticks.h"
#endif

#include "pico_sleep/pico_sleep.h"         // githubにあるarduino-pico-sleepのコピーです


class cPowerSave
{
  public:
    static void WithXOSC();
    //
    static void CpuSpeed12MHz()
    {
      if ( clock_get_hz(clk_sys) == 12*MHZ )
        return;
      //
      CpuSpeedAdjust( 1 , 1 ) ;
      // 約3.3mA消費する
    }
    static void CpuSpeed4MHz()
    {
      if ( clock_get_hz(clk_sys) == 4*MHZ )
        return;
      //
      CpuSpeedAdjust( 3 , 1 ) ;
      // 約1.8mA消費する
    }
    static void CpuSpeed2MHz()
    {
      if ( clock_get_hz(clk_sys) == 2*MHZ )
        return;
      //
      CpuSpeedAdjust( 3 , 2 ) ;
      // 約1.8mA消費する
    }
    //
    static void CpuSpeed40MHz()
    {
      if ( clock_get_hz(clk_sys) == 40*MHZ )
        return;
      //
      CpuSpeedAdjustPLL( 120 , 6 , 6 );
      // 12MHz * 120 / 6 / 6 => 40MHz
      // 約10mA消費する
    }
    //
    static void CpuSpeed80MHz()
    {
      if ( clock_get_hz(clk_sys) == 80*MHZ )
        return;
      //
      CpuSpeedAdjustPLL( 120 , 3 , 6 );
      // 12MHz * 120 / 3 / 6 => 80MHz
      // 約16mA消費する
    }
    //
    static void CpuSpeed120MHz()
    {
      if ( clock_get_hz(clk_sys) == 120*MHZ )
        return;
      //
      CpuSpeedAdjustPLL( 120 , 3 , 4 );
      // 12MHz * 120 / 3 / 4 => 120MHz
      // 約22mA消費する
    }
    //



  private:
    static void CpuSpeedAdjust( u_int ClkRefDiv , u_int ClkSysDiv ) ;
    static void CpuSpeedAdjustPLL( uint FBDIV , uint PDIV1, uint PDIV2 ) ;
} ;

// define in ShowReges.cpp
class cShowClkRegs
{
	public:
    static void ShowAll( Print * aPrint ) ;
    static void ShowClockRegs( Print * aPrint ) ;
    static void ShowClockFrequency( Print * aPrint ) ;
    static void ShowPllRegs( Print * aPrint) ;
    static void ShowClkRegs( Print * aPrint ) ;
    static void ShowXoscRegs( Print * aPrint ) ;
    static void ShowRoscRegs( Print * aPrint ) ;
#if defined( PICO_RP2350 )
    static void ShowTickRegs(Print * aPrint ) ;
#endif    
    static uint32_t frequency_count_hz(uint src);
} ;


class cClkGpout
{
public:
  enum eOutPin{
#if defined( PICO_RP2350 )  
    GPOUT13=13,
    GPOUT15=15,
#endif
    GPOUT21=21,
    GPOUT23=23,
    GPOUT24,
    GPOUT25,
  } ;
  enum eSrc{
    PLL_SYS = 0 ,
    GPIN0_20,
    GPIN1_21,
    PLL_USB,
#if defined( PICO_RP2350 )  
    PLL_USB_PRIM,
#endif
    ROSC,
    XOSC,
#if defined( PICO_RP2350 )
    LPOSC,
#endif
    CLK_SYS,
    CLK_USB,
    CLK_ADC,
#if defined( PICO_RP2350 )   
    CLK_RTC,
#endif
    CLK_REF,
#if defined( PICO_RP2350 )  
    CLK_PERI,
    CLK_HSTX,
    OTP_CLK,
#endif
  } ;
  static void Setup(eOutPin PinNo, eSrc Src, double div);
} ;

class cClkPeri
{
public:
 enum eSrc{
    CLK_SYS = 0 ,
    PLL_SYS  ,
    PLL_USB ,
    ROSC,
    XOSC,
    GPIN0_20,
    GPIN1_21,
  } ;
  static void Setup( eSrc Src ,u_int32_t Hz  );
} ;

class cClkAdc
{
public:
 enum eSrc{
    PLL_USB = 0 ,
    PLL_SYS  ,
    ROSC,
    XOSC,
    GPIN0_20,
    GPIN1_21,
  } ;
  inline static void Setup( eSrc Src ,u_int32_t Hz  )
  {
    Setup(Src,1,Hz);
  }
  static void Setup( eSrc Src ,u_int32_t div, u_int32_t Hz  );
} ;





#endif // defined(ARDUINO_ARCH_RP2040)
 

CPU is RP2040 group
CPU is RP2040
Setup done

CPU 12MHz Cu=  1
PLL_SYS :     0KHz
PLL_USB :     0KHz
ROSC    :     0KHz
XOSC    : 12000KHz
CLK_REF : 12002KHz
CLK_SYS : 12000KHz  <-- 12MHz
CLK_PERI: 12002KHz
CLK_USB :     0KHz
CLK_ADC :     0KHz
CLK_RTC :     0Hz

CPU 40MHz Cu=  2
PLL_SYS : 40000KHz  <-- PLL_SYSが動作している
PLL_USB :     0KHz
ROSC    :     0KHz
XOSC    : 12000KHz
CLK_REF : 12002KHz
CLK_SYS : 40000KHz  <-- 40MHz
CLK_PERI: 12002KHz
CLK_USB :     0KHz
CLK_ADC :     0KHz
CLK_RTC :     0Hz

CPU 2MHz Cu=  3
PLL_SYS :     0KHz
PLL_USB :     0KHz
ROSC    :     0KHz
XOSC    : 12000KHz
CLK_REF :  4002KHz
CLK_SYS :  2000KHz  <-- 2MHz
CLK_PERI: 12000KHz
CLK_USB :     0KHz
CLK_ADC :     0KHz
CLK_RTC :     0Hz

シーブイデブ e-mail:mnakatani@cvdev-jp.com