AnsweredAssumed Answered

stm32f407 pwm control both dutycycle and phase shift

Question asked by zarks.con on Dec 14, 2014
Latest reply on Dec 22, 2014 by zarks.con

I'm new with the stm32f407 discovery board and I'm trying to make 4 signals which I can control phase shift and dutycycle. The thing is, when i set my timer on PWM mode I can't control phase shift between channel_1 and channel_2. I know I have to use interrupts but I can't figure out what i should code inside it. I would be grateful if you could help me.

Here is my code, I use one interrupt which switches on/off a LED every some time (the delay is not well synchronized yet).


/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "misc.h"
#include "stm32f4xx_tim.h"
#include "stm32f4xx_usart.h"
#include "delay.h"
 
/* Private typedef -----------------------------------------------------------*/
GPIO_InitTypeDef  GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
TIM_OCInitTypeDef  TIM_OCInitStructure;
 
/* Private define ------------------------------------------------------------*/
#define frequency 42500
 
/* Private macro -------------------------------------------------------------*/
 
/* Private variables ---------------------------------------------------------*/
int Prescaler = 0;
int Period = 84000000 / frequency; // ~42.5KHz
int pulse_width;
/* Private function prototypes -----------------------------------------------*/
void GPIO_Config(void);
void PWM_Config(void);
void PWM_SetDC(int channel,int dutycycle);
void Delay(__IO int nCount);
void LED_Config(void);
 
/* Private functions ---------------------------------------------------------*/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
{
 
    Delay(10000000);
 
    GPIO_ToggleBits(GPIOD, GPIO_Pin_15);
 
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
}
/**
  * Main program
  */
int main(void)
{
 
 
  /* GPIO Configuration */
  GPIO_Config();
 
  LED_Config();
 
  /* PWM Configuration */
  PWM_Config();
 
  PWM_SetDC(1,80);
  PWM_SetDC(2,40);
  PWM_SetDC(3,0);
  PWM_SetDC(4,0);
 
  while (1)
  {
 
  }
}
 
/**
  * Configure the TIM2 Output Channels.
  */
void GPIO_Config(void)
{
 
  NVIC_InitTypeDef NVIC_InitStructure;
  /* Enable the TIM2 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
  /* TIM2 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
 
  /* GPIOA clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
 
  GPIO_InitTypeDef GPIO_InitStructure;
  /* GPIOC Configuration: TIM2 CH1 (PA0), TIM2 CH2 (PA1), TIM2 CH3 (PA2), TIM2 CH4 (PA3) */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
 
  /* Connect TIM2 pins to AF2 */
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_TIM2);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM2);
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM2);
 
}
 
void PWM_Config(void)
{
 
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = Period - 1;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
 
  TIM_ARRPreloadConfig(TIM2, ENABLE);
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
 
  /* PWM1 Mode configuration: Channel1 */
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OC1Init(TIM2, &TIM_OCInitStructure);
  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
 
  ////////////////////////* TIM INTERRUPT enable *////////////////////////////
  TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
  ////////////////////////////////////////////////////////////////////////////
 
  /* PWM1 Mode configuration: Channel2 */
//  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OC2Init(TIM2, &TIM_OCInitStructure);
  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
 
  /* PWM1 Mode configuration: Channel3 */
//  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OC3Init(TIM2, &TIM_OCInitStructure);
  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
 
  /* PWM1 Mode configuration: Channel4 */
//  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OC4Init(TIM2, &TIM_OCInitStructure);
  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
 
  /* TIM2 enable counter */
    TIM_Cmd(TIM2, ENABLE);
}
 
void PWM_SetDC(int channel,int dutycycle)
{
    if (dutycycle <= 100 && dutycycle >= 0)
    {
        pulse_width=(Period*dutycycle)/100;
          if (channel == 1)
          {
            TIM2->CCR1 = pulse_width;
 
          }
          else if (channel == 2)
          {
 
            TIM2->CCR2 = pulse_width;
          }
          else if (channel == 3)
          {
            TIM2->CCR3 = pulse_width;
          }
          else
          {
            TIM2->CCR4 = pulse_width;
          }
    }
}
 
void LED_Config(void)
{
  /* GPIOD Peripheral clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
 
  /* Configure PD12, PD13, PD14 and PD15 in output push-pull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
 
}
 
/* Delay Function.
 * nCount:specifies the Delay time length.
 */
void Delay(__IO int nCount)
{
  while(nCount--)
  {
  }
}

Outcomes