Module stm32h7xx_hal::pwm[][src]

Expand description

Pulse Width Modulation (PWM)

PWM output is avaliable for the advanced control timers (TIM1, TIM8), the general purpose timers (TIM[2-5], TIM[12-17]) and the Low-power timers (LPTIM[1-5]).

Timers support up to 4 simultaneous PWM output channels

Examples

Usage

let gpioa = ..; // Set up and split GPIOA
let pins = (
    gpioa.pa8.into_alternate_af1(),
    gpioa.pa9.into_alternate_af1(),
    gpioa.pa10.into_alternate_af1(),
    gpioa.pa11.into_alternate_af1(),
);

To see which pins can be used with which timers, see your device datasheet or see which pins implement the Pins trait.

Then call the pwm function on the corresponding timer:

  let device: pac::Peripherals = ..;

  // Put the timer in PWM mode using the specified pins
  // with a frequency of 100 hz.
  let (c0, c1, c2, c3) = device.TIM1.pwm(
      pins,
      100.hz(),
      prec,
      &clocks
  );

  // Set the duty cycle of channel 0 to 50%
  c0.set_duty(c0.get_max_duty() / 2);
  // PWM outputs are disabled by default
  c0.enable()

Advanced features

Some timers support various advanced features. These features are accessed by calling TIMx.pwm_advanced to get a PwmBuilder and calling appropriate methods of the PwmBuilder before calling PwmBuilder::finalize to create the PWM channels and a PwmControl struct exposing things like FaultMonitor functionality.

let gpioa = ..; // Set up and split GPIOA
let pins = (
    gpioa.pa8.into_alternate_af1(),
    gpioa.pa9.into_alternate_af1(),
    gpioa.pa10.into_alternate_af1(),
    gpioa.pa11.into_alternate_af1(),
);

Then call the pwm_advanced function on the corresponding timer:

  let device: pac::Peripherals = ..;

  // Put the timer in PWM mode using the specified pins
  // with a frequency of 100 hz, 2us deadtime between complementary edges,
  // center-aligned PWM, and an active-low fault input
  let (mut control, (c1, c2, c3, c4)) = device.TIM1
      .pwm_advanced(
          pins,
          prec,
          &clocks
      )
      .frequency(100.hz())
      .center_aligned()
      .with_break_pin(gpioe.pe15.into_alternate_af1(), Polarity::ActiveLow)
      .finalize();

Then change some PWM channels to active-low (reversing pin polarity relative to logic polarity) or enable a complementary PWM output (both only on some timer channels).

  // Set channel 1 to complementary with both the regular and complementary output active low
  let mut c1 = c1
      .into_complementary(gpioe.pe8.into_alternate_af1())
      .into_active_low()
      .into_comp_active_low();

  // Set the duty cycle of channel 1 to 50%
  c1.set_duty(c1.get_max_duty() / 2);

  // PWM outputs are disabled by default
  c1.enable()

  // If a PWM fault happened, you can clear it through the control structure
  if control.is_fault_active() {
      control.clear_fault();
  }

Fault (Break) inputs

The PwmBuilder::with_break_pin method emables break/fault functionality as described in the reference manual.

The PwmControl will then implement FaultMonitor which can be used to monitor and control the fault status.

If the break input becomes active, all PWM will be stopped.

The BKIN hardware respects deadtimes when going into the fault state while the BKIN2 hardware acts immediately.

The fault state puts all PWM pins into high-impedance mode, so pull-ups or pull-downs should be used to set the pins to a safe state.

Currently only one break input (BKIN or BKIN2) can be enabled, this could be changed to allow two break inputs at the same time.

Complementary outputs

Once a PWM channel has been created through TIMx.pwm(…) or TIMx.pwm_advanced(…).finalize(), it can be put into complementary mode or have its polarity changed.

Pwm::into_complementary takes a pin that can be used as a complementary output

For allowed pins, see the device datasheet or see which pins implement the NPins trait.

PWM alignment

A timer with multiple PWM channels can have different alignments between PWM channels.

All PWM-capable timers support left aligned PWM. In left aligned PWM, all channels go active at the start of a PWM cycle then go inactive when their duty cycles expire.

Some timers also support right aligned and center aligned PWM. In right aligned PWM, all channels go inactive at the end of a PWM cycle and go active when their duty cycle remains until the end of the PWM cycle.

In center aligned PWM, all channels start inactive, then go active when half their duty cycle remains until the center of the PWM period, then go inactive again once their duty cycle expires and remain inactive for the rest of the PWM cycle. This produces a symmetrical PWM waveform, with increasing duty cycle moving both the inactive and active edge equally. When a component is placed across multiple PWM channels with different duty cycles in center aligned mode, the component will see twice the ripple frequency as the PWM switching frequency.

PWM channel polarity

A PWM channel is active or inactive based on the duty cycle, alignment, etc. However, the actual GPIO signal level that represents active vs inactive is configurable.

The into_active_low and into_active_high methods set the active signal level to low (VSS) or high (VDD).

The complementary output is active when the regular output is inactive. The active signal level of the complementary output is set by the into_comp_active_low, and into_comp_active_high methods.

Deadtime

All channels on a given timer share the same deadtime setting as set by PwmBuilder::with_deadtime

PWM channels with complementary outputs can have deadtime added to the signal. Dead time is used to prevent cross-conduction in some power electronics topologies.

With complementary outputs and dead time enabled on a PWM channel, when the regular output goes inactive (high or low based on into_active_high/into_active_low), the complementary output remains inactive until the deadtime passes. Similarily, when the complementary output goes inactive, the regular output waits until the deadtime passes before it goes active.

Deadtime is applied based on the logical active/inactive levels. Depending on the PWM polarity and complementary polarity, both pins can be high or low during deadtime; they will both be in the inactive state.

The deadtime must be 4032 counts of the timer clock or less or the builder will assert/panic. For a 200MHz timer this is 20 microseconds; slower timers can have even longer deadtimes.

Disabled or faulted state

At initialization, when a PWM channel is disabled, or while a fault is active, the PWM outputs will be in a high impedance state.

If needed, pull-up or pull-down resistors should be used to ensure that all power electronics are in a safe state while the GPIO pins are high impedance.

Although the timers allow quite a bit of configuration here, that would require configuring the PWM pins before configuring other parts of the timer, which would be a challenge with how type states and traits are used for timer configuration.

Additionally, the GPIO will always be high-impedance during power-up or in reset, so pull-ups or pull-downs to ensure safe state are always a good idea.

Structs

Marker struct for active high IO polarity

Marker struct for active low IO polarity

Marker struct for PWM channel 1 on Pins trait and Pwm struct

Marker struct for PWM channel 2 on Pins trait and Pwm struct

Marker struct for PWM channel 3 on Pins trait and Pwm struct

Marker struct for PWM channel 4 on Pins trait and Pwm struct

Marker struct for pins and PWM channels that support complementary output but are not using it

Marker struct for PWM channels that have complementary outputs enabled

Marker struct for pins and PWM channels that do not support complementary output

Marker struct indicating that a PwmControl does not handle fault monitoring

Marker struct indicating that a PwmControl is in charge of fault monitoring

Pwm represents one PWM channel; it is created by calling TIM?.pwm(…) and lets you control the channel through the PwmPin trait

PwmBuilder is used to configure advanced PWM features

Exposes timer wide advanced features, such as FaultMonitor or future features like trigger outputs for synchronization with ADCs and other peripherals

Enums

Whether a PWM signal is left-aligned, right-aligned, or center-aligned

Configuration enum to keep track of which break input corresponds with which FaultPins

Enum for IO polarity

Traits

Allows a PwmControl to monitor and control faults (break inputs) of a timer’s PWM channels

FaultPins is a trait that marks which GPIO pins may be used as PWM fault inputs; it should not be directly used. See the device datasheet ‘Pin descriptions’ chapter for which pins can be used with which timer PWM channels (or look at Implementors)

NPins is a trait that marks which GPIO pins may be used as complementary PWM channels; it should not be directly used. See the device datasheet ‘Pin descriptions’ chapter for which pins can be used with which timer PWM channels (or look at Implementors)

Pins is a trait that marks which GPIO pins may be used as PWM channels; it should not be directly used. See the device datasheet ‘Pin descriptions’ chapter for which pins can be used with which timer PWM channels (or look at Implementors)

Allows the pwm() method to be added to the peripheral register structs from the device crate