Pic ile V/F servo kontrolü pwm problemi

spirtless

Üye
Katılım
25 May 2009
Mesajlar
45
Puanları
1
Yaş
36
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.Ayrıca arada bir pwm 0 oluyor. Bunu nasıl çözerim. Muhtemelen kod diziliminde bir hata yapıyorum.Hatayı nerede 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);
}
}
 
#use delay(clock=200000000)
pic 200 mhz demi çalışıyor. burada yanlışlık olmasın.
 
20 Mhz onu buraya yanlış yazmışım. Doğrusu böyle;
#use delay(clock=20000000)
 

Forum istatistikleri

Konular
127,958
Mesajlar
913,910
Kullanıcılar
449,606
Son üye
rasit.

Yeni konular

Geri
Üst