Using TIM1 of stm32f4 to generate 3 pwms and their complimentary pwms

Hi

I need to generate 3 pwms and their complementary signals using TIM1 of stm32f4. The stm32f4xx_hal has example for generating 1 pwm and it's complementary. When I try to use multiple channels (CH1, CH1N; CH2, CH2N; CH3, CH3N) of TIM1 in the following manner,

  // PWM Channel setup
       let channels_one: hal::timer::ChannelBuilder<TIM1, 0, true>= Channel1::new(gpioa.pa8).with_complementary(gpioa.pa7); //signal1
       let channels_two: hal::timer::ChannelBuilder<TIM1, 1, true> = Channel2::new(gpioe.pe11).with_complementary(gpioe.pe10); //signal2
       let channels_three: hal::timer::ChannelBuilder<TIM1, 2, true> = Channel3::new(gpioe.pe13).with_complementary(gpioe.pe12); //signal3
        
       let mut pwm1 = dp.TIM1.pwm_hz(channels_one, 100.kHz(), &clocks);
       let mut pwm2 = dp.TIM1.pwm_hz(channels_two, 100.kHz(), &clocks);
       let mut pwm3 = dp.TIM1.pwm_hz(channels_three, 100.kHz(), &clocks);

I get the following issue:

use of moved value: `dp.TIM1`
move occurs because `dp.TIM1` has type `TIM1`, which does not implement the `Copy` trait rustc Click for full compiler diagnostic
main.rs(44, 23): value moved here

I am still new with RUST and struggling to figure out concepts. Grateful to any help!

Thank you

The issue must be here. I guess that pwm_hz takes ownership of self, so you can only use your "TIM1" in "dp" once.

In order to make your code work, you'll need to clone TIM1:

let mut pwm1 = dp.TIM1.clone().pwm_hz(channels_one, 100.kHz(), &clocks);
let mut pwm2 = dp.TIM1.clone().pwm_hz(channels_two, 100.kHz(), &clocks);
       let mut pwm3 = dp.TIM1.pwm_hz(...

Sorry for not being more helpful. I'm on the mobile and I haven't checked your library's API :sweat_smile:

1 Like

TIM1 represents a hardware resource, it can only be configured once, you cannot configure it multiple times. the key is, you build up your configuration beforehand and configure it in a single step.

I'm not familiar with STM32 microcontrollers, but looking at the documentation, you probably should do it like this:

let channels_one: hal::timer::ChannelBuilder<TIM1, 0, true> =
    Channel1::new(gpioa.pa8).with_complementary(gpioa.pa7); //signal1
let channels_two: hal::timer::ChannelBuilder<TIM1, 1, true> =
    Channel2::new(gpioe.pe11).with_complementary(gpioe.pe10); //signal2
let channels_three: hal::timer::ChannelBuilder<TIM1, 2, true> =
    Channel3::new(gpioe.pe13).with_complementary(gpioe.pe12); //signal3

let (mut pwm1, mut pwm2, mut pwm3) = dp
    .TIM1
    .pwm_hz(
        (channels_one, channel_two, channel_three),
        100.kHz(),
        &clocks,
    )
    .split();
2 Likes

Thank you @moy2010

1 Like

Thank you @nerditation

1 Like