[mw_shl_code=c,true]#include "p33fxxxx.h"
#include "svm.h"
//---------------------------------------------------------------------
// These are the definitions for various angles used in the SVM
// routine. A 16-bit unsigned value is used as the angle variable.
//用一个16位的无符号数代表角度
// The SVM algorithm determines the 60 degree sector
//SVM算法决定的60°扇区
#define VECTOR1 0 // 0 degrees
#define VECTOR2 0x2aaa // 60 degrees
#define VECTOR3 0x5555 // 120 degrees
#define VECTOR4 0x8000 // 180 degrees
#define VECTOR5 0xaaaa // 240 degrees
#define VECTOR6 0xd555 // 300 degrees
#define SIXTY_DEG 0x2aaa // 60 degrees
//---------------------------------------------------------------------
// This is the maximum value that may be passed to the SVM
// function without overmodulation. This limit is equivalent
// to 0.866, which is sqrt(3)/2.
//最大值可能会超出SVM的极限,这限定了等价输出为0.866,即sin 60°;
#define VOLTS_LIMIT 28300
// This sinewave lookup table has 171 entries. (1024 points per
// electrical cycle -- 1024*(60/360) = 171)
// The table covers 60 degrees of the sine function.
//表格包含60°的正弦函数方程 最大值为32767 2^15
//int sinetable[] __attribute__((far,section(".const,r")))=
const int sinetable[] = //1024/6=171
{0 ,201 ,401 ,602 ,803 ,1003 ,1204 ,1404 ,1605 ,1805 ,2005 ,2206 ,
2406 ,2606 ,2806 ,3006 ,3205 ,3405 ,3605 ,3804 ,4003 ,4202 ,4401 ,4600 ,
4799 ,4997 ,5195 ,5393 ,5591 ,5789 ,5986 ,6183 ,6380 ,6577 ,6773 ,6970 ,
7166 ,7361 ,7557 ,7752 ,7947 ,8141 ,8335 ,8529 ,8723 ,8916 ,9109 ,9302 ,
9494 ,9686 ,9877 ,10068,10259,10449,10639,10829,11018,11207,11395,11583,
11771,11958,12144,12331,12516,12701,12886,13070,13254,13437,13620,13802,
13984,14165,14346,14526,14706,14885,15063,15241,15419,15595,15772,15947,
16122,16297,16470,16643,16816,16988,17159,17330,17500,17669,17838,18006,
18173,18340,18506,18671,18835,18999,19162,19325,19487,19647,19808,19967,
20126,20284,20441,20598,20753,20908,21062,21216,21368,21520,21671,21821,
21970,22119,22266,22413,22559,22704,22848,22992,23134,23276,23417,23557,
23696,23834,23971,24107,24243,24377,24511,24644,24776,24906,25036,25165,
25293,25420,25547,25672,25796,25919,26042,26163,26283,26403,26521,26638,
26755,26870,26984,27098,27210,27321,27431,27541,27649,27756,27862,27967,
28071,28174,28276,28377};
//---------------------------------------------------------------------
// The function SVM() determines which sector the input angle is
// located in. Then, the modulation angle is normalized to the current
// 60 degree sector. Two angles are calculated from the normalized
// angle. These two angles determine the times for the T1 and T2
// vectors. The T1 and T2 vectors are then scaled by the modulation
// amplitude and the duty cycle range. Finally, the T0 vector time
// is the time left over in the PWM counting period.
// The SVM() function then calculates three duty cycle values based
// on the T0, T1, and T2 times. The duty cycle calculation depends
// on the
// appropriate duty cycle values depending on the type of SVM to be
// generated.
//---------------------------------------------------------------------
void SVM(int volts, unsigned int angle)
{ //电压 角度 angle——角度
// These variables hold the normalized sector angles used to find t1, t2.
// 变量 标准化 扇区 角度
unsigned int angle1, angle2;
// These variables hold the space vector times.
// 变量 空间矢量
unsigned int half_t0,t1,t2,tpwm;
// Calculate the total PWM count period, which is twice the value in the PTPER register.
// 两次PTPER寄存器的值计算PWM总数
tpwm = PTPER << 1;
// Limit volts input to avoid overmodulation.
// 限制输入电压,避免过调
if(volts > VOLTS_LIMIT) volts = VOLTS_LIMIT; //最大电压控制到28300
if(angle < VECTOR2) // 0° ~ 59°
{
angle2 = angle - VECTOR1; // Reference SVM angle to the current sector
//angle2 = angle - 0°
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//angle1 = 60°- angle2
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from period and t1,t2
// 计算half_t0
// Calculate duty cycles for Sector 1 (0 - 59 degrees)
// 计算角度在 0 ~ 59° 之间
PDC1 = t1 + t2 + half_t0; //PDC1——PWM占空比寄存器1
PDC2 = t2 + half_t0; //PDC2——PWM占空比寄存器2
PDC3 = half_t0; //PDC3——PWM占空比寄存器3
}
else if(angle < VECTOR3) // 60° ~ 119°
{
angle2 = angle - VECTOR2; // Reference SVM angle to the current secto
//angle2 = angle - 60°
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//angle1 = 60° - angle2
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from
// period and t1,t2
// Calculate duty cycles for Sector 2 (60 - 119 degrees)
// 计算角度在 60 ~ 119° 之间
PDC1 = t1 + half_t0;
PDC2 = t1 + t2 + half_t0;
PDC3 = half_t0;
}
else if(angle < VECTOR4) // 120° ~ 179°
{
angle2 = angle - VECTOR3; // Reference SVM angle to the current sector
//angle2 = angle - 120°
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//angle1 = 60° - angle2
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from
// period and t1,t2
// Calculate duty cycles for Sector 3 (120 - 179 degrees)
// 计算角度在 120 ~ 179° 之间
PDC1 = half_t0;
PDC2 = t1 + t2 + half_t0;
PDC3 = t2 + half_t0;
}
else if(angle < VECTOR5) // 180° ~ 239°
{
angle2 = angle - VECTOR4; // Reference SVM angle to the current sector
//angle2 = angle - 180°
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//angle1 = 60° - angle2
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from
// period and t1,t2
// Calculate duty cycles for Sector 4 (180 - 239 degrees)
// 计算角度在 180 ~ 239° 之间
PDC1 = half_t0;
PDC2 = t1 + half_t0;
PDC3 = t1 + t2 + half_t0;
}
else if(angle < VECTOR6) // 240° ~ 299°
{
angle2 = angle - VECTOR5; // Reference SVM angle to the current sector
//angle2 = angle - 240°
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//angle1 = 60° - angle2
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from
// period and t1,t2
// Calculate duty cycles for Sector 5 (240 - 299 degrees)
// 计算角度在 240 ~ 299° 之间
PDC1 = t2 + half_t0;
PDC2 = half_t0;
PDC3 = t1 + t2 + half_t0;
}
else // 300° ~ 359°
{
angle2 = angle - VECTOR6; // Reference SVM angle to the current sector
//
angle1 = SIXTY_DEG - angle2; // Calculate second angle referenced to sector
//
t1 = sinetable[(unsigned char)(angle1 >> 6)]; // Look up values from table.
// 查表
t2 = sinetable[(unsigned char)(angle2 >> 6)];
// Scale t1 to by the volts variable.
t1 = ((long)t1*(long)volts) >> 15;
// Scale t1 for the duty cycle range.
t1 = ((long)t1*(long)tpwm) >> 15;
// Scale t2 time
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1; // Calculate half_t0 null time from
// period and t1,t2
// Calculate duty cycles for Sector 6 ( 300 - 359 degrees )
PDC1 = t1 + t2 + half_t0;
PDC2 = half_t0;
PDC3 = t1 + half_t0;
}
} // end SVM()
[/mw_shl_code]
|