STM32F103 timer ile güvenli şekilde PWM oluşturmak - yardım

Başlatan magnetron, 02 Temmuz 2014, 13:24:04

magnetron

merhaba forum

220 Voltu doğrultup STM32F103 ile sürdüğüm H köprüsüyle frekansını (25Hz- 100Hz) ve
duty ( %10 - %70 ) değiştiriyorum

ama 2 defa IRFP460 mosfetlerim patladı

bir tanesi 5 dakka çalıştıktan sonra oldu bir tanesi tam PWM başlarken

demekki STM32F103 PWM çıkışlarını güveni bir şekilde oluşturamıyorum

aşağıdaki kodlarda main döngüsünde analog girişlerden frekans ve duty değerlerini
okuyup frekansı ve dutyi değiştiriyorum

ama nasıl oluyorsa bir an geliyor H ve L mosfetler çakışıyor

bu da TIM8 interrupt ın içinde oluyor mutlaka
burda yaptığı sadece H köprüsünü 1 çaprazdan ötekine geçirmek
ve yeni duty değerini compare registerlere yazmak

nasıl yapmalıyım da TIM8 interrupt içinde
PWM çıkışlarını güvenli bir şekilde çaprazlarım ?
siz bir hata görüyor musunuz ?

teşekkür
not: mosfetlerde snubber var
not: pulsv volatile tanımlandı

kodlarım burda

main {

PWMinit2(void)
.....................
      while(1){
      Delay ( 2000 )
......................
       period=7200000L/freq;puls=(period/100)*dutyv;
        if ((freqold!=freq)||(pulsold!=puls)){
            pulsv=puls;
            TIM_SetAutoreload(TIM8,period);}
        freqold=freq;pulsold=puls; 


void PWMinit2(void){

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


/* Time Base configuration */
  TIM_TimeBaseStructure.TIM_Prescaler = 99;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_Period = 5000;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

  TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

  /* Channel 1, 2,3 and 4 Configuration in PWM mode */
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 4500;
  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(TIM8, &TIM_OCInitStructure);
  TIM_OC2Init(TIM8, &TIM_OCInitStructure);
  
  reset_motor();
  
  /* 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 = 120;
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//Enable;
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;

  TIM_BDTRConfig(TIM8, &TIM_BDTRInitStructure);

  TIM_CCPreloadControl(TIM8, DISABLE);
  TIM_ARRPreloadConfig(TIM8, ENABLE);

  TIM_ITConfig(TIM8, TIM_IT_Update , ENABLE);

  TIM_Cmd(TIM8, ENABLE);
  TIM_CtrlPWMOutputs(TIM8, ENABLE);
  reset_motor();
}

void reset_motor(void){ 
    TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Disable);
    TIM_CCxNCmd(TIM8, TIM_Channel_1, TIM_CCxN_Disable);

    TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Disable);
    TIM_CCxNCmd(TIM8, TIM_Channel_2, TIM_CCxN_Disable);

}


void TIM8_UP_IRQHandler(void){
    TIM_ClearFlag(TIM8, TIM_FLAG_Update);
    TIM_ClearITPendingBit(TIM8, TIM_IT_Update);
    tim8tog++;

    TIM_SetCompare1(TIM8, pulsv);
    TIM_SetCompare2(TIM8, pulsv);
    if (PWMenable){
    if (tim8tog&0x1) {
    TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_OCMode_PWM2);
    TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Enable);
    TIM_CCxNCmd(TIM8, TIM_Channel_1, TIM_CCxN_Enable);

    TIM_SelectOCxM(TIM8, TIM_Channel_2,TIM_ForcedAction_Active);
    TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Disable);
    TIM_CCxNCmd(TIM8, TIM_Channel_2, TIM_CCxN_Enable); }
    else {
    TIM_SelectOCxM(TIM8, TIM_Channel_2, TIM_OCMode_PWM2);
    TIM_CCxCmd(TIM8, TIM_Channel_2, TIM_CCx_Enable);
    TIM_CCxNCmd(TIM8, TIM_Channel_2, TIM_CCxN_Enable);

    TIM_SelectOCxM(TIM8, TIM_Channel_1, TIM_ForcedAction_Active);
    TIM_CCxCmd(TIM8, TIM_Channel_1, TIM_CCx_Disable);
    TIM_CCxNCmd(TIM8, TIM_Channel_1, TIM_CCxN_Enable); }  
}
    else reset_motor();

magnetron

sorumu daraltıyim biraz uzun oldu sanırım

şüphelendiğim yer hakkında yorumlarınız alıyim

şimdi aşağıdaki kod parçası main()  içinde ana döngüde yer alıyor
-----------------------------------------------------------------------
        period=7200000L/freq;puls=(period/100)*dutyv;
        if ((freqold!=freq)||(pulsold!=puls)){
            pulsv=puls;
----------> tam burada TIM8_UP_IRQ interrupt gelirse <----------------         
            TIM_SetAutoreload(TIM8,period);}
        freqold=freq;pulsold=puls;

işte yukardaki 2 satır arasında interrupt gelirse (aslında  SetAuotoreload() fonksiyonu içinde de gelebilir )
puls (compare) ve period değerleri gelen Timer periodunda birbirini tutmuyor

bunu nasıl yapacağım da interrupt tam da orada gelirse timer registerlerin birbirini tutmayan
puls (compare) ve period değeri almasını engelleyeceğim

yorumlarınız lütfen