PWM phase shift

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
simone.c
Posts: 2
Joined: Mon Oct 20, 2014 3:41 pm

PWM phase shift

Post by simone.c »

Hi I'm using the STM32f3discovery. I have generate 6 pwm signals but they are in phase. How can I shift them?
My code is the follow:

Code: Select all

#include "ch.h"
#include "hal.h"

static uint32_t DUTY=5000;

static PWMConfig pwmcfg = {
  1000000,                                    /* 100kHz PWM clock frequency.   */
  1000,                                    /* Initial PWM period 1S. (Numero colpi di clock di un periodo       */
  NULL,
  {
   {PWM_OUTPUT_ACTIVE_HIGH, NULL},
   {PWM_OUTPUT_ACTIVE_HIGH, NULL},
   {PWM_OUTPUT_ACTIVE_HIGH, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
};


static PWMConfig pwmcfg_neg = {
  1000000,                                    /* 10kHz PWM clock frequency.   */
  1000,                                    /* Initial PWM period 1S. (Numero colpi di clock di un periodo       */
  NULL,
  {
   {PWM_OUTPUT_ACTIVE_LOW, NULL},
   {PWM_OUTPUT_ACTIVE_LOW, NULL},
   {PWM_OUTPUT_ACTIVE_LOW, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
};


int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();


  pwmStart(&PWMD2,&pwmcfg);
   palSetPadMode(GPIOA, 0, PAL_MODE_ALTERNATE(1));
   palSetPadMode(GPIOA,1,PAL_MODE_ALTERNATE(1));
   palSetPadMode(GPIOA,2,PAL_MODE_ALTERNATE(1));
   chThdSleepMilliseconds(100);


  pwmStart(&PWMD3,&pwmcfg_neg);
  palSetPadMode(GPIOC, 6, PAL_MODE_ALTERNATE(2));
  palSetPadMode(GPIOC, 7, PAL_MODE_ALTERNATE(2));
  palSetPadMode(GPIOC, 8, PAL_MODE_ALTERNATE(2));

    chThdSleepMilliseconds(1000);




   pwmEnableChannel(&PWMD2, 0, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, DUTY));
   pwmEnableChannel(&PWMD2, 1, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, DUTY));
   pwmEnableChannel(&PWMD2, 2, PWM_PERCENTAGE_TO_WIDTH(&PWMD2, DUTY));

   pwmEnableChannel(&PWMD3,0, PWM_PERCENTAGE_TO_WIDTH(&PWMD3, DUTY));
   pwmEnableChannel(&PWMD3,1, PWM_PERCENTAGE_TO_WIDTH(&PWMD3, DUTY));
   pwmEnableChannel(&PWMD3,2, PWM_PERCENTAGE_TO_WIDTH(&PWMD3, DUTY));
   chThdSleepMilliseconds(10000);







}



thanks to your availability.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: PWM phase shift

Post by Giovanni »

Hi,

The channels of a same PWM are always aligned by design, the STM32 internal timer does not allow to generate shifted signal.

There could a possibility about the channels belonging to different timers, the timers support a master/slave mode and it is *apparently* possible to start a slave timer at a fixed counter offset from the master one. There is this note in the manual:

In this example both timers are initialized before starting (by setting their respective UG
bits). Both counters starts from 0, but you can easily insert an offset between them by
writing any of the counter registers (TIMx_CNT). You can see that the master/slave mode
insert a delay between CNT_EN and CK_PSC on timer 1.


I never tested this so can't help but you could read the paragraph "Starting 2 timers synchronously in response to an external trigger" in the STM32 Reference Manual and decide if it is a solution for your problem.

The PWM driver itself has no support for that mode so a custom driver will be probably required.

Giovanni
Post Reply