adc_saadc.c
El SAADC del nRF52840 mide con la referencia interna de 0,6 V y ganancia fraccionaria: al dividir la batería LiPo entre dos, se leen 0-3,3 V en el pin y se reconstruyen 0-6,6 V. Base de toda vigilancia de alimentación autónoma.
Hardware
Una placa nRF52840-MDK (Nordic nRF52840, Cortex-M4F @ 64 MHz, 1 MB flash / 256 KB RAM, BLE 5 + 802.15.4) con depurador integrado, programada en C con nRF5 SDK v17 y SoftDevice S140. Batería LiPo de 3,7 V + divisor con 2 × 1 MΩ (punto medio a P0.04), condensador de 100 nF a GND.
Cableado
Vbat → 1 MΩ → P0.04 → 1 MΩ → GND; 100 nF en paralelo con la resistencia inferior. Masa de la batería común con la placa.
Funcionamiento
El canal SE mide P0.04 contra GND con ganancia 1/6 y referencia interna; la muestra de 12 bits se convierte a milivoltios y se multiplica ×2 para la tensión real.
Ejecución
Abre el ejemplo equivalente del nRF5 SDK v17 (objetivo custom_board), pega este código en main.c, compila con Segger Embedded Studio o el Makefile de gcc y programa por el depurador integrado.
Variantes
Muestrear en modo buffered + EasyDMA, guardar historial en flash (NVCU) y publicar el nivel de batería por BLE (ejemplo NUS).
adc_saadc.c
// nRF52840-MDK : mesure SAADC canal 1 (P0.04) — batterie LiPo via pont diviseur.
// Diviseur 1M/1M -> Vbat = 2 x Vpin ; ref interne 0,6 V, gain 1/6 -> pleine echelle 3,6 V.
#include "nrfx_saadc.h"
#include "nrf_delay.h"
static volatile int16_t echantillon;
static volatile bool pret = false;
static void evt(nrfx_saadc_evt_t const *p_evt) {
if (p_evt->type == NRFX_SAADC_EVT_DONE) {
pret = true; // la conversion demandee est terminee
}
}
int main(void) {
nrfx_saadc_config_t cfg = NRFX_SAADC_DEFAULT_CONFIG;
cfg.resolution = NRF_SAADC_RESOLUTION_12BIT;
nrfx_saadc_init(&cfg, evt);
nrf_saadc_channel_config_t ch = NRFX_SAADC_DEFAULT_CHANNEL_CONFIG_SE(4); // AIN1 = P0.04
ch.gain = NRF_SAADC_GAIN1_6; // pleine echelle ~ 3,6 V
ch.reference = NRF_SAADC_REFERENCE_INTERNAL;
nrfx_saadc_channel_init(0, &ch);
for (;;) {
nrfx_saadc_buffer_convert((int16_t *)&echantillon, 1);
nrfx_saadc_simple_mode_start(1, 0, false, 0);
while (!pret) { } // attend l'evenement DONE
pret = false;
int mv_pin = (int)((echantillon / 4095.0f) * 3600.0f); // 12 bits -> mV
int mv_bat = 2 * mv_pin; // dediviseur x2 : tension batterie
// Afficher mv_bat sur la console (voir exemple console_uart) ou le
// publier en BLE. Temoin visuel : LED si batterie < 3,3 V.
nrf_gpio_cfg_output(6);
nrf_gpio_pin_write(6, mv_bat < 3300);
nrf_delay_ms(1000);
}
}