LPC810メモ:deep power-downモード(Self wake-up timerで復帰)
前回と同様、deep power-downモードの実験。
ただし、WAKEUP pinではなく、Self wake-up timer(WKT)で定期的にwake upする例。
前提とする環境はこちら→LPC810メモ 共通の準備
- 電源onすると、LED一回点滅してdeep power-down
- 3秒経過するとwake up、LEDを2回点滅してdeep power-down
- 以降、3秒経過する度にwake up、点滅回数が一回ずつ増える。
サンプルコード
#include "LPC8xx.h" int main(void) { // 何回目の起動かを判別用 uint32_t count = 1; // wake up時の手順、deep power-downに入る手順は、それぞれ // UM10601の5.7.7.4、5.7.7.5 // wake upかどうか判定 // UM10601 5.6.1 Power control register if(LPC_PMU->PCON & (1 << 11)) { // DPDFLAG(11)が立ってるので、deep power-downからの復帰である。 // 同フラグをクリア LPC_PMU->PCON &= ~(1 << 11); // Deep power-downする前に記録した汎用レジスタから値を読み込み // UM10601 5.6.2 General purpose registers 0 to 3 count = LPC_PMU->GPREG0; } // countの回数分、8番pinのLEDを点滅 LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6); LPC_GPIO_PORT->DIR0 |= (1<<0); for(uint32_t i = 0; i < (count * 2); i++) { LPC_GPIO_PORT->NOT0 |= (1<<0); for(volatile int i = 0; i < 200000; i++) {} } /// Self wake-up timer (WKT)の有効化 // UM10601 13.3 Basic configuration LPC_SYSCON->SYSAHBCLKCTRL |= (1<<9); LPC_SYSCON->PRESETCTRL &= ~(0x1<<9); LPC_SYSCON->PRESETCTRL |= (0x1<<9); // Deep power-downの処理 // UM10601 5.6.3 Deep power-down control register LPC_PMU->DPDCTRL |= (1 << 1) // WAKEPAD_DISABLE = 1(今回はWAKEUP pinは使わない) | (1 << 2) // LPOSCEN = 1 | (1 << 3); // LPOSCDPDEN = 1 // UM10601 5.6.1 Power control register LPC_PMU->PCON &= ~(1 << 3); // NODPD = 0 LPC_PMU->PCON |= 0x3; // PM = 0x3 // UM10601 5.6.2 General purpose registers 0 to 3 LPC_PMU->GPREG0 = count + 1; // 次回のために汎用レジスタをカウントアップ // UM10601 5.3.1.1 System control register SCB->SCR |= (1 << 2); // SLEEPDEEP = 1 /// Self wake-up timer (WKT)設定 // 13.6.1 Control register LPC_WKT->CTRL |= (1 << 0); // CLKSEL = 1 10KHzのlow power clockを利用 LPC_WKT->COUNT = 30000; // 10KHzなので、3秒に設定 // Use the ARM WFI instruction. __WFI(); return 0 ; }
補足/雑感
- WAKEUP pin使わないから、UM10601「5.4 Pin description」の記載を無視して1,2番をpull upしてないが、問題ないのか不明。1番(RESET)はpull upした方が良い気もする。
- この機能って何に使うんだろう。1時間毎に温度記録する、とか?