stm32sleep ライブラリを使います。
インストール
Latest commit f672b16 on 20 Apr 2016
を使いました。
ダウンロード or Clone して、Arduino フォルダの libraries の中に stm32sleep というフォルダを作り展開します。
使いかた
タイマーで復帰する
github にあるサンプルプログラムを動かすと、stop ないし standby に入って、タイマーで 5 秒で復帰するようになります。
しかしながらサンプルは最低限の記述なので、外部から動いているのだか動いてないのだかあまり良くわかりません。
RobotDyn STM32 Dev.Board ( ≒ BluePill ≒ Maple Mini ) を使って、もうちょっとわかりやすいプログラムに直しました。
#include <STM32Sleep.h>
#include <RTClock.h>
RTClock rt(RTCSEL_LSE);
long int alarmDelay = 5;
int i;
#define LED PC13
void setup() {
Serial.begin(9600);
delay(100);
// We have just started or woken up from sleep! System clock is set to 72MHz HSE.
pinMode(LED,OUTPUT);
for ( i=0;i<10;i++){
digitalWrite(LED,HIGH);
delay(100);
digitalWrite(LED,LOW);
delay(100);
}
Serial.println("start ...");
delay(100);
sleepAndWakeUp(STANDBY, &rt, alarmDelay);
Serial.println("Never came here");
}
void loop() {
// Never came here!
Serial.println("looping");
delay(100);
}
シリアルで状況を送ってますが、 PA9/PA10 ピンにUSBシリアルアダプタをつなげ、それで書込/通信をしています。
オンボードのUSBを使った場合はどうなるかは未検証です。
外部からの信号で復帰する
#include <STM32Sleep.h>
#include <RTClock.h>
// #include <series/rcc.h>
// RTClock rt(RTCSEL_LSE);
// long int alarmDelay = 5;
int i;
#define LED PC13
#define BOARD_BUTTON_PIN PB9
void setup() {
Serial.begin(9600);
delay(100);
// We have just started or woken up from sleep! System clock is set to 72MHz HSE.
pinMode(LED,OUTPUT);
pinMode(BOARD_BUTTON_PIN, INPUT_PULLUP);
for ( i=0;i<5;i++){
digitalWrite(LED,HIGH);
delay(40);
digitalWrite(LED,LOW);
delay(40);
}
Serial.println("start ...");
attachInterrupt(BOARD_BUTTON_PIN, action, CHANGE);
delay(100);
Serial.println("Never came here");
}
void loop() {
// sleepAndWakeUp(STANDBY, &rt, alarmDelay);
goToSleep(STANDBY);
switchToPLLwithHSE(RCC_PLLMUL_9);
delay(100);
Serial.println("looping");
for ( i=0;i<5;i++){
digitalWrite(LED,HIGH);
delay(40);
digitalWrite(LED,LOW);
delay(40);
}
delay(60);
}
void action()
{
}
switchToPLLwithHSE(RCC_PLLMUL_9);
が無いと、復帰後の動作がナメクジのように遅くなります。そこでこれを使うとクロックが復帰できるはずですが・・・
クロックがやっぱり遅いです。
調べてみると、STM32Sleep.cpp の中に書かれているコードが間違っていたみたいなので、
rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, RCC_PLLMUL_2);
を
rcc_clk_init(RCC_CLKSRC_PLL, RCC_PLLSRC_HSE, pllMultiplier);
に直すとうまくいきました。
参考資料
-
このライブラリの他にもこんなのもみつけましたが、まだ試していません;
https://gist.github.com/tomtor/3dff8dd2f2514912aacbab1b1652be76 -
libmapleのrccについてのドキュメントはこちら
http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/0.0.12/libmaple/api/rcc.html