app_timer_rtc.c
The 32.768 kHz RTC keeps counting during sleep: app_timer schedules a 1 Hz callback without ever blocking the CPU, which waits in WFE. It is the service clock of any battery-powered nRF52840 program.
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 alone (crystal or internal 32 kHz RC).
Wiring
No wiring; LED P0.06 to eyeball the rhythm (0.5 Hz).
How it works
app_timer converts milliseconds into RTC ticks and fires the callback from interrupt context; APP_TIMER_TICKS handles precision. The CPU burns almost nothing between ticks.
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
Create several timers (1 Hz sensing, 10 Hz BLE), or switch to the NRFX_TIMER driver for a high-frequency 16-bit timer.
app_timer_rtc.c
// nRF52840-MDK : tâche périodique 1 Hz via app_timer (compteur RTC 32,768 kHz).
// Le CPU dort entre deux ticks : bien plus économe qu'une boucle delay().
#include "app_timer.h"
#include "nrf_gpio.h"
#include "nrf_sdh.h"
APP_TIMER_DEF(m_timer);
static volatile uint32_t secondes;
static void tick(void *ctx) {
(void)ctx;
secondes++;
nrf_gpio_pin_toggle(6); // LED à 0,5 Hz pile
// Ici : lecture capteur, mise à jour BLE, sauvegarde...
}
int main(void) {
nrf_sdh_enable_request(); // horloge 32 kHz gérée (SoftDevice ou LFCLK)
if (!nrf_sdh_is_enabled()) {
NRF_CLOCK->TASKS_LFCLKSTART = 1;
while (!NRF_CLOCK->EVENTS_LFCLKSTARTED) { }
}
app_timer_init();
app_timer_create(&m_timer, APP_TIMER_MODE_REPEATED, tick);
app_timer_start(m_timer, APP_TIMER_TICKS(1000), NULL);
nrf_gpio_cfg_output(6);
for (;;) {
// Le cœur peut dormir : le RTC et les interruptions le réveillent.
__WFE();
if (secondes >= 60) { // exemple : une action par minute
secondes = 0;
// publish_ble_mesure();
}
}
}