Quick actions

cmd+k|ctrl+k

Navigation

Languages

svpwm.cpp

Snippet info

Language

Cpp

Visibility

public

Author

jiemnij

Created

2017-07-03T00:13:01Z

Updated

2017-07-03T00:13:12Z

#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;
}

INFO