nRF5 SDK v12.1.0
PWM library

The pulse-width modulation (PWM) library provides functions to generate a pulse-width modulated output signal.

Key features include:

Resource usage

Users can create multiple instances of the library. The PWM library allocates a timer instance (see Timer) that is not available to the user. Therefore, the number of independent PWM instances depends on the number of hardware timers.

Resource usage:

nRF51 only:

nRF52 only:

nRF51 only: For example, a PWM instance with two channels will consume 2+4 PPI channels, 1 PPI group, and 2 GPIOTE channels. nRF52 only: For example, a PWM instance with two channels will consume 1+4 PPI channels and 2 GPIOTE channels.

The PPI and GPIOTE channels are allocated by the PPI and GPIOTE drivers.

Generating a low-power PWM signal

Complete the following steps to generate a PWM signal:

  1. Create one or more PWM instances by calling the APP_PWM_INSTANCE macro. Note that each instance will utilize a hardware timer, which will be unavailable for other uses. Changing the timer parameters during PWM operation will result in undefined behavior.
    The following code shows how to create a new PWM instance:
    APP_PWM_INSTANCE(PWM0,0); // Create the instance "PWM0" using TIMER0.
  2. For each instance, create an app_pwm_config_t structure with the default or custom configuration. If you want to use the default configuration, call the APP_PWM_DEFAULT_CONFIG_1CH or APP_PWM_DEFAULT_CONFIG_2CH macro to fill the configuration structure.
    The following parameters must be specified:
    • pins: Array of two unsigned integers that indicate which physical pins will be used for the PWM output. In one-channel mode, the second element is ignored.
    • pin_polarity: 2-element array of app_pwm_polarity_t that indicates the output signal polarity. In one-channel mode, the second element is ignored.
    • num_of_channels: Number of PWM channels (1 or 2).
    • period_us: Signal period (in microseconds).
  3. Provide a callback function (see app_pwm_callback_t) that will be executed when the PWM state changes from BUSY to READY. (Also see the Limitations section.)
  4. Initialize each instance using app_pwm_init, with pointers to the instance, the configuration structure, and the callback function as parameters. The function will return NRF_SUCCESS on success or an error code on failure. Initialization will fail if the instance was already initialized, if an invalid configuration was provided, or if there were not enough free resources.
  5. Call app_pwm_enable to enable a given instance.
  6. Call app_pwm_channel_duty_set to set the duty cycle for a given instance.

A PWM signal should now appear on the output pin. No CPU time is used during operation.

Limitations

nRF51 only:

nRF52 only:

Example

See the following code for a usage example. Note that this example is not power optimized.

APP_PWM_INSTANCE(PWM1,1); // Create the instance "PWM1" using TIMER1.
void pwm_ready_callback(uint32_t pwm_id) // PWM callback function
{
}
/*
...
*/
ret_code_t err_code;
/* 2-channel PWM, 200 Hz, output on DK LED pins. */
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(5000L, BSP_LED_0, BSP_LED_1);
/* Switch the polarity of the second channel. */
pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
/* Initialize and enable PWM. */
err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
APP_ERROR_CHECK(err_code);
uint32_t value;
while(true)
{
for (uint8_t i = 0; i < 40; ++i)
{
value = (i < 20) ? (i * 5) : (100 - (i - 20) * 5);
/* Se the duty cycle - keep trying until PWM is ready. */
while (app_pwm_channel_duty_set(&PWM1, 0, value) == NRF_ERROR_BUSY);
while (app_pwm_channel_duty_set(&PWM1, 1, value) == NRF_ERROR_BUSY);
nrf_delay_ms(25);
}
}

See the PWM Library Example for a full application that uses the PWM library.

Usage with a SoftDevice

The PWM library can be used with a SoftDevice. However, there are some limitations:


Documentation feedback | Developer Zone | Subscribe | Updated