| パソコン制御をもっと気軽に 電子制御をもっと気楽に |
低速CPUクロックによる省電力化
Arduino RP2040 2026/01/10
/*
実際は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 |