pwm_fade.c
El PWM por hardware del nRF52840 produce la respiración sin intervención de la CPU: una secuencia de dos valores reproducida 40 veces por paso de intensidad. El LED P0.06 sube y baja suavemente a 25 kHz inaudibles.
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. LED en P0.06 (integrado) + resistencia de 330 Ω si el LED es externo.
Cableado
Ánodo del LED a P0.06 mediante 330 Ω, cátodo a GND; la salida va invertida para que el nivel alto la apague según el montaje.
Funcionamiento
NRFX_PWM genera periodo y ciclo de trabajo por hardware; simple_playback repite la secuencia "repeat" veces y la CPU solo cambia la rampa cada 30 ms.
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
Gestionar la rampa por interrupción PWM END para un fundido sin delay, o sacar 4 canales (tira LED) con los 4 subcanales del 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);
}
}