Vektör kontrolü ile Servo Sürücü geliştirmesi

Başlatan spirtless, 12 Mayıs 2018, 15:04:39

spirtless

Arkadaşlar merhaba,
Bir süredir PMSM motor sürücüsü için uğraşıyorum. Şuana kadar pcb donanımı hazır ancak yazılım konusunda bir noktada tıkandım. Yapacağım uygulama pozisyon kontrolü olacaktır.  Daha o noktaya gelemeden pwm konusunda tıkandım. Vektör kontrolü yapmaya çalışıyorum. Pwm duty nin hiç durmadan %8-%92 arasında değişmesi lazım.Ben arada pwm in 0 olduğunu da görüyorum. Ayrıca kodun açıklamasına göre pwm değerlerini girdiğimde çok farklı değerler görüyorum. Mesela %92 duty oranına göre değer verdiğimde %15 gibi duty görüyorum. Muhtemelen kod diziliminde bir hata yapıyorum. Bu konuda yorumlarınız nedir?
Bunu çözdükten sonra pozisyon bilgisi alt programını ekleyeceğim.


#include<18F4431.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOLVP
#use delay(clock=200000000)

setup_oscillator(OSC_20MHZ); 

  #include <math.h>
  #include "float.h"
  #include "math.h"
  #include "stdlib.h" 
  #include "stdio.h" 
  

#define POWER_PWM_PERIOD 332
/*********************************** 
freq= Fosc / (4*(period + 1) * postscale) 
or 
period = (Fosc /( 4 * freq * postscale)) -1 

if we want 15khz 
period =( 20mhz /(4 * 15khz * 1) -1 
peroid = 332; 
*****************************************/ 


double U_faz_aci=(0), V_faz_aci=((180)/3), W_faz_aci=((2*180)/3);
float motor_frekans=50,max_motor_frekans=50,pwm_frekansi=15000; 
double aci_artis, ornek_sayisi=50, duty_kazanc=1;
double sin_U, sin_V, sin_W,duty_U,duty_V,duty_W;
float32 rad=PI/180.0;
 
void main()
{
  
// Setup the 4 Power PWM channels as ordinary pwm channels.
//setup_power_pwm_pins(PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON, PWM_ODD_ON);
//  setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY, PWM_COMPLEMENTARY, PWM_OFF);
  setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_COMPLEMENTARY, PWM_COMPLEMENTARY, PWM_COMPLEMENTARY);
// Mode = Free Run 
// Postscale = 1  (1-16) Timebase output postscaler
// TimeBase = 0  (0-65355) Initial value of PWM Timebase
// Period = 2000  (0-4095) Max value of PWM TimeBase
// Compare = 0    (Timebase value for special event trigger)
// Compare Postscale = 1 (Postscaler for Compare value)
// Dead Time

  setup_power_pwm(PWM_FREE_RUN, 1, 0, POWER_PWM_PERIOD, 0, 1,0); 
//  setup_power_pwm(PWM_CLOCK_DIV_4 | PWM_FREE_RUN |  PWM_DEAD_CLOCK_DIV_16,1,10000,1000,0,1,30);
    set_power_pwm0_duty(0);
    set_power_pwm2_duty(0);
    set_power_pwm4_duty(0);
          
  while(TRUE)
  {
        
                                                                      //Hız düştükçe V/f oranını sbit tutmak için basılan gücü düşür
        duty_kazanc=(motor_frekans/max_motor_frekans)*(0.92)*1;    // kazanç sabitleyici (V/f sabit tutmak için)

                                                                    // Belli bir orandan sonra artık V/f sabit değil. Duty ratio değerini sabitle
        if(duty_kazanc<(0.2))
        {
        duty_kazanc=0.2;
        }
            //Duty ratio değerini limitle
      if(duty_kazanc>(0.92))
      {
      duty_kazanc=0.92;
        }
                                                                  // anahtarlama frekansını ulaşılmak istenilen hız değerine bölerek örnekleme sayısını bul
      ornek_sayisi=(pwm_frekansi/motor_frekans);                //örnekleme sayısı
      aci_artis = ((180)/ornek_sayisi);                          // örnwkleme sayısını kullanarak oluşturulacak sinüs değerinin açısal artışını bul

      u_faz_aci=u_faz_aci+aci_artis;                            // fazlardaki sinüsün açısını arttır
      if(u_faz_aci>(180))
      {
      u_faz_aci=u_faz_aci-(180);                                // fazlardaki sinüsün açısını baştan başlat
      }
 
      if(u_faz_aci<(180/3))
      {
      v_faz_aci=(180/3)+u_faz_aci;
      w_faz_aci=((2*180)/3)+u_faz_aci;
      }

      else if ((u_faz_aci>=(180/3)) && (u_faz_aci<((2*180)/3)))
      {

      v_faz_aci=(180/3)+u_faz_aci;
      w_faz_aci=u_faz_aci-(180/3);
      }

      else if ((u_faz_aci>=((2*180)/3)) && (u_faz_aci<=(180)))
      {

      v_faz_aci=u_faz_aci-((2*180)/3);
      w_faz_aci=u_faz_aci-(180/3);
      } 
                                  
      sin_U=(sin(u_faz_aci*rad))*duty_kazanc;                // pwm genlik değeri(U)
      sin_V=(sin(v_faz_aci*rad))*duty_kazanc;                //  pwm genlik değeri(V)
      sin_W=(sin(w_faz_aci*rad))*duty_kazanc;                //  pwm genlik değeri(W)
 
      if(sin_U<(0.08))
      {
        sin_U=0.08;
      } 
      if(sin_U>(0.92))
      {
        sin_U=0.92;
      }
      if(sin_V<(0.08))
      {
        sin_V=0.08;
      } 
      if(sin_V>(0.92))
      {
        sin_V=0.92;
      }
      if(sin_W<(0.08))
      {
        sin_W=0.08;
      } 
      if(sin_W>(0.92))
      {
        sin_W=0.92;
      }
 
        duty_U=4*POWER_PWM_PERIOD*sin_U;
        duty_V=4*POWER_PWM_PERIOD*sin_V;
        duty_W=4*POWER_PWM_PERIOD*sin_W; 
        
        set_power_pwm0_duty(duty_U);
        set_power_pwm2_duty(duty_V);
        set_power_pwm4_duty(duty_W);            
  }  
  }


spirtless

Yorum yapacak veya yardımcı olabilecek kimse yok mudur?