pwm_fade.c

nRF52840-MDK (id boards.json : nrf52840-mdk) · Fichier : pwm_fade.c · Langage : C · Usage : Faire respirer une LED avec un canal PWM

Le PWM matériel du nRF52840 produit la respiration sans intervention du CPU : une séquence de deux valeurs rejouée 40 fois par pas d'intensité. La LED P0.06 monte et descend en douceur, à 25 kHz hors bruit audible.

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. LED sur P0.06 (embarquée) + résistance 330 Ω si LED externe.

Câblage

LED anode vers P0.06 via 330 Ω, cathode vers GND ; la sortie est inversée pour que la valeur haute éteigne correctement selon le montage.

Fonctionnement

NRFX_PWM génère la période et le rapport cyclique en matériel ; simple_playback relance la séquence repeat fois, le CPU ne fait que changer la rampe toutes les 30 ms.

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

Piloter la rampe par interruption PWM END pour un fondu sans delay, ou sortir 4 canaux (ruban LED) avec les 4 sous-canaux du PWM.

pwm_fade.c

// nRF52840-MDK : respiration LED sur P0.06 via le périphérique PWM0, canal 0.
// Le PWM matériel génère le signal seul : le CPU peut dormir entre deux pas.
#include "nrfx_pwm.h"
#include "nrf_delay.h"

static uint16_t seq_haute[2] = { 0, 600 };    // OFF puis ON (PWM inversé)
static uint16_t seq_basse[2] = { 600, 0 };

static void pwm_evt(nrf_pwm_event_t evt) { (void)evt; }

static void fade(bool montant) {
  nrf_pwm_values_common_t *seq = montant ? seq_basse : seq_haute;
  nrf_pwm_sequence_t s = {
    .values.p_common = seq, .length = 2,
    .repeat = 39,                              // 40 périodes = rampe douce
    .end_delay = 0,
  };
  nrf_pwm_sequence_t *seqs[] = { &s };
  nrfx_pwm_simple_playback(seqs, 1, 1, 0);
}

int main(void) {
  nrfx_pwm_config_t cfg = NRFX_PWM_DEFAULT_CONFIG(
      6, NRF_PWM_PIN_INVERTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED);
  cfg.refresh_cycle_time = 39;                 // ~40 µs -> 25 kHz inaudible
  nrfx_pwm_init(&cfg, pwm_evt);

  for (;;) {
    for (int i = 0; i < 40; i++) { fade(true);  nrf_delay_ms(30); }
    for (int i = 0; i < 40; i++) { fade(false); nrf_delay_ms(30); }
    nrf_delay_ms(400);
  }
}

← Retour à la fiche