AnsweredAssumed Answered

STM32F429 3 phases PWM signal with inverted delayed output

Question asked by karpavicius.linas on Oct 12, 2015
Hello, i am making simple 3 phase BLDC driver with STM32F429-disco

Right now i get 6 output working with correct phase shift. Problem is, where is no dead time between inverted and non inverted PWM output. And my MOSFET driver for tens of nanoseconds short high side, and low side MOSFET's, and they heat up quite badly.

This is the code with bruit force sinus modulation of PWM signal ( later i would use DMA triggered by timer to copy CCRx registers with data)

#include "stm32f4xx.h"
#include "math.h"
void TIM_Config(void);
 
 
void Delay(uint32_t a)
{
  while(a)
  {
    a--;
    asm("nop");
  }
}
 
float a = 0.5f;
 
 
uint16_t Phase_A[4096];
uint16_t Phase_B[4096];
uint16_t Phase_C[4096];
 
float speed = 5000;
float speed2 = 5000;
 int main(void)  
{
  Delay(0xFFFF);
  TIM_Config();
  uint32_t i=0;
  while(i<4096)
  {
    Phase_A[i]=(uint16_t)(500.0f*(1+sinf((6.2831853f*i/4096.0f))));
    Phase_B[i]=(uint16_t)(500.0f*(1+sinf(((6.2831853f*i)/4096.0f)+2.0943f)));
    Phase_C[i]=(uint16_t)(500.0f*(1+sinf(((6.2831853f*i)/4096.0f)+4.1887f)));
    i++;
  }
  i=0;
  while(1)
  {
    while(i<4096)
    {
       
      TIM1->CCR1=(uint16_t)(Phase_A[i]*a);
      TIM1->CCR2=(uint16_t)(Phase_B[i]*a);
      TIM1->CCR3=(uint16_t)(Phase_C[i]*a);
      i++;
      Delay((uint32_t)speed);
      if(speed>speed2)
        speed-=0.01f;
      if(speed<speed2)
        speed+=0.01f;
    }
    i=0;
  }
}
 
 
 
 
 
void TIM_Config(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
      
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
  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_DOWN ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
  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_DOWN ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13;
  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_DOWN ;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
   
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM1); // PWM Generation CH1N
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM1); // PWM Generation CH2N
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM1); // PWM Generation CH3N
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1); // PWM Generation CH1
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);// PWM Generation CH2
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);// PWM Generation CH3
   
  TIM_TimeBaseStructure.TIM_Prescaler = 1;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 1000;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
 
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 500;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
 
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_Pulse = 500;
   
  TIM_OC2Init(TIM1, &TIM_OCInitStructure);
 
  TIM_OCInitStructure.TIM_Pulse = 500;
  TIM_OC3Init(TIM1, &TIM_OCInitStructure);
   
  TIM_ARRPreloadConfig(TIM1, ENABLE);
  TIM_Cmd(TIM1, ENABLE);
  TIM_CtrlPWMOutputs(TIM1, ENABLE);
  TIM_Cmd(TIM1, ENABLE);
}

How can I generate signal, where i have a bit dead time between CH1 and CH1N ( aka both are low for few nanoseconds) ?

Outcomes