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

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

spirtless

12 Mayıs 2018, 18:04:39 Son düzenlenme: 12 Mayıs 2018, 18:07:26 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.


Kod Seç
#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_artisornek_sayisi=50duty_kazanc=1;
double sin_Usin_Vsin_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_COMPLEMENTARYPWM_COMPLEMENTARYPWM_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_RUN10POWER_PWM_PERIOD01,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?