system_off.c

nRF52840-MDK (boards.json id: nrf52840-mdk) · File : system_off.c · Language : C · Use case : Atteindre le microampère en System Off

The nRF52840 drops to a few microamps in System Off: only a pin armed with SENSE can power the chip back up. This sketch dies after an LED flash and wakes on a button press — the base of a coin-cell sensor.

Hardware

An nRF52840-MDK board (Nordic nRF52840, Cortex-M4F @ 64 MHz, 1 MB flash / 256 KB RAM, BLE 5 + 802.15.4) with onboard debugger, programmed in C with nRF5 SDK v17 and the S140 SoftDevice. nRF52840-MDK on a coin cell or USB (current visible on a µA meter in series).

Wiring

Button between P0.02 and GND. To measure true sleep, remove the debugger or cut its supply side.

How it works

nrf_gpio_cfg_sense_input arms the level detector; SYSTEMOFF cuts internal power. Wake-up is a hardware reset: the code restarts from scratch.

Running it

Open the matching nRF5 SDK v17 example (custom_board target), paste this code into main.c, build with Segger Embedded Studio or the gcc Makefile, then flash through the onboard debugger.

Variants

Periodic wake with the RTC (System ON + WFE), or NFC wake (a phone's field) for a button-less sensor.

system_off.c

// nRF52840-MDK : sommeil profond System Off (~0,4 µA typique).
// Réveil par appui sur le bouton P0.02 (PIN RESET) ou reset broche.
#include "nrf.h"
#include "nrf_gpio.h"

#define BTN 2U   // P0.02 : configuré en réveil bas niveau

static void configurer_reveil(void) {
  nrf_gpio_cfg_sense_input(BTN,
      NRF_GPIO_PIN_PULLUP,               // repos haut, bouton vers GND
      NRF_GPIO_PIN_SENSE_LOW);           // un niveau bas réveille la puce
}

int main(void) {
  // 1) Tâche brève : allumer la LED 100 ms pour signaler le cycle.
  nrf_gpio_cfg_output(6);
  nrf_gpio_pin_set(6);
  for (volatile int i = 0; i < 800000; i++) __NOP();
  nrf_gpio_pin_clear(6);

  // 2) Configuration du réveil puis entrée en System Off.
  configurer_reveil();
  NRF_POWER->SYSTEMOFF = 1UL;            // écriture magique : la puce s'éteint

  // Inatteignable : après réveil, le programme repart de main().
  for (;;) { }
}

← Back to the board