SVPWM控制是一種控制三相交流電機的方法,它可以實現高效、精確的控制。由于它具有快速響應、低噪聲、高精度等特點,在工業控制、船舶、風力發電、太陽能發電、新能源汽車等領域得到了廣泛的應用。以下是一些應用領域:
**1. ** 變頻空調 : SVPWM控制可以降低功率因數,提高空氣質量,節約能源。
2. 電動船和潛水 器: SVPWM控制可以通過改變電機轉速來改變船或潛水器的速度和方向。
3. 風力發電系統: SVPWM控制可以將變頻器輸出的直流電轉換為交流電,以控制發電機的轉速和輸出功率。
4. 太陽能發電系統: SVPWM控制可以優化光伏逆變器的輸出,最大限度地提高太陽能電池板的能量利用效率。
5. 汽車電動驅動系統: SVPWM控制可以提高電驅動車輛的性能和節能效果,使其具有更好的加速性能和更長的續航里程。
總之,SVPWM控制在許多工業領域和新興領域都具有廣泛的應用前景,其高效、精確的控制特性使其成為一種技術上先進的控制方法。
function [v1, v2, v3] = svpwm(theta, va, vb, vc)
% theta:當前時刻的角度值
% va, vb, vc:三相電壓值
% 轉換輸入電壓為ab、bc、ca軸正向電壓值
va_b = -0.5 * va + 0.5 * sqrt(3) * vb;
va_c = -0.5 * va - 0.5 * sqrt(3) * vb;
vb_c = sqrt(3) * vc;
% 計算電壓矢量的幅值和角度
Vmax = max([va_b va_c vb_c]); % 電壓矢量的最大幅值
theta_tilda = pi/3; % 電壓/電流星型轉換因子
tau = theta_tilda - mod(theta, theta_tilda); % 計算角度離豎直線頂點的偏差
Vm_alpha = Vmax * sin(tau/2); % 電壓矢量在alpha軸上的投影
Vm_beta = Vmax * cos(tau/2); % 電壓矢量在beta軸上的投影
phi = acos(Vm_alpha / Vmax); % 電壓矢量與alpha軸的夾角
% 根據所處的扇區計算PWM信號
if (phi < pi/6)
T1 = Vm_alpha / sin(phi);
T2 = Vm_beta / sin(pi/3 - phi);
v1 = 0.5 * (T1 + T2);
v2 = 0.5 * (T1 - T2);
v3 = -v1 - v2;
elseif (phi < pi/3)
T1 = Vm_beta / sin(phi);
T2 = Vm_alpha / sin(pi/3 - phi);
v1 = 0.5 * (T2 - T1);
v2 = 0.5 * (T2 + T1);
v3 = -v1 - v2;
else
v1 = Vmax / sqrt(3);
v2 = Vmax / sqrt(3);
v3 = Vmax / sqrt(3);
end
這段代碼中,theta是當前時刻的角度值,va、vb、vc是三相電壓值。首先通過對輸入電壓的正向投影獲得各軸正向電壓值,然后計算電壓矢量的幅值和角度,根據所處的扇區計算PWM信號,并最終得到輸出的電壓值v1、v2和v3。需要注意的是,在扇區一和二中,存在一個機電轉動角度(受跨越VRT變化的影響),需要在程序中進行補償。
以下是一份基于TMS320F28035的SVPWM程序代碼:
//--------------------------------- Include Files ---------------------------------
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#include
//--------------------------------- Definitions ---------------------------------
#define Fsw 10000 // SVPWM Switching Frequency (Hz)
#define Vdc 24.0 // DC Bus Voltage (V)
#define PI 3.141592 // Pi Value
//--------------------------------- Global Variables ------------------------------
float Va_REF = 0.0;
float Vb_REF = 0.0;
float Vc_REF = 0.0;
float theta_elec = 0.0;
Uint16 SVPWM_Trip = 0;
//-------------------------------- Function Prototypes -----------------------------
void SVPWM(void);
interrupt void epwm1_isr(void);
//----------------------------------- Main Routine --------------------------------
void main(void)
{
// Initialize system variables
InitSysCtrl();
InitPieCtrl();
//Enable CPU interrupts
DINT;
InitPieVectTable();
EALLOW;
PieVectTable.EPWM1_INT = &epwm1_isr; //Assign ISR address to vector
EDIS;
// Load PWM configuration
InitEPwm1Gpio(); // Initialize EPWM1 GPIO pins
EPwm1Regs.TBPRD = 1500; // 10 kHz PWM frequency
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Enable phase loading
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Set SYNCOUT to zero
EPwm1Regs.TBCTR = 0x0000; // Clear counter
// Set CMPA register to adjust duty cycle
EPwm1Regs.CMPA.half.CMPA = 0;
// Configure timer period
EPwm1Regs.TBPRD = 1500;
// Configure CMPA to generate interrupt when its value matches the counter value
EPwm1Regs.ETSEL.bit.INTEN = 1;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Interrupt on Counter Zero event
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate an interrupt on every event
// Not necessary, but added for clarity
// Enable PWM interrupts
IER |= M_INT3; // Enable INT3 (EPWM1) in IER register
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; // Enable EPWM1 INT in PIE
// Enable global interrupts and start the timer
EINT;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
while(1)
{
// Call SVPWM function to calculate duty cycles
SVPWM();
// Update PWM duty cycles based on reference voltages
EPwm1Regs.CMPA.half.CMPA = Va_REF*750/Vdc + 750;
EPwm1Regs.CMPB = Vb_REF*750/Vdc + 750;
EPwm2Regs.CMPA.half.CMPA = Vc_REF*750/Vdc + 750;
}
}
//------------------------------- Function Definitions ------------------------------
void SVPWM(void)
{
float sin_theta, cos_theta, sector_angle, Va_mag, Vb_mag, Vc_mag, t1, t2, t0;
//Update mechanical angle
theta_elec += 2.0 * PI / (Fsw * 6);
//limit increment of theta between (0,0.99999)
if(theta_elec > 2.0 * PI)
{
theta_elec -= 2.0 * PI;
}
sector_angle = floor(theta_elec * Fsw / (2.0 * PI));
switch((Uint16)sector_angle)
{
case 0: //Sector1 (0 - 60 degrees)
sin_theta = sin(theta_elec);
cos_theta = cos(theta_elec);
Va_mag = (Vdc/sqrt(3))*cos_theta;
Vb_mag = (Vdc/sqrt(3))*(sin_theta*cos(30*PI/180) - cos_theta*sin(30*PI/180));
Vc_mag = -Vb_mag - Va_mag;
break;
case 1: //Sector2 (60 - 120 degrees)
sin_theta = sin(theta_elec - 2.0*PI/3.0);
cos_theta = cos(theta_elec - 2.0*PI/3.0);
Va_mag = (Vdc/sqrt(3))*(sin_theta*cos(30*PI/180) - cos_theta*sin(30*PI/180));
Vb_mag = (Vdc/sqrt(3))*cos_theta;
Vc_mag = -Vb_mag - Va_mag;
break;
case 2: //Sector3 (120 - 180 degrees)
sin_theta = sin(theta_elec - 4.0*PI/3.0);
cos_theta = cos(theta_elec - 4.0*PI/3.0);
Va_mag = -(Vdc/sqrt(3))*cos_theta;
Vb_mag = -(Vdc/sqrt(3))*(sin_theta*cos(30*PI/180) - cos_theta*sin(30*PI/180));
Vc_mag = -Vb_mag - Va_mag;
break;
case 3: //Sector4 (180 - 240 degrees)
sin_theta = sin(theta_elec + PI);
cos_theta = cos(theta_elec + PI);
Va_mag = -(Vdc/sqrt(3))*cos_theta;
Vb_mag = (Vdc/sqrt(3))*(cos_theta*sin(30*PI/180) - sin_theta*cos(30*PI/180));
Vc_mag = -Vb_mag - Va_mag;
break;
case 4: //Sector5 (240 - 300 degrees)
sin_theta = sin(theta_elec + 4.0*PI
評論
查看更多