How to play PWM sequence of the variable frequency and constant duty cycle

Hello, guys!

Here are the details about my development environment:

SDK = 15.3.0


SoC = nRF52840-based BL654 module.

In my design, I need to drive a buzzer with the PWM signal. I've seen many PWM examples that deal with the complex playing sequences. What I need, however, is to play PWM that has constant duty cycle but variable frequency. Moreover, I would like, if possible, to change PWM frequency automatically, without CPU intervention (i.e. without event handlers).

Is there any way I can do this? By looking at this thread, I've learned that PWM hardware is intended for use cases where the duty cycle is changing and if I want to change the PWM frequency, I need to uninit and re-init the PWM hardware. This uninit - reinit process is quite fast to be perceived by a human ear. Withing the same thread they suggest a possibility to use a timer and GPIO with PPI for implementing the signal with variable frequency.

What is your opinion, guys, is there any way I could change PWM frequency parameter automatically, on-the-fly, without any CPU intervention (in DMA mode)?

Thanks in advance for your time and effort.



  • Hi Bojan,

    Yes, there is a waveform mode that can change both frequency and duty cycle. Here's its description from spec:

    A special mode of operation is available when DECODER.LOAD is set to WaveForm. In this mode, up to
    three PWM channels can be enabled - OUT[0] to OUT[2]. In RAM, four values are loaded at a time: the
    first, second and third location are used to load the values, and the fourth RAM location is used to load the
    COUNTERTOP register. This way one can have up to three PWM channels with a frequency base that
    changes on a per PWM period basis. This mode of operation is useful for arbitrary wave form generation in
    applications such as LED lighting.

  • Hello ,

    Thank you very much for pointing out that for me. Indeed, I was able to benefit from the PWM waveform mode!

    Thanks once again!