pwm_rampe.c
Flicker-free brightness ramp: the nRF chip PWM at 100 Hz raises and lowers brightness in 2 % steps. The channel comes from alias pwm-0; an overlay steers the PWM controller to a header pin when needed.
Hardware
An nRF52833-DK board (Nordic, nRF52833 Cortex-M4F SoC, BLE 5) powered over USB: 4 LEDs on P0.13-P0.16 (active-low) and 4 buttons on P0.11, P0.12, P0.24, P0.25 (active-low, internal pull-up must be enabled). One LED + 330 Ω on a PWM-routed pin (P2.xx on the DK via overlay), or the MDK RGB LED if the overlay targets it.
Wiring
LED between the PWM pin and GND through 330 Ω. The DK P1/P2 header pins output 3.3 V: check voltage before any 5 V part.
How it works
pwm_set_dt sets period (10 ms) and pulse width (0 to period). The loop sweeps 0-100 % every 20 ms, i.e. a 2-second full ramp.
Running it
Zephyr project: west build -b nrf52833dk/nrf52833 then west flash (on-board J-Link); 115200 serial console on the USB UART connector.
Variants
Three PWM channels = RGB fading, push frequency past 1 kHz for filtered audio, or drive a servo with a 20 ms period.
pwm_rampe.c
/* Rampe PWM sur l'alias pwm-0 (100 Hz, rapport 0-100 %).
* Le BSP ne route pas toujours PWM sur les LED : overlay minimal
* à ajouter au projet pour coller PWM0 sur une broche libre, p.ex.
* &pwm20 { status = "okay"; };
* / { aliases { pwm-0 = &pwm20; }; };
* (sur le DK, P2.xx du connecteur via le node pinctrl du PWM). */
#include <zephyr/kernel.h>
#include <zephyr/drivers/pwm.h>
static const struct pwm_dt_spec pwm_led = PWM_DT_SPEC_GET(DT_ALIAS(pwm_0));
#define PERIODE_NS 10000000U /* 10 ms = 100 Hz, sans scintillement */
static void intensite(unsigned pct)
{
pwm_set_dt(&pwm_led, PERIODE_NS, PERIODE_NS * pct / 100U);
}
int main(void)
{
if (!pwm_is_ready_dt(&pwm_led)) {
printk("Canal PWM indisponible\n");
return 1;
}
while (1) {
for (unsigned p = 0; p <= 100; p += 2) {
intensite(p);
k_msleep(20);
}
for (unsigned p = 100; p >= 2; p -= 2) {
intensite(p);
k_msleep(20);
}
}
return 0;
}