adc_saadc.c

nRF52840-MDK (id boards.json : nrf52840-mdk) · Fichier : adc_saadc.c · Langage : C · Usage : Mesurer une tension avec le SAADC (surveillance batterie LiPo)

Le SAADC du nRF52840 mesure avec la référence interne 0,6 V et un gain fractionnaire : en divisant la batterie LiPo par deux, on lit 0-3,3 V sur la broche et on reconstitue 0-6,6 V. Base de toute surveillance d'alimentation autonome.

Matériel requis

Une carte nRF52840-MDK (Nordic nRF52840, Cortex-M4F @ 64 MHz, 1 Mo flash / 256 Ko RAM, BLE 5 + 802.15.4) avec son debugger intégré, programmée en C sous nRF5 SDK v17 et SoftDevice S140. Batterie LiPo 3,7 V + pont diviseur 2 × 1 MΩ (point milieu vers P0.04), condensateur 100 nF vers GND.

Câblage

Vbat → 1 MΩ → P0.04 → 1 MΩ → GND ; 100 nF en parallèle sur la résistance basse. Masse batterie commune avec la carte.

Fonctionnement

Le canal SE mesure P0.04 contre GND avec gain 1/6 et référence interne ; l'échantillon 12 bits est converti en millivolts puis ×2 pour la tension batterie réelle.

Exécution

Ouvrir l'exemple correspondant du nRF5 SDK v17 (target custom_board), coller ce code dans main.c, compiler avec Segger Embedded Studio ou Makefile gcc, puis programmer via le debugger intégré (flash_nrf.py ou IDE).

Variantes

Échantillonner en mode buffered + EasyDMA, stocker l'historique en flash (NVCU) et publier le niveau de batterie en BLE (exemple 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);
  }
}

← Retour à la fiche