RP2040 PWM Library

Hello

I'm using the RP2040 Connect and the PWM Library,it work all fine but a have a question and I can not find the Answer anywhere.
How can I generate with two PWM Slices four complementary Outputs for a Full Bridge Converter Project.
I tryed something like the code below:

/****************************************************************************************************************************
  PWM_PushPull.ino
  For RP2040 boards
  Written by Khoi Hoang

  Built by Khoi Hoang https://github.com/khoih-prog/RP2040_PWM
  Licensed under MIT license

  The RP2040 PWM block has 8 identical slices. Each slice can drive two PWM output signals, or measure the frequency
  or duty cycle of an input signal. This gives a total of up to 16 controllable PWM outputs. All 30 GPIO pins can be driven
  by the PWM block
*****************************************************************************************************************************/

#define _PWM_LOGLEVEL_        4
#include "RP2040_PWM.h"

//creates pwm instance
RP2040_PWM* PWM_Instance;
RP2040_PWM* PWM_Instance2;
float frequency = 100000.0f;
float dutyCycle = 50.0f;

// Pins have to be in pairs of the same PWM slice / channel
// Check https://github.com/khoih-prog/RP2040_PWM#programmers-model
// For example: pins 0/1, 2/3, 4/5, 6/7, 8/9, 10/11, 12/13, 14/15, 16/17, 18/19, 20/21, 22/23, 24/25, 26/27, 28/29

#define pinToUseA      18     // PWM1A
#define pinToUseB      19     // PWM1A
#define pinToUseC      20     // PWM1A
#define pinToUseD      21     // PWM1A
void printPWMInfo(RP2040_PWM* PWM_Instance)
{
  uint32_t div = PWM_Instance->get_DIV();
  uint32_t top = PWM_Instance->get_TOP();

  Serial.print("Actual PWM Frequency = ");
  Serial.println(PWM_Instance->getActualFreq());

  PWM_LOGDEBUG5("TOP =", top, ", DIV =", div, ", CPU_freq =", PWM_Instance->get_freq_CPU());
}
void printPWMInfo2(RP2040_PWM* PWM_Instance2)
{
  uint32_t div = PWM_Instance2->get_DIV();
  uint32_t top = PWM_Instance2->get_TOP();

  Serial.print("Actual PWM Frequency = ");
  Serial.println(PWM_Instance2->getActualFreq());

  PWM_LOGDEBUG5("TOP =", top, ", DIV =", div, ", CPU_freq =", PWM_Instance2->get_freq_CPU());
}

void setup()
{ 
  Serial.begin(115200);

  while (!Serial && millis() < 5000);

  delay(100);

  Serial.print(F("\nStarting PWM_PushPull on "));
  Serial.println(BOARD_NAME);
  Serial.println(RP2040_PWM_VERSION);

  // Use just one of these 2 for a pair
  // assigns pinToUseA, with frequency of 200 Hz and a duty cycle of 0%
  PWM_Instance = new RP2040_PWM(pinToUseA, frequency, 0);
  PWM_Instance2 = new RP2040_PWM(pinToUseC, frequency, 0);
  // assigns pinToUseB, with frequency of 200 Hz and a duty cycle of 0%
  //PWM_Instance = new RP2040_PWM(pinToUseB, frequency, 0);

  // pinToUseA always with same polarity, pinToUseB with reversed polarity
  //PWM_Instance->setPWMPushPull(pinToUseA, pinToUseB, frequency, dutyCycle);
  // pinToUseA always with same polarity, pinToUseB shifted 180 deg
  PWM_Instance->setPWMPushPull(pinToUseA, pinToUseB, frequency, dutyCycle);
  PWM_Instance2->setPWMPushPull(pinToUseC, pinToUseD, frequency, dutyCycle);
delay(5000);
  printPWMInfo(PWM_Instance);
  printPWMInfo2(PWM_Instance2);
}

void loop()
{
}

I'm not sure if this is the right way !? :slight_smile:

Thanks in advance for any Help!

Regards

I have tryed the code and analysed with the Logic Analyser,the second Slice Output is not Synchrone with the first one.
I have no Idea how to synchronise the two slices.

I found the Way to do Synchronous Slice Start but not with the rp2040_pwm Library.
I'm using the hardware/pwm.h pico SDK Library,now I can generate full Bridge U-V Outputs,the dead Times are made with external IC.
Here is the Code,maybe some one have the same Issue:

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "pico/stdlib.h"
#include "hardware/pwm.h"

int main() {
   

    /////Slice 1
    gpio_set_function(18, GPIO_FUNC_PWM);
    gpio_set_function(19, GPIO_FUNC_PWM);
    /////Slice 2
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
   
    uint slice_num1 = pwm_gpio_to_slice_num(18);
    uint slice_num2 = pwm_gpio_to_slice_num(20);
    #define PWM_PERIOD 1249 //50 Khz
    #define PWM_VALUE   624
    // Set PWM period
    pwm_set_wrap(slice_num1, PWM_PERIOD);
    // Set channel A output high in low zone of counter
    pwm_set_chan_level(slice_num1, PWM_CHAN_A, PWM_VALUE);
    // Set initial B output high in high zone of counter
    pwm_set_chan_level(slice_num1, PWM_CHAN_B, PWM_PERIOD - PWM_VALUE);

    pwm_set_phase_correct(slice_num1, true);
    pwm_set_output_polarity(slice_num1, false, true);
    //////////////////////////////////////////////////////////
     pwm_set_wrap(slice_num2, PWM_PERIOD);
    // Set channel A output high in low zone of counter
    pwm_set_chan_level(slice_num2, PWM_CHAN_A, PWM_VALUE);
    // Set initial B output high in high zone of counter
    pwm_set_chan_level(slice_num2, PWM_CHAN_B, PWM_PERIOD - PWM_VALUE);

    pwm_set_phase_correct(slice_num2, true);
    pwm_set_output_polarity(slice_num2, true, false);
    // Set the PWM running
    pwm_set_enabled(slice_num1, false);
     pwm_set_enabled(slice_num2, false);
     // make them go:
   pwm_set_mask_enabled((1<<slice_num1) | (1<<slice_num2) | pwm_hw->en);
    /// \end::setup_pwm[]
return 0;
    
}

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.