AnsweredAssumed Answered

STM32F4 Complementary PWM doesn't run correctly

Question asked by pham.minh on Jan 19, 2015
Latest reply on Jan 20, 2015 by pham.minh

Can anyone help me? 
I'm using STM32F407VG Discovery for my LLC Fulbridge DC-DC Charger. Today I have some troubles with Complementary TIM1 PWM. I config Channel1,1N,3,3N for it. The problem is that somehow these pulses gets overlaped, like the pictures attached below, highly likely making my converter shortcircuited. I wonder maybe the process of updating Timer_Period, Pulse_Channel, and DeadTime causes this problem. 
Can anyone have trouble like this, or someone knows the solution, please help me!!

TIM2 is used for Interrupt. The overlap occurs after the SoftStart has already been done and turned into the Controller Cal_Ir(). 


void main(void)
{
          SysTick_Config(SystemCoreClock / 5000000);


          InitializeLcm();
          Init();
    while(1)
    {
          Display_LCD();
    }
}


void TIM2_IRQHandler(void)
{
          count++;
          if(count>20000)
          {
                   count = 0;
                   STM_EVAL_LEDToggle(LED3);
          }
          GPIOC->ODR ^= LED;

          if(count>100)
                   {
                             ADC_Start = 1;
                   }
          if(!ADC_Start) return;

// read ADC
          Read_ADC();

//        Soft_Start();
          if (Soft_Start_Done > 0)
          {
                   Soft_Start();
                   TIM2->SR = (uint16_t)~TIM_IT_Update;
                   return;
          }

          Cal_Ir();
// clear bit Timer
          TIM2->SR = (uint16_t)~TIM_IT_Update; // Clear interrup flag
}

 

void Cal_Ir()
{
          Fx = (double)(Fx - 4e-2*k);
          if (Fx < Fx_Min)
          {
                   Fx = (double) Fx_Min;
                   k = -k;
          }
          else if (Fx > Fx_Max)
          {
                   Fx = (double) Fx_Max;
                   k = -k;
          }

          Timer_Period         = (double) (Period_Res / Fx);
          Channel_Pulse      = (double) (Timer_Period * 0.5);
          Dead_Time            = (double) (Channel_Pulse * (1 - 2 * Duty));
          TIM1_PWM_Freq_Update();
}

void Soft_Start(void)
{
          if (Soft_Start_Time >  0) Soft_Start_Time--;
          else 
          {
                   Dead_Time -= 0.0005; 
                   if (Dead_Time < 30) Soft_Start_Done = 0;
          }

          TIM1_PWM_Freq_Update_SoftStart();
}

 

static void TIM1_Configuration(void)
{
          /* Time Base configuration */
          TIM_TimeBaseStructure.TIM_Prescaler                            = 1;
          TIM_TimeBaseStructure.TIM_CounterMode                    = TIM_CounterMode_Up;
          TIM_TimeBaseStructure.TIM_Period                      = Timer_Period;
//        TIM_TimeBaseStructure.TIM_ClockDivision                    = TIM_CKD_DIV1;
          TIM_TimeBaseStructure.TIM_RepetitionCounter   = 0; // update event is generated at each counter overflow
          TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
          TIM1->CR1 |= TIM_CR1_ARPE; // Set the ARR Preload Bit


          /* Channel 1, 3 Configuration in PWM mode */
          TIM_OCInitStructure.TIM_OCMode             = TIM_OCMode_PWM2;
          TIM_OCInitStructure.TIM_OutputState        = TIM_OutputState_Enable;
          TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
          TIM_OCInitStructure.TIM_Pulse                  = Channel_Pulse;
          TIM_OCInitStructure.TIM_OCPolarity         = TIM_OCPolarity_High; 
          TIM_OCInitStructure.TIM_OCNPolarity       = TIM_OCNPolarity_High; 
          TIM_OCInitStructure.TIM_OCIdleState        = TIM_OCIdleState_Reset;
          TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
          TIM_OC1Init(TIM1, &TIM_OCInitStructure);
          TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
          TIM_OC3Init(TIM1, &TIM_OCInitStructure);
          TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

          /* Automatic Output enable, Break, dead time and lock configuration*/
          TIM_BDTRInitStructure.TIM_OSSRState     = TIM_OSSRState_Enable;
          TIM_BDTRInitStructure.TIM_OSSIState      = TIM_OSSIState_Enable;
          TIM_BDTRInitStructure.TIM_LOCKLevel   = TIM_LOCKLevel_OFF;
          TIM_BDTRInitStructure.TIM_DeadTime      = Dead_Time;
          TIM_BDTRInitStructure.TIM_Break             = TIM_Break_Disable;
          TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
          TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);

          /* TIM1 counter enable */
          TIM_Cmd(TIM1, ENABLE);//1Tcy
}


void TIM1_PWM_Freq_Update(void)
{
          tmpbdtr = TIM1->BDTR;
          tmpbdtr &= 0xFF00;
          tmpbdtr |= (uint8_t) Dead_Time;
          tmparr         = (uint16_t) Timer_Period;
          tmpccr         = (uint16_t) Channel_Pulse;
          TIM1->ARR  = tmparr;
          TIM1->CCR3         = tmpccr;
          TIM1->CCR1         = tmpccr;
          TIM1->BDTR         = tmpbdtr;
}


void TIM1_PWM_Freq_Update_SoftStart(void)
{
          tmpbdtr = TIM1->BDTR;
          tmpbdtr &= 0xFF00;
          tmpbdtr |= (uint8_t) Dead_Time;
          TIM1->BDTR         = tmpbdtr;
}

In the scope below, channel 1,3 corresponds to PA8, PB13 as TIM1 PWM Channel1,1N; channel 2,4 corresponds to PA10, PB15 as TIM1 PWM Channel 3,3N

Untitled.gif

Attachments

Outcomes