#include <iostream>
using namespace std;
// svpwm.cpp : Defines the entry point for the console application.
//
typedef int s16;
typedef unsigned u16;
s16 sector_get_table[8] = {
4,1,5,0,3,2,4,4
};
static const s16 sin_table[]= {
0,
286, 572, 857, 1143, 1428,
1713, 1997, 2280, 2563, 2845,
3126, 3406, 3686, 3964, 4240,
4516, 4790, 5063, 5334, 5604,
5872, 6138, 6402, 6664, 6924,
7182, 7438, 7692, 7943, 8192,
8438, 8682, 8923, 9162, 9397,
9630, 9860, 10087, 10311, 10531,
10749, 10963, 11174, 11381, 11585,
11786, 11982, 12176, 12365, 12551,
12733, 12911, 13085, 13255, 13421,
13583, 13741, 13894, 14044, 14189,
14330, 14466, 14598, 14726, 14849,
14968, 15082, 15191, 15296, 15396,
15491, 15582, 15668, 15749, 15826,
15897, 15964, 16026, 16083, 16135,
16182, 16225, 16262, 16294, 16322,
16344, 16362, 16374, 16382, 16384,
};
static const s16 secter_table[6][4] = {
{20066, -11858, 0, 23170},
{-20066, 11585, 20066, 11585},
{0, 23170, -20066, -11585},
{0, -23170, -20066, 11585},
{-20066, -11585, 20066, -11585},
{20066, 11585, 0, -23170},
};
#if 0
static const s16 secter_table[6][4] = {
{20066, -11858, 0, 23170},
{20066, 11585, -20066, 11585},
{0, 23170, -20066, -11585},
{-20066, 11585, 0, -23170},
{-20066, -11585, 20066, -11585},
{0, -23170, 20066, 11585},
};
#endif
static u16 PDC1, PDC2, PDC3;
volatile u16 * const reg_table[6][3]={
{&PDC1, &PDC2, &PDC3},
{&PDC2, &PDC1, &PDC3},
{&PDC2, &PDC3, &PDC1},
{&PDC3, &PDC2, &PDC1},
{&PDC3, &PDC1, &PDC2},
{&PDC1, &PDC3, &PDC2},
};
#define PWM_PTR 2000
s16 out_d =0;
#if 0
void svpwm(u16 ang)
{
int b0,b1,b2,p;
extern u16 tmp_angle;
u16 secter;
const s16 *sect_index;
s16 out_a,out_b, t1,t2,t3, sin, cos;
u16 angle = ang;
s16 out = 640;
if (angle > 359)
angle -= 359;
if (angle >= 270) {
sin = -sin_table[360 - angle];
cos = sin_table[angle - 270];
}else if (angle >= 180) {
sin = -sin_table[angle - 180];
cos = -sin_table[270 - angle];
}else if (angle >= 90) {
sin = sin_table[180 - angle];
cos = -sin_table[angle - 90];
}else {
sin = sin_table[angle];
cos = sin_table[90 - angle];
}
out_a = (out_d * cos - sin* out) >> 14;
out_b = (out_d* sin + cos* out) >> 14;
if (out >=0) angle += 90;
else angle += 270;
if (angle > 359)
angle -= 360;
secter = angle / 60;
b0 = out_b;
b1 = (out_a*867-out_b*512) >> 10;
b2 = (-out_a *867-out_b*512)>>10;
p=0;
if (b0> 0)
p = 1;
if (b1 > 0)
p += 2;
if (b2 > 0)
p += 4;
sect_index = secter_table[secter];
t1 = (out_a * sect_index[0] + out_b * sect_index[1]) >> 14;
t2 = (out_a * sect_index[2] + out_b * sect_index[3]) >> 14;
t3 =1024 - t1 - t2;
/* if (secter%2) {
p = t2;
t2 = t1;
t1 = p;
}*/
printf("%d=%d,%d,%d\n",ang, t1, t2, t3);
/* t1 = t1 * PWM_PTR >> 9;
t2 = t2 * PWM_PTR >> 9;
t3 = t3 * PWM_PTR >> 10;
*reg_table[secter][0] = (t1 + t2 + t3) ;
*reg_table[secter][1] = (t2 + t3) ;
*reg_table[secter][2] = t3 ;
*/
}
#endif
#include <math.h>
void svpwm(u16 ang)
{
int b0,b1,b2,p;
u16 secter;
s16 angle;
double _sin, _cos;
const s16 *sect_index;
double out_a,out_b, t1,t2,t3;
s16 out = 1;
if (ang > 359)
ang -= 359;
_sin = sin((double)(ang*3.1415926/180));
_cos = cos((double)(ang*3.1415926/180));
out_a = out_d * _cos - _sin* out;
out_b = out_d* _sin + _cos* out;
if (out >=0) angle = ang + 90;
else angle = ang + 270;
if (angle > 359)
angle= 360;
secter = angle / 60;
sect_index = secter_table[secter];
t1 = (out_a * sect_index[0] + out_b * sect_index[1])/16384;
t2 = (out_a * sect_index[2] + out_b * sect_index[3])/16384;
t3 =1024 - t1 - t2;
printf("%d=%lf\t%lf\t%lf\n",ang, t1, t2, t1-t2/*t3*/);
/* t1 = t1 * PWM_PTR >> 9;
t2 = t2 * PWM_PTR >> 9;
t3 = t3 * PWM_PTR >> 10;
*reg_table[secter][0] = (t1 + t2 + t3) ;
*reg_table[secter][1] = (t2 + t3) ;
*reg_table[secter][2] = t3 ;
*/}
#define VECTOR1 0
#define VECTOR2 0x2aaa
#define VECTOR3 0x5555
#define VECTOR4 0x8000
#define VECTOR5 0xaaaa
#define VECTOR6 0xd555
#define SIXTY_DEG 0x2aaa
#define PTPER 2000
#define VOLTS_LIMIT 32767//28300
const int sinetable[] =
{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
};
void SVM(int volts, unsigned int angle)
{
unsigned int angle1, angle2;
unsigned int half_t0,t1,t2,tpwm;
tpwm = PTPER << 1;
if(volts > VOLTS_LIMIT)
volts = VOLTS_LIMIT;
if(angle < VECTOR2) {
angle2 = angle - VECTOR1;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = t1 + t2 + half_t0;
PDC2 = t2 + half_t0;
PDC3 = half_t0;
}
else if(angle < VECTOR3) {
angle2 = angle - VECTOR2;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = t1 + half_t0;
PDC2 = t1 + t2 + half_t0;
PDC3 = half_t0;
}
else if(angle < VECTOR4) {
angle2 = angle - VECTOR3;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = half_t0;
PDC2 = t1 + t2 + half_t0;
PDC3 = t2 + half_t0;
}
else if(angle < VECTOR5) {
angle2 = angle - VECTOR4;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = half_t0;
PDC2 = t1 + half_t0;
PDC3 = t1 + t2 + half_t0;
}
else if(angle < VECTOR6) {
angle2 = angle - VECTOR5;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = t2 + half_t0;
PDC2 = half_t0;
PDC3 = t1 + t2 + half_t0;
}
else {
angle2 = angle - VECTOR6;
angle1 = SIXTY_DEG - angle2;
t1 = sinetable[(unsigned char)(angle1 >> 6)];
t2 = sinetable[(unsigned char)(angle2 >> 6)];
t1 = ((long)t1*(long)volts) >> 15;
t1 = ((long)t1*(long)tpwm) >> 15;
t2 = ((long)t2*(long)volts) >> 15;
t2 = ((long)t2*(long)tpwm) >> 15;
half_t0 = (tpwm - t1 - t2) >> 1;
PDC1 = t1 + t2 + half_t0;
PDC2 = half_t0;
PDC3 = t1 + half_t0;
}
}
int main(int argc, char* argv[])
{
int i;
for (i=0; i<=359; i++) {
svpwm(i);
}
/*
for (i=0; i<172*6; i++) {
SVM(32767, i<<6);
printf("%d\t%d\t%d\n", PDC1, PDC2, PDC3);
}
*/
return 0;
}