## Troubles with C

22 posts / 0 new
Author
Message

I am working on a sensorless vector control scheme, I am using a Texas processor but I am having an issue with some code and I just can not see what the hell the problem is

I initialise a table, 720 values making up sinreference with a third harmonic added

No issue here

`float sin_table[721]={0};`

```    for(i>=0; i<=720; i++)
{
sin_table[i]=1.1547*MAXMODINDEX*(sin(i*0.5*PI/180)+sin(3*i*0.5*PI/180)/6.0); //
}```

I use a count n to determine sample time, I update n in an interrupt and call the SPWM function every interrupt

```

void Third_SPWM(count)
{

volatile float theta1= (2*fref*count*TS)*360;
volatile float theta2= (theta1 - 2.0/3.0)*360;
volatile float theta3= (theta1 + 2.0/3.0)*360;

float moda = (fref/FREFMAX)*(sin_table[(int)theta1]);
float modb = (fref/FREFMAX)*(sin_table[(int)theta2]);
float modc = (fref/FREFMAX)*(sin_table[(int)theta3]);
......
........

}```

The above compiles with no error but its not finished, theta1, theta2 and theta3 are actually the number of 0.5 degrees hence with a 720 table it is the index but I need to stop the index being negative or exceeding 720 so I need to make it loop which should be so easy

Theta 2 is lagging theta1 so it can only be negative never more, theta 3 is leading so it will exceed 720 and needs to go back to 0

It should be so easy (in my mind)

```if(theta2<0)
{
theta2=720-theta2;
}

if(theta3>720)
{
theta3=theta3-720;;
}```

But if I try

```volatile float theta1= (2*fref*count*TS)*360;
volatile float theta2= (theta1 - 2.0/3.0)*360;
volatile float theta3= (theta1 + 2.0/3.0)*360;

if(theta2<0)
{
theta2=720-theta2;
}

if(theta3>720)
{
theta3=theta3-720;;
}

float moda = (fref/FREFMAX)*(sin_table[(int)theta1]);
float modb = (fref/FREFMAX)*(sin_table[(int)theta2]);
float modc = (fref/FREFMAX)*(sin_table[(int)theta3]);
......
........

}

```

It unleashes a world of crap

#28 expression must have a constant value

#68 expected a }

and lower down its starts telling me things are not defined when they clearly are

Any help is much appreciated

Which line is #28 and which line is #68?

BTW I know a double negative makes a positive so:

```if(theta2<0)
{
theta2=720-theta2;
}```

should work but personally I'd simply write:

```if (theta2 < 0) {
theta2 += 720;
}```

(BTW spaces around operators cost nothing ;-)

how about the modulus operator?  The modulus is the remainder of a division.

theta2 = theta2 % 720;

no need to have a negative theta, just add the angle so it wraps around again. i.e. for -1 degree, add 718 then do the modulus. Value has wrapped around.

If the modulus is computationally too expensive, think about using a binary angle, then modulus just becomes a bit mask. Thus you might have a 10 bit angle - but this doesn't divide by three too well. Quantify the error and see if it is acceptable.

You might want to read up on the CORDIC technique. This is used for fast trig operations. Was used on the Apollo space computer.

And if you have a table that hold 2 sine waves (1 2/3 I guess will do), then you only need think about 1 phase (the two others are just a+120deg, and a+240deg)

One glaring problem is;

`for(i>=0; i<=720; i++)`

should be;

`for(i=0; i<=720; i++)`

the first part of a for is used to initialize the iterator.

Happy Trails,

Mike

JaxCoder.com

Which line is #28 and which line is #68?

Well line 28 is a space

This is lines 27,28 and 29

```#define MIF    EPwm6Regs.CMPA.half.CMPA

#define EPWM_TIMER_TBPRD	3750	// Set PWM carrier to 20kHz (clk = 150MHZ, TPWM = 2*EPWM_TIMER_TBPR/clk)```

should work but personally I'd simply write:

Yes its better like that

(BTW spaces around operators cost nothing ;-)

=-) I promise I will try in future

More info is required here I think so let me overload you! because I tried to minimise the problem to show the issue

I am trying to do sensorless vector control but this program is just trying to get the sensorless bit work, sensorless means encoderless so instead of actually measuring the motor speed we use a mathematical model, currents and voltages feed in and using a dicrete version of the induction motor dq model we can estimate the speed, its a model reference adaptive system (MRAS observer)

I have done quite a bit on this, I started with this program

```//###########################################################################

//       EPWM1A is on GPIO0 = PORT 8 PIN  9
//       EPWM1B is on GPIO1 = PORT 8 PIN 10
//
//       EPWM2A is on GPIO2 = PORT 8 PIN 11
//       EPWM2B is on GPIO3 = PORT 8 PIN 12
//
//       EPWM3A is on GPIO4 = PORT 8 PIN 13
//       EPWM3B is on GPIO5 = PORT 8 PIN 14
//

//###########################################################################

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include <math.h>
#include "stdio.h"

#define MIA    EPwm1Regs.CMPA.half.CMPA
#define MIB    EPwm2Regs.CMPA.half.CMPA
#define MIC    EPwm3Regs.CMPA.half.CMPA
#define MID    EPwm4Regs.CMPA.half.CMPA
#define MIE    EPwm5Regs.CMPA.half.CMPA
#define MIF    EPwm6Regs.CMPA.half.CMPA

#define EPWM_TIMER_TBPRD	3750	// Set PWM carrier to 20kHz (clk = 150MHZ, TPWM = 2*EPWM_TIMER_TBPR/clk)

//**************************Vector control and MRAS Parameters*****************************************//
#define VDC   24.0
#define Rs    1.899      //1.6 changed
#define Rr    0.918    //0.71
#define Ls    0.02757 //0.0307
#define Lr    0.02757 //0.0307
#define Lm    0.02525 //0.0283
#define POLES 4.0

#define KP    10.0
#define KI    100.0

#define B0_SENSOR_GAIN     0.004310344  //	LEM 6NP through 5k6 and 9k5 divider, 232 counts per amp at ADC 1/232=0.004310344
#define B0_SENSOR_OFFSET   2033.3

#define B1_SENSOR_GAIN     0.004310344
#define B1_SENSOR_OFFSET   2014.9

#define B2_SENSOR_GAIN     0.004310344
#define B2_SENSOR_OFFSET   2026.3

#define TS 0.00005
#define MAXMODINDEX 3750
#define FREFMAX 50.0
#define FREFMIN 10.0

/*------------------------------------------------------Software Filter Coefficients -------------------------------------------*/

/*---------------------------------------------------------------Low Pass ------------------------------------------------------*/
#define                 TAU       0.001              // Software filter time constant
#define                 TS        0.00005              // Software filter sampling period
#define                 C0        TS/(TAU +TS)     // Software filter first coefficient
#define                 C1        TAU/(TAU+TS)     // Software filter second coefficient
/*---------------------------------------------------------------High Pass ------------------------------------------------------*/
#define                TAU2       0.159 //0.02
#define                A0         TAU2/(TAU2+TS)

/*-----------------------------------------------------------------------------------------------------------------------------*/
#define PI 3.14159265358979323846
#define SQRT3  1.73205080756887729353
#define SQRT2  1.414213562
#define PIoverThree    1.047197551196598
#define TwoPIoverThree 2.094395102393196

float phase_voltages[3] ={0};
float phase_currents[3] ={0};

//****************************** HD44780 commands *****************************************/
#define CLEAR        0x01
#define LCD_LINE_0   0x80
#define LCD_LINE_1   0xC0
#define LCD_LINE_2   0x94
#define LCD_LINE_3   0xD4
/******************************************************************************************/

/******************************  HD44780 Port Connections ********************************/
#define LED_TOGGLE       (GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1)  // Port 8 pin 36
#define GPIO33_TOGGLE    (GpioDataRegs.GPBTOGGLE.bit.GPIO33 = 1)  // Port 8 pin 38

#define LCD_RS_HIGH      (GpioDataRegs.GPASET.bit.GPIO26 = 1)     // Port 8 pin 35 high
#define LCD_RS_LOW       (GpioDataRegs.GPACLEAR.bit.GPIO26 = 1)   // Port 8 pin 35 low

#define LCD_E_HIGH       (GpioDataRegs.GPASET.bit.GPIO25 = 1)     // Port 8 pin 34 high
#define LCD_E_LOW        (GpioDataRegs.GPACLEAR.bit.GPIO25 = 1)   // PORT 8 PIN 34 low

#define SET_DAT4         (GpioDataRegs.GPASET.bit.GPIO22 = 1)     // Port 8 pin 33 high
#define CLEAR_DAT4       (GpioDataRegs.GPACLEAR.bit.GPIO22 = 1)   // Port 8 pin 33 low

#define SET_DAT5         (GpioDataRegs.GPASET.bit.GPIO23 = 1)      // Port 8 pin 8 high
#define CLEAR_DAT5       (GpioDataRegs.GPACLEAR.bit.GPIO23 = 1)    // PORT 8 PIN 8 low

#define SET_DAT6         (GpioDataRegs.GPASET.bit.GPIO21 = 1)     // Port 8 pin 7 high
#define CLEAR_DAT6       (GpioDataRegs.GPACLEAR.bit.GPIO21 = 1)   // Port 8 pin 7 low

#define SET_DAT7         (GpioDataRegs.GPASET.bit.GPIO20 = 1)     // Port 8 pin 6 high
#define CLEAR_DAT7       (GpioDataRegs.GPACLEAR.bit.GPIO20 = 1)   // PORT 8 PIN 6 low
/******************************************************************************************/

// Prototype statements for functions found within this file.

void Setup_Function(void);
void GPIO_Setup_Function(void);
void LCD_Init(void);
void LCD_Command (Uint16 command);
void LCD_String(const char*text);
void LCD_Send_Char (Uint16 ch);
void LCD_Send (Uint16 data);
void Setup_EPwm(void);
interrupt void epwm1_isr(void);
void Third_SPWM(volatile int count);
void MRAS(void);
// These are defined by the linker (see F28335.cmd)

extern Uint16 RamfuncsRunStart;

char line0str[21];
char line1str[21];
char line2str[21];
char line3str[21];

volatile Uint16      theta1 = 0;
volatile Uint16      theta2 = 0;
volatile Uint16      sector = 0;
volatile float         fref = FREFMAX;
volatile Uint16        flag = 0;
volatile Uint32           n = 0;
volatile Uint32          nn = 0;
volatile Uint32           m = 0;

volatile Uint32 MAXn = 0;
volatile Uint16 ipeak =0;
volatile Uint16 imin  =2050;

volatile float  ia=0;
volatile float  ib=0;
volatile float  ic=0;

volatile float  vds=0;
volatile float  vqs=0;

volatile float  vds_hp=0;
volatile float  vqs_hp=0;

volatile float  ids=0;
volatile float  iqs=0;

volatile float  ids_hp=0;
volatile float  iqs_hp=0;

volatile float  fdr=0;
volatile float  fqr=0;

volatile float  fdr_hp=0;
volatile float  fqr_hp=0;

volatile float  fdr_est=0;
volatile float  fqr_est=0;

volatile float wr=0.0;
volatile float integral_old=0.0;

//float table1[401]={0};
//float table2[401]={0};
//float table3[401]={0};
void main(void)
{
//Uint16 i=0;
Uint16 k=0;
Setup_Function();
GPIO_Setup_Function();
LCD_Init();
//GpioDataRegs.GPBSET.bit.GPIO33 = 1;

for(;;)
{
if(flag==0)
{
fref = (FREFMAX-FREFMIN)*A2_data/3300 +FREFMIN;

if(fref>=FREFMAX)
{
fref=FREFMAX;
}
else if(fref<=FREFMIN)
{
fref= FREFMIN;
}

float iph  = (1/250.0)*(ipeak-2045.0)/SQRT2;
float rps  = wr/(2*PI);
float rpm  = 60*rps;

sprintf(line0str, "ipeak  is  %.2fA", iph);
sprintf(line1str, "Output Freq %.2fHz", fref);
sprintf(line2str, "wr  %.1f", wr);
sprintf(line3str, "RPM %.1f %.2fHz", rpm,rps);

k=k+1;
if(k>=10)
{
LCD_Init();
k=0;
}

LCD_Command(CLEAR);
DELAY_US(2000);
LCD_Command(LCD_LINE_0);
LCD_String(line0str);
DELAY_US(50);
LCD_Command(LCD_LINE_1);
LCD_String(line1str);
DELAY_US(50);
LCD_Command(LCD_LINE_2);
LCD_String(line2str);
DELAY_US(50);
LCD_Command(LCD_LINE_3);
LCD_String(line3str);
ipeak=0;
imin =2050;
flag  = 1;
}
}

}

interrupt void epwm1_isr(void)

{

Third_SPWM(n);
n=n+1;
SET_DAT5;
MRAS();
MAXn=1.0/(fref*TS);

if(n>=MAXn)
{
n=0;

}

m=m+1;

if(m>=20000)
{
flag=0;
m=0;

}
// Housekeeping at end of ISR

// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
CLEAR_DAT5;
}

void Third_SPWM(count)
{

float theta1= 2*PI*fref*count*TS;
float theta2= 2*PI*fref*count*TS - TwoPIoverThree;
float theta3= 2*PI*fref*count*TS + TwoPIoverThree;

float three_theta = sin(3*theta1);

float moda = 1.1547*MAXMODINDEX*(fref/FREFMAX)*(sin(theta1)+three_theta/6);
float modb = 1.1547*MAXMODINDEX*(fref/FREFMAX)*(sin(theta2)+three_theta/6);
float modc = 1.1547*MAXMODINDEX*(fref/FREFMAX)*(sin(theta3)+three_theta/6);

if (moda>=0)
{
MIA = moda;
MIB = MAXMODINDEX;
phase_voltages[0] = (moda/MAXMODINDEX)*(VDC/2);
}

else
{
MIA=0;
MIB = (MAXMODINDEX+moda);
phase_voltages[0] = (moda/MAXMODINDEX)*(VDC/2);
}

if (modb>=0)
{
MIC = modb;
MID = MAXMODINDEX;
phase_voltages[1] = (modb/MAXMODINDEX)*(VDC/2);
}

else
{
MIC = 0;
MID = MAXMODINDEX+modb;
phase_voltages[1] = (modb/MAXMODINDEX)*(VDC/2);

}

if (modc>=0)
{
MIE = modc;
MIF = MAXMODINDEX;
phase_voltages[2] = (modc/MAXMODINDEX)*(VDC/2);
}

else
{
MIE = 0;
MIF = MAXMODINDEX+modc;
phase_voltages[2] = (modc/MAXMODINDEX)*(VDC/2);
}

}

void MRAS(void)
{

/*
*/

if(B0_data>ipeak)
{
ipeak=B0_data;
}

if(B0_data<imin)
{
imin=B0_data;
}

float ia_new  = C0*B0_SENSOR_GAIN*(B0_data-B0_SENSOR_OFFSET) + C1*ia;
float ib_new  = C0*B1_SENSOR_GAIN*(B1_data-B1_SENSOR_OFFSET) + C1*ib;
float ic_new  = C0*B2_SENSOR_GAIN*(B2_data-B2_SENSOR_OFFSET) + C1*ic;

ia=ia_new;
ib=ib_new;
ic=ic_new;

float vds_new = +C0*((2/3.0)*phase_voltages[0] -(1/3.0)*phase_voltages[1] -(1/3.0)*phase_voltages[2]) +C1*vds;
float vqs_new = +C0*((phase_voltages[1]-phase_voltages[2])/SQRT3)+C1*vqs;

float vds_hp_new = A0*(vds_new-vds+vds_hp);
float vqs_hp_new = A0*(vqs_new-vqs+vqs_hp);

float ids_new = (2*ia_new/3) -(ib_new/3) -(ic_new/3);
float iqs_new = (ib_new-ic_new)/SQRT3;

float ids_hp_new = A0*(ids_new-ids+ids_hp);
float iqs_hp_new = A0*(iqs_new-iqs+iqs_hp);

//reference model
float fdr_new =((Lr/Lm)*(vds_hp_new-Rs*ids_hp_new)*TS +((Ls*Lr-Lm*Lm)/Lm)*(ids_hp-ids_hp_new)) +fdr;//Currents are highpassed here when not required but better performance
float fdr_hp_new = A0*(fdr_new-fdr+fdr_hp);

float fqr_new =(Lr/Lm)*(vqs_hp_new-Rs*iqs_hp_new)*TS +((Ls*Lr-Lm*Lm)/Lm)*(iqs_hp-iqs_hp_new)   +fqr;//Currents are highpassed here when not required but better performance
float fqr_hp_new = A0*(fqr_new-fqr+fqr_hp);

float alpha = Lr/(Lr+TS*Rr);
float beta  = TS*POLES/2;
float gamma = 1/(1-(beta*beta*wr*wr));

float fdr_est_new = gamma*((fdr_est + ids_hp_new*(Lm*Rr/Lr)*TS)-beta*wr*(fqr_est+iqs_hp_new*(Lm*Rr/Lr)*TS));
float fqr_est_new = alpha*(fqr_est + iqs_hp_new*(Lm*Rr/Lr)*TS + beta*wr*fdr_est_new);

float error=(fdr_est_new*fqr_hp_new - fqr_est_new*fdr_hp_new);

float integral_change = KI*error +integral_old;

wr= KP*error + integral_change;
if(wr>=200)
{
wr=200;
}
else if(wr<=-200)
{
wr=-200;
}

integral_old = integral_change;
if(integral_old>200)
{
integral_old=200;
}
if(integral_old<-200)
{
integral_old=-200;
}

vds=vds_new;
vqs=vqs_new;

vds_hp=vds_hp_new;
vqs_hp=vqs_hp_new;

ids=ids_new;
iqs=iqs_new;

ids_hp=ids_hp_new;
iqs_hp=iqs_hp_new;

fdr=fdr_new;
fqr=fqr_new;

fdr_hp=fdr_hp_new;
fqr_hp=fqr_hp_new;

fdr_est=fdr_est_new;
fqr_est=fqr_est_new;
}

void LCD_Command (Uint16 command)
{
LCD_RS_LOW;	// R/S line 0 = command data
LCD_Send(command);         	// send it
}

void LCD_String(const char*text) // display string on LCD
{
LCD_RS_HIGH; 	// R/S line 1 = character data
while(*text)        // do until /0 character
{
LCD_Send(*text++);       	// send it
//LCD_Char(*text++);	// send char & update char pointer
}
}

void LCD_Send_Char (Uint16 ch)
{
LCD_RS_HIGH; 	// R/S line 1 = character data
LCD_Send(ch);       	// send it
}

void LCD_Send (Uint16 data)
{
CLEAR_DAT4;
CLEAR_DAT5;
CLEAR_DAT6;
CLEAR_DAT7;

if	(data &	(1<<4))
{
SET_DAT4;
}

if 	(data &	(1<<5))
{
SET_DAT5;
}
if	(data &(1<<6))
{
SET_DAT6;
}
if(data	&(1<<7))
{
SET_DAT7;
}
LCD_E_HIGH; 	        // LCD enable line high, data is clocked in
DELAY_US(40);      	// wait 40us
LCD_E_LOW; 	            // LCD enable line low

CLEAR_DAT4;
CLEAR_DAT5;
CLEAR_DAT6;
CLEAR_DAT7;

data=(data<<4);

if	(data &	(1<<4))
{
SET_DAT4;
}

if 	(data &	(1<<5))
{
SET_DAT5;
}
if	(data &(1<<6))
{
SET_DAT6;
}
if(data	&(1<<7))
{
SET_DAT7;
}
LCD_E_HIGH; 	        // LCD enable line high, data is clocked in
DELAY_US(40);      	// wait 40us
LCD_E_LOW; 	            // LCD enable line low
}

void LCD_Init()
{
LCD_Command(0x33); 	// initialize controller
LCD_Command(0x32); 	// set to 4	  bit input mode
LCD_Command(0x28);	// 2 line, 5x7 matrix???????????????????????????????????????????????????????????????????????????????????????????
LCD_Command(0x0C); 	// turn cursor off (0x0E to enable)
LCD_Command(0x06); 	// cursor direction = right
DELAY_US(3000);     // wait for LCD to initialize
}

void GPIO_Setup_Function(void)
{   // Each GPIO pin can be:
// a) a GPIO input/output
// b) peripheral function 1
// c) peripheral function 2
// d) peripheral function 3
// By default, all are GPIO Inputs

//GPAMUX1 for functionality GPIO0-GPIO15
//GPAMUX2 for functionality GPIO16-GPIO31
//GPBMUX1 for functionality GPIO32-GPIO47
//GPBMUX2 for functionality GPIO48-GPIO63
//GPCMUX1 for functionality GPIO64-GPIO79
//GPCMUX2 for functionality GPIO80-GPIO95

//GPBDIR for GPIO32-GPIO63
//GPCDIR for GPIO64-GPIO95

//  Mux bits : 00 for GPIO mode : 01 for function 1: 10 for function 2: 11 for function 3 // see table 52, 53, 54 and 55 in SPRUFB0D located here http://www.ti.com.cn/cn/lit/ug/sprufb0d/sprufb0d.pdf
//  Dir bits :0 for input :1 for output                                                   // see table 62 in SPRUFB0D
EALLOW;
// GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
// GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;
//   GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0;
//  GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;

GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;  // LCD DAT7 PORT 8 PIN 6
GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO21 = 1;  // LCD DAT6 PORT 8 PIN 7
GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO23 = 1;  // LCD DAT5 PORT 8 PIN 8
GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO22 = 1;  // LCD DAT4 PORT 8 PIN 33
GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO25 = 1;  // LCD E PORT 8 PIN 34
GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 0;

GpioCtrlRegs.GPADIR.bit.GPIO26 = 1;  // LCD RS PORT 8 PIN 35
GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0;

EDIS;

}

void Setup_Function(void)
{

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2833x_SysCtrl.c file.
InitSysCtrl();
// For this case just init GPIO pins for ePWM1, ePWM2, ePWM3
// These functions are in the DSP2833x_EPwm.c file
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
InitEPwm4Gpio();
InitEPwm5Gpio();
InitEPwm6Gpio();

/*
// Enable TZ4 as a cycle-by-cycle trip source for all PWM channels
EPwm1Regs.TZSEL.bit.CBC4 = 1;
EPwm2Regs.TZSEL.bit.CBC4 = 1;
EPwm3Regs.TZSEL.bit.CBC4 = 1;
EPwm4Regs.TZSEL.bit.CBC4 = 1;
EPwm5Regs.TZSEL.bit.CBC4 = 1;
EPwm6Regs.TZSEL.bit.CBC4 = 1;

// Set all PWM outputs low when trip occurs (i.e. pin TZ4 is pulled low or software forced trip)
// This setting depends on if gate drive has active high or active low inputs
EPwm1Regs.TZCTL.bit.TZA = 0x02;
EPwm1Regs.TZCTL.bit.TZB = 0x02;
EPwm2Regs.TZCTL.bit.TZA = 0x02;
EPwm2Regs.TZCTL.bit.TZB = 0x02;
EPwm3Regs.TZCTL.bit.TZA = 0x02;
EPwm3Regs.TZCTL.bit.TZB = 0x02;
EPwm4Regs.TZCTL.bit.TZA = 0x02;
EPwm4Regs.TZCTL.bit.TZB = 0x02;
EPwm5Regs.TZCTL.bit.TZA = 0x02;
EPwm5Regs.TZCTL.bit.TZB = 0x02;
EPwm6Regs.TZCTL.bit.TZA = 0x02;
EPwm6Regs.TZCTL.bit.TZB = 0x02;

// Force trip to turn off all PWM outputs
EPwm1Regs.TZFRC.bit.OST = 1;
EPwm2Regs.TZFRC.bit.OST = 1;
EPwm3Regs.TZFRC.bit.OST = 1;
EPwm4Regs.TZFRC.bit.OST = 1;
EPwm5Regs.TZFRC.bit.OST = 1;
EPwm6Regs.TZFRC.bit.OST = 1;
*/
// Step 2. Initalize GPIO:
// This example function is found in the DSP2833x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();  // Skipped for this example

// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example.  This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();

// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW;  // This is needed to write to EALLOW protected registers

EDIS;    // This is needed to disable write to EALLOW protected registers

// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash();
// The following function sets ADCCLK to 37.5MHz if CPS = 1 (this is too high as ADCCLK <= 25MHz)

// This code sets ADCCLK to 25MHz (period = 40ns)
// This is based on SYSCLKOUT = 150MHz and therefore HSPCLK = SYSCLKOUT/2 = 150MHz/2 = 75MHz
// SYSCLKOUT = 5 x 30MHz = 150MHz (PLL multiplier = 10/2 = 5, ext clk = 30MHz)

AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;	  // Reset SEQ1/SEQ - instantaneous reset (RST_SEQ1 bit doesn't stay at 1)
//   AdcRegs.ADCTRL2.bit.RST_SEQ2 = 1;	  // Reset SEQ2 - instantaneous reset (RST_SEQ2 bit doesn't stay at 1)

AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;	  // Allows SEQ1/SEQ to be started by ePWM1SOCA trigger
/*

// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
InitFlash();
*/

// For this example, only initialize the ePWM

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;

Setup_EPwm();

EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;

// Step 5. User specific code, enable interrupts:

// Enable CPU interrupts
IER |= M_INT1;	// Enable CPU INT1 which is connected to PIE group 1 (main control ISR)

PieCtrlRegs.PIEIER1.bit.INTx6 = 1;		// Enable ADCINT in the PIE: Group 1 interrupt 6 (i.e. INT1.6)

// Enable global Interrupts and higher priority real-time debug events:
EINT;   // Enable Global interrupt INTM
ERTM;   // Enable Global realtime interrupt DBGM

}

void Setup_EPwm()
{

//############################## EPWM 1 #####################################
//       EPWM1A is on GPIO0 = PORT 8 PIN  9
//       EPWM1B is on GPIO1 = PORT 8 PIN 10
EPwm1Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm1Regs.TBPHS.half.TBPHS = 0x0000;           // Phase is 0

EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;        // Master module
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;    // Sync down-stream module
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW1A
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary

// Set actions
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;             // Set PWM1A on event A, up count
EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR;           // Clear PWM1A on event A, down count

EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;             // Set PWM1B on event B, up count
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;           // Clear PWM1B on event B, down count

// Interrupt where we will change the Compare Values
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;      // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1;                 // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;            // Generate INT on 3rd event
// Set up for ADC SEQ to be triggered from EPwm1

EPwm1Regs.ETSEL.bit.SOCASEL = 0x2;       	   // Pulse generated when TBCTR = TBPRD (Positive apex of carrier)
//   EPwm1Regs.ETSEL.bit.SOCBSEL = 0x2;       	   // Pulse generated when TBCTR = TBPRD (Positive apex of carrier)

//   EPwm1Regs.ETSEL.bit.SOCASEL = 0x1;       	   // Pulse generated when TBCTR = 0 (Negative apex of carrier)

EPwm1Regs.ETPS.bit.SOCACNT = 0x1;       		   // SOCA pulse occurs after one event
//   EPwm1Regs.ETPS.bit.SOCBCNT = 0x1;       		   // SOCB pulse occurs after one event

EPwm1Regs.ETPS.bit.SOCAPRD = 0x1;       		   // SOCA pulse generated on first  event
//   EPwm1Regs.ETPS.bit.SOCBPRD = 0x1;       		   // SOCB pulse generated on first event

EPwm1Regs.ETSEL.bit.SOCAEN = 0x1;       		   // Enable EPWM1SOCA pulse
//   EPwm1Regs.ETSEL.bit.SOCBEN = 0x1;       		   // Enable EPWM1SOCB pulse

//###########################################################################

//############################## EPWM 2 #####################################
//       EPWM2A is on GPIO2 = PORT 8 PIN 11
//       EPWM2B is on GPIO3 = PORT 8 PIN 12

EPwm2Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm2Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;         // Slave module
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;     // Sync flow through
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW2A
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary
// Interrupt where we will change the Compare Values
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
EPwm2Regs.ETSEL.bit.INTEN = 1;                // Enable INT
EPwm2Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event

//###########################################################################

//############################## EPWM 3 #####################################
//       EPWM3A is on GPIO4 = PORT 8 PIN 13
//       EPWM3B is on GPIO5 = PORT 8 PIN 14
EPwm3Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm3Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE;         // Slave module
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;     // Sync flow through
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW3A
EPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary

// Interrupt where we will change the Compare Values
EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
EPwm3Regs.ETSEL.bit.INTEN = 1;                // Enable INT
EPwm3Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event

//############################## EPWM 4 #####################################

EPwm4Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm4Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE;         // Slave module
EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;     // Sync flow through
EPwm4Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW3A
EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary

// Interrupt where we will change the Compare Values
EPwm4Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
EPwm4Regs.ETSEL.bit.INTEN = 1;                // Enable INT
EPwm4Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event

//############################## EPWM 5 #####################################
EPwm5Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm5Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE;         // Slave module
EPwm5Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;     // Sync flow through
EPwm5Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW3A
EPwm5Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm5Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary

// Interrupt where we will change the Compare Values
EPwm5Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
EPwm5Regs.ETSEL.bit.INTEN = 1;                // Enable INT
EPwm5Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event

//############################## EPWM 6 #####################################
EPwm6Regs.TBPRD = EPWM_TIMER_TBPRD;            // Set timer period
EPwm6Regs.TBPHS.half.TBPHS = 0x0000;            // Phase is 0
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric mode
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE;         // Slave module
EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;     // Sync flow through
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET;             // Set actions for EPW3A
EPwm6Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable deadband
EPwm6Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;      // Active high complementary

// Interrupt where we will change the Compare Values
EPwm6Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO;     // Select INT on Zero event
EPwm6Regs.ETSEL.bit.INTEN = 1;                // Enable INT
EPwm6Regs.ETPS.bit.INTPRD = ET_1ST;           // Generate INT on 3rd event
}

```

And it works really well, lots of room for improvement messing around with filter cut offs and PI gains as well as getting better parameters for my motor but this does work

Now in that program I am telling the controller what the phase voltages are by using the modulation index to reconstruct them, theres are errors associated with this and it can get really hairy trying to compensate for deadtime and inverter none linearities, losses etc but in my system I am using an LC filter so I am sending sinusoidal voltages to my machine and hence I can then measure these voltages directly which wouldn't be possible if the motor was being fed PWM pulses

In the above program I am calculating the sin on the fly (the processor has a beefy hardware FPU)

When I alter my program to measure the voltages then it all just takes too long, I need to speed up the code and the first stop is this then the MRAS part next

So far I haven't made much progress

Here is the complete broken program so far (with most of the repeated function deleted for (a little bit of) brevity

```
//###########################################################################

//       EPWM1A is on GPIO0 = PORT 8 PIN  9
//       EPWM1B is on GPIO1 = PORT 8 PIN 10
//
//       EPWM2A is on GPIO2 = PORT 8 PIN 11
//       EPWM2B is on GPIO3 = PORT 8 PIN 12
//
//       EPWM3A is on GPIO4 = PORT 8 PIN 13
//       EPWM3B is on GPIO5 = PORT 8 PIN 14
//

//###########################################################################

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
#include <math.h>
#include "stdio.h"

#define MIA    EPwm1Regs.CMPA.half.CMPA
#define MIB    EPwm2Regs.CMPA.half.CMPA
#define MIC    EPwm3Regs.CMPA.half.CMPA
#define MID    EPwm4Regs.CMPA.half.CMPA
#define MIE    EPwm5Regs.CMPA.half.CMPA
#define MIF    EPwm6Regs.CMPA.half.CMPA

#define EPWM_TIMER_TBPRD	3750	// Set PWM carrier to 20kHz (clk = 150MHZ, TPWM = 2*EPWM_TIMER_TBPR/clk)

//**************************Vector control and MRAS Parameters*****************************************//
#define VDC   24.0
#define Rs    1.899      //1.6 changed
#define Rr    0.918    //0.71
#define Ls    0.02757 //0.0307
#define Lr    0.02757 //0.0307
#define Lm    0.02525 //0.0283
#define POLES 4.0

#define KP    10.0
#define KI    100.0

#define B0_SENSOR_GAIN     0.004310344  //	LEM 6NP through 5k6 and 9k5 divider, 232 counts per amp at ADC 1/232=0.004310344
#define B0_SENSOR_OFFSET   2033.3

#define B1_SENSOR_GAIN     0.004310344
#define B1_SENSOR_OFFSET   2014.9

#define B2_SENSOR_GAIN     0.004310344
#define B2_SENSOR_OFFSET   2026.3

#define B3_SENSOR_OFFSET   2052.0

#define A3_SENSOR_OFFSET   2060.0

#define B4_SENSOR_OFFSET   2054.0

#define A4_SENSOR_OFFSET   2056.0

#define TS 0.00005
#define MAXMODINDEX 3750
#define FREFMAX 50.0
#define FREFMIN 10.0

/*------------------------------------------------------Software Filter Coefficients -------------------------------------------*/

/*---------------------------------------------------------------Low Pass ------------------------------------------------------*/
#define                 TAU       0.001              // Software filter time constant
#define                 TS        0.00005              // Software filter sampling period
#define                 C0        TS/(TAU +TS)     // Software filter first coefficient
#define                 C1        TAU/(TAU+TS)     // Software filter second coefficient
/*---------------------------------------------------------------High Pass ------------------------------------------------------*/
#define                TAU2       0.159 //0.02
#define                A0         TAU2/(TAU2+TS)

/*-----------------------------------------------------------------------------------------------------------------------------*/
#define PI 3.14159265358979323846
#define SQRT3  1.73205080756887729353
#define SQRT2  1.414213562
#define PIoverThree    1.047197551196598
#define TwoPIoverThree 2.094395102393196

float phase_voltages[3] ={0};
float phase_currents[3] ={0};

//****************************** HD44780 commands *****************************************/
#define CLEAR        0x01
#define LCD_LINE_0   0x80
#define LCD_LINE_1   0xC0
#define LCD_LINE_2   0x94
#define LCD_LINE_3   0xD4
/******************************************************************************************/

/******************************  HD44780 Port Connections ********************************/
#define LED_TOGGLE       (GpioDataRegs.GPBTOGGLE.bit.GPIO32 = 1)  // Port 8 pin 36
#define GPIO33_TOGGLE    (GpioDataRegs.GPBTOGGLE.bit.GPIO33 = 1)  // Port 8 pin 38

#define LCD_RS_HIGH      (GpioDataRegs.GPASET.bit.GPIO26 = 1)     // Port 8 pin 35 high
#define LCD_RS_LOW       (GpioDataRegs.GPACLEAR.bit.GPIO26 = 1)   // Port 8 pin 35 low

#define LCD_E_HIGH       (GpioDataRegs.GPASET.bit.GPIO25 = 1)     // Port 8 pin 34 high
#define LCD_E_LOW        (GpioDataRegs.GPACLEAR.bit.GPIO25 = 1)   // PORT 8 PIN 34 low

#define SET_DAT4         (GpioDataRegs.GPASET.bit.GPIO22 = 1)     // Port 8 pin 33 high
#define CLEAR_DAT4       (GpioDataRegs.GPACLEAR.bit.GPIO22 = 1)   // Port 8 pin 33 low

#define SET_DAT5         (GpioDataRegs.GPASET.bit.GPIO23 = 1)      // Port 8 pin 8 high
#define CLEAR_DAT5       (GpioDataRegs.GPACLEAR.bit.GPIO23 = 1)    // PORT 8 PIN 8 low

#define SET_DAT6         (GpioDataRegs.GPASET.bit.GPIO21 = 1)     // Port 8 pin 7 high
#define CLEAR_DAT6       (GpioDataRegs.GPACLEAR.bit.GPIO21 = 1)   // Port 8 pin 7 low

#define SET_DAT7         (GpioDataRegs.GPASET.bit.GPIO20 = 1)     // Port 8 pin 6 high
#define CLEAR_DAT7       (GpioDataRegs.GPACLEAR.bit.GPIO20 = 1)   // PORT 8 PIN 6 low
/******************************************************************************************/

// Prototype statements for functions found within this file.

void Setup_Function(void);
void GPIO_Setup_Function(void);
void LCD_Init(void);
void LCD_Command (Uint16 command);
void LCD_String(const char*text);
void LCD_Send_Char (Uint16 ch);
void LCD_Send (Uint16 data);
void Setup_EPwm(void);
interrupt void epwm1_isr(void);
void Third_SPWM(volatile int count);
void MRAS(void);
// These are defined by the linker (see F28335.cmd)

extern Uint16 RamfuncsRunStart;

char line0str[21];
char line1str[21];
char line2str[21];
char line3str[21];

volatile Uint16      theta1 = 0;
volatile Uint16      theta2 = 0;
volatile Uint16      sector = 0;
volatile float         fref = FREFMAX;
volatile Uint16        flag = 0;
volatile Uint32           n = 0;
volatile Uint32          nn = 0;
volatile Uint32           m = 0;

volatile Uint32 MAXn = 0;
volatile Uint16 ipeak =0;
volatile Uint16 imin  =2050;
volatile Uint16 vpeak =0;
volatile Uint16 vmin  =2050;

volatile float  ia=0;
volatile float  ib=0;
volatile float  ic=0;

volatile float  vph_a=0;
volatile float  vph_b=0;
volatile float  vph_c=0;

volatile float  vph_a_hp=0;
volatile float  vph_b_hp=0;
volatile float  vph_c_hp=0;

volatile double vdc_bus=0;

volatile float  vds=0;
volatile float  vqs=0;

volatile float  vds_hp=0;
volatile float  vqs_hp=0;

volatile float  ids=0;
volatile float  iqs=0;

volatile float  ids_hp=0;
volatile float  iqs_hp=0;

volatile float  fdr=0;
volatile float  fqr=0;

volatile float  fdr_hp=0;
volatile float  fqr_hp=0;

volatile float  fdr_est=0;
volatile float  fqr_est=0;

volatile float wr=0.0;
volatile float integral_old=0.0;

float sin_table[721]={0};

void main(void)
{
Uint32 i=0;
Uint16 k=0;
Setup_Function();
GPIO_Setup_Function();
LCD_Init();
for(i>=0; i<=720; i++)
{
sin_table[i]=1.1547*MAXMODINDEX*(sin(i*0.5*PI/180)+sin(3*i*0.5*PI/180)/6.0); //
}

for(;;)
{
if(flag==0)
{
fref = (FREFMAX-FREFMIN)*A2_data/3300 +FREFMIN;

if(fref>=FREFMAX)
{
fref=FREFMAX;
}
else if(fref<=FREFMIN)
{
fref= FREFMIN;
}

float iph  = (1/250.0)*(ipeak-2045.0)/SQRT2;
float rps  = wr/(2*PI);
float rpm  = 60*rps;
float vph  = B3_SENSOR_GAIN*(vpeak-B3_SENSOR_OFFSET)/SQRT2;

sprintf(line0str, "%.2fA RMS %.2fV DC", iph, vdc_bus);
sprintf(line1str, "%.1f rad/s %.2fHz", wr, fref);
sprintf(line2str, "Va %.2f VAC RMS",vph);
sprintf(line3str, "RPM %.1f", rpm);

k=k+1;
if(k>=10)
{
LCD_Init();
k=0;
}

/*
LCD_Command(CLEAR);
DELAY_US(2000);
LCD_Command(LCD_LINE_0);
LCD_String(line0str);
DELAY_US(50);
LCD_Command(LCD_LINE_1);
LCD_String(line1str);
DELAY_US(50);
LCD_Command(LCD_LINE_2);
LCD_String(line2str);
DELAY_US(50);
LCD_Command(LCD_LINE_3);
LCD_String(line3str);
ipeak=0;
imin =2050;
vpeak=0;
vmin =2050;*/
flag  = 1;
}
}

}

interrupt void epwm1_isr(void)

{

Third_SPWM(n);
MRAS();

n=n+1;
MAXn=1.0/(fref*TS);

if(n>=MAXn)
{
n=0;

}

m=m+1;

if(m>=20000)
{
flag=0;
m=0;
}
// Housekeeping at end of ISR

// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;

}

void Third_SPWM(count)
{

volatile float theta1= (2*fref*count*TS)*360
volatile float theta2= (theta1 - 2.0/3.0)*360;
volatile float theta3= (theta1 + 2.0/3.0)*360;

if(theta2<0)
{
theta2=(720-theta2);
}

int moda = (fref/FREFMAX)*(sin_table[(int)theta1]);
int modb = (fref/FREFMAX)*(sin_table[(int)theta2]);
int modc = (fref/FREFMAX)*(sin_table[(int)theta3]);

if (moda>=0)
{
MIA = moda;
MIB = MAXMODINDEX;
//phase_voltages[0] = (moda/MAXMODINDEX)*(VDC/2);
}

else
{
MIA=0;
MIB = (MAXMODINDEX+moda);
//phase_voltages[0] = (moda/MAXMODINDEX)*(VDC/2);
}

if (modb>=0)
{
MIC = modb;
MID = MAXMODINDEX;
//phase_voltages[1] = (modb/MAXMODINDEX)*(VDC/2);
}

else
{
MIC = 0;
MID = MAXMODINDEX+modb;
//phase_voltages[1] = (modb/MAXMODINDEX)*(VDC/2);

}

if (modc>=0)
{
MIE = modc;
MIF = MAXMODINDEX;
//phase_voltages[2] = (modc/MAXMODINDEX)*(VDC/2);
}

else
{
MIE = 0;
MIF = MAXMODINDEX+modc;
//phase_voltages[2] = (modc/MAXMODINDEX)*(VDC/2);
}

}

void MRAS(void)
{

if(B0_data>ipeak)
{
ipeak=B0_data;
}

if(B0_data<imin)
{
imin=B0_data;
}

if(B3_data>vpeak)
{
vpeak=B3_data;
}

if(B3_data<vmin)
{
vmin=B3_data;
}

double vdc_bus_new = C0*A4_SENSOR_GAIN*(A4_data - A4_SENSOR_OFFSET) + C1*vdc_bus;

double   vph_a_new = C0*B3_SENSOR_GAIN*(B3_data - B3_SENSOR_OFFSET) + C1*vph_a;
double   vph_b_new = C0*A3_SENSOR_GAIN*(A3_data - A3_SENSOR_OFFSET) + C1*vph_b;
double   vph_c_new = C0*B4_SENSOR_GAIN*(B4_data - B4_SENSOR_OFFSET) + C1*vph_c;

double   vph_a_hp_new = A0*(vph_a_new-vph_a+vph_a_hp);
double   vph_b_hp_new = A0*(vph_b_new-vph_b+vph_b_hp);
double   vph_c_hp_new = A0*(vph_c_new-vph_c+vph_c_hp);

float ia_new  = C0*B0_SENSOR_GAIN*(B0_data-B0_SENSOR_OFFSET) + C1*ia;
float ib_new  = C0*B1_SENSOR_GAIN*(B1_data-B1_SENSOR_OFFSET) + C1*ib;
float ic_new  = C0*B2_SENSOR_GAIN*(B2_data-B2_SENSOR_OFFSET) + C1*ic;

ia=ia_new;
ib=ib_new;
ic=ic_new;

float vds_new = +C0*((2/3.0)*vph_a_hp_new -(1/3.0)*vph_b_hp_new -(1/3.0)*vph_c_hp_new) +C1*vds;
float vqs_new = +C0*((vph_b_hp_new-vph_c_hp_new)/SQRT3)+C1*vqs;

float vds_hp_new = A0*(vds_new-vds+vds_hp);
float vqs_hp_new = A0*(vqs_new-vqs+vqs_hp);

float ids_new = (2*ia_new/3) -(ib_new/3) -(ic_new/3);
float iqs_new = (ib_new-ic_new)/SQRT3;

float ids_hp_new = A0*(ids_new-ids+ids_hp);
float iqs_hp_new = A0*(iqs_new-iqs+iqs_hp);

//reference model
float fdr_new =((Lr/Lm)*(vds_hp_new-Rs*ids_hp_new)*TS +((Ls*Lr-Lm*Lm)/Lm)*(ids_hp-ids_hp_new)) +fdr;//Currents are highpassed here when not required but better performance
float fdr_hp_new = A0*(fdr_new-fdr+fdr_hp);

float fqr_new =(Lr/Lm)*(vqs_hp_new-Rs*iqs_hp_new)*TS +((Ls*Lr-Lm*Lm)/Lm)*(iqs_hp-iqs_hp_new)   +fqr;//Currents are highpassed here when not required but better performance
float fqr_hp_new = A0*(fqr_new-fqr+fqr_hp);

float alpha = Lr/(Lr+TS*Rr);
float beta  = TS*POLES/2;
float gamma = 1/(1-(beta*beta*wr*wr));

float fdr_est_new = gamma*((fdr_est + ids_hp_new*(Lm*Rr/Lr)*TS)-beta*wr*(fqr_est+iqs_hp_new*(Lm*Rr/Lr)*TS));
float fqr_est_new = alpha*(fqr_est + iqs_hp_new*(Lm*Rr/Lr)*TS + beta*wr*fdr_est_new);

float error=(fdr_est_new*fqr_hp_new - fqr_est_new*fdr_hp_new);

float integral_change = KI*error +integral_old;

wr= KP*error + integral_change;
if(wr>=200)
{
wr=200;
}
else if(wr<=-200)
{
wr=-200;
}

integral_old = integral_change;
if(integral_old>200)
{
integral_old=200;
}
if(integral_old<-200)
{
integral_old=-200;
}

vph_a=vph_a_new;
vph_b=vph_b_new;
vph_c=vph_c_new;

vph_a_hp=vph_a_hp_new;
vph_b_hp=vph_b_hp_new;
vph_c_hp=vph_c_hp_new;

vds=vds_new;
vqs=vqs_new;

vds_hp=vds_hp_new;
vqs_hp=vqs_hp_new;

ids=ids_new;
iqs=iqs_new;

ids_hp=ids_hp_new;
iqs_hp=iqs_hp_new;

fdr=fdr_new;
fqr=fqr_new;

fdr_hp=fdr_hp_new;
fqr_hp=fqr_hp_new;

fdr_est=fdr_est_new;
fqr_est=fqr_est_new;
}

```

That if statement breaks it and I do not have a clue how it could

how about the modulus operator?  The modulus is the remainder of a division.

theta2 = theta2 % 720;

no need to have a negative theta, just add the angle so it wraps around again. i.e. for -1 degree, add 718 then do the modulus. Value has wrapped around.

If the modulus is computationally too expensive, think about using a binary angle, then modulus just becomes a bit mask. Thus you might have a 10 bit angle - but this doesn't divide by three too well. Quantify the error and see if it is acceptable.

You might want to read up on the CORDIC technique. This is used for fast trig operations. Was used on the Apollo space computer.

Nice tip on the modulus operator Kartman, I never thought of that before but it does make sense, I will definitely look at this, it makes sense for sure

I don't want to go all out trying to avoid floats and make the code as efficient as possible not because I am not interested in that but because I want the code easy (for me at least) to read, its just an academic pursuit

I have seen the CORDIC thing before and in fact I have a hard copy of 'Numerical Recipes in C', its an old book i don't know if you have ever seen it but its right up my street, in the future I will explore this book much deeper but I just don't have the time yet

And if you have a table that hold 2 sine waves (1 2/3 I guess will do), then you only need think about 1 phase (the two others are just a+120deg, and a+240deg)

Thats exactly what I am doing, its one table for phase A reference, but that phase A has a third harmonic added to gain the extra voltage, you might ask why no SVM? well thats because I tried and failed that one, this is a three level inverter and SVM for multilevel inverters proved many times more difficult than for a standard two level inverter, I spnt two weeks trying and there are all these algorithms out there but if you try and write a C program that uses all the states then it was just too much for my brain so in the name of progress I reverted back to third harmonic injection, I will revisit it after I have made some progress because its essential, I think SVM with common mode voltage elimination looks easier which is where I am heading

Thanks for the input chaps, I really don't know why that if statement breaks the code so badly

Last Edited: Fri. May 22, 2015 - 02:08 PM

The reason I asked about lines #28 and #68 is because you said the errors were:

#28 expression must have a constant value

#68 expected a }

I guess I sort of assumed those were source file line numbers but maybe the compiler is trying to say something else? Perhaps they are just error numbers?

What I was trying to get at was WHICH line is reported as "expression must have a constant value"? (most such restrictions are lifted in C99 by the way).

Sorry cliff I posted the # part because I thought maybe its useful to someone!

The offending lines

int moda = (fref/FREFMAX)*(sin_table[(int)theta1]);   //#68 expected a }, #28 expression must have a constant value
int modb = (fref/FREFMAX)*(sin_table[(int)theta2]);  //#28 expression must have a constant value
int modc = (fref/FREFMAX)*(sin_table[(int)theta3]);  //#28 expression must have a constant value

It also says theta 3 is undefined!

most such restrictions are lifted in C99 by the way

Well correct me if I am wrong but if you aren't doing C99 and later then you know about it?, I am using code composer studio V5 so surely these restrictions have been lifted (long ago?)

What do the offending lines look like after pre-processing?

(most compilers will let you see the pre-pro output if invoked with -E)

I'd suspect that something in either those lines you show (FREFMAX for example?) is a macro with a wonky defintion or at the point of definition for theta[1..3] something there (TS perhaps?) is not what you think it should be.

Alternatively these mod[a..c] lines are just suffering from corruption on previous lines that finally becomes evident when the compiler hits these lines.

clawson wrote:
What do the offending lines look like after pre-processing?

Good suggestion.

Quote:
(most compilers will let you see the pre-pro output if invoked with -E)

With GCC, use -save-temps

https://www.avrfreaks.net/comment...

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

clawson wrote:

The reason I asked about lines #28 and #68 is because you said the errors were:

#28 expression must have a constant value

#68 expected a }

I guess I sort of assumed those were source file line numbers

That would seem a fair assumption to me

Quote:
but maybe the compiler is trying to say something else? Perhaps they are just error numbers?

And that's the trouble with posting in the wrong forum!

The OP said he's using a TI processor; so it would have made far more sense to have posted in a TI forum - where people are going to be familiar with the formats of the messages from the TI compiler!!

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

What do the offending lines look like after pre-processing?

(most compilers will let you see the pre-pro output if invoked with -E)

=(

I dont know how to do this, theres so many tabs and settings its quite depressing, I can see the build console but I dont think this is what you are talking about

I tried

float theta1= (2*25*count*0.00005)*360;
float theta2= (theta1 - 2.0/3.0)*360;
float theta3= (theta1 + 2.0/3.0)*360;

if(theta2<0)
{
theta2=(720-theta2);
}

int moda = (25/50)*(sin_table[(int)theta1]);
int modb = (25/50)*(sin_table[(int)theta2]);
int modc = (25/50)*(sin_table[(int)theta3]);

Same if I eliminate count too and set it constant

WTF!

With GCC, use -save-temps

True that is one way but it's not the only way:

```\$ cat avr.c
#include <avr/io.h>

#define FOO (3 * 7)

int main(void) {
PORTB = FOO;
}
\$ avr-gcc -E -c -mmcu=atmega16 avr.c -o avr.i
\$ tail -n 7 avr.i
# 2 "avr.c" 2

int main(void) {
(*(volatile uint8_t *)((0x18) + 0x20)) = (3 * 7);
}
\$
```

Last Edited: Fri. May 22, 2015 - 03:32 PM

And that's the trouble with posting in the wrong forum!

 Compilers and General Programming A forum for discussions about compilers and general programming topics not specifically related to a particular microcontroller.

Oh please, dude don't even go there

Have you seen the state of those forums?, the answer isn't over there I am afraid, it actually makes no sense at allnto post it over there

Sorry for being a n00b on you here but why do we need to limit the forum?, I am using a TI processor because thats the hardware, I will be using an AVR very soon to do comms, speed measurement and load torque control so think of this as a step towards that if you absolutely need everything to be Atmel related

The way I seen it is this is a C programming question but maybe I was wrong and its a compiler issue in that instance please forgive my n00b-ish-ness but at least I learnt something

Last Edited: Fri. May 22, 2015 - 03:36 PM

BTW It was a TI compiler I used in the last 4..5 years that did NOT clear .bss in its default CRT - be warned and watch out for such things.

BTW It was a TI compiler I used in the last 4..5 years that did NOT clear .bss in its default CRT - be warned and watch out for such things.

=)

Cliff I hate it!, its been the worst thing in the world to get working on Windows 8, but the hardware is very good, excellent in fact so its worth the learning, the chip is actually very good I do like it but that above comment really trouble me, I have no idea what not clearin .bss in default CRT means but it sounds bad!

At least I wasn't totally insane and I can actually write an if statement, I was worried for a minute

I will go for the modulus solution, let me try that

Don't talk to me about TI Code Composer. It's really just Eclipse but it tends to split the debugging as a foreground and background process. Often I would have it crash the foreground but then lose communication to the back end that then had the debug hardware "locked". Often a Windows reboot (certainly a lot messing with Task Manager) would be the only solution to get things talking. This did not make for a happy development cycle.

Are you able to say what CPU? I was using a TI VisionMid which is a Davinci vision processor. TI don't actually admit to the device I used on their public website but this comes pretty close:

http://www.ti.com/general/docs/d...

That's a 1.2GHz Cortex A8 with a 1GHz DSP and a number of video co-processors. The silicon also had a couple of Cortex M3's on it to mop up some of the control stuff for the video sub-systems.

This was pretty much about as powerful as was then available at the time (which was kind of the point - what we do is about as CPU intensive as embedded applications get!)

Its this development board Cliff

http://uk.farnell.com/spectrum-d...

Pricetag is ridiculous but the chip modest compared to what you describe, its the hardware that my university provide which is the thing for me, the board plugs into my kit and its great otherwise I would of been using another chip ages ago, its no fun blowing these things up, no fun at all and its not even my money that goes up!

The processor is good but I get loads of crap, losing connections, power fail on CPU, emulator issues you name it

I heard a newer version of my chip does single cycle trig functions, and loads of other stuff

what we do is about as CPU intensive as embedded applications get

Driverless vehicles I believe, yeah thats an amazing thing to work on, thing is though as AMS's long term main boffin () work is just a pass time =-)

Last Edited: Fri. May 22, 2015 - 04:16 PM

Hey--

Y'all can take your praise of TI microcontrollers elsewhere.  The same with the "praise" for the tools.  Why should gurus who choose to hang out here in effect provide support for a different brand?

I should report this to a moderator.  Oh, wait..

[I vote the whole thread be deleted, or at the least sent to off-topic.]

the hardware is very good, excellent in fact so its worth the learning, the chip is actually very good I do like it

Since you think it is appropriate, please list the areas in which that processor is "more excellent" [sic] than the ones discussed on this site.  Please cite specific line items, and the references for both sides.

I'll start:

http://www.maximintegrated.com/e...

Table1 and Table 2 ... which is more excellent?

Then, after reading about the flaws in TI's study, closely examine table 3 and Table 4 and again tell which is more excellent.

Finally, repeat with Table 7.  Note the iterations per second normalized, and at Fmax.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. May 22, 2015 - 07:28 PM

Lee

The hardware I am talking about interfaces with the ezdsp and all my sensors connect to it, its a very good design

its the hardware that my university provide which is the thing for me, the board plugs into my kit and its great otherwise I would of been using another chip ages ago

The TI chip is good but its too much money to start raving about but while we are here the chip is a TMS320 32bit DSP, not an MSP430 so I think the link is redundant and off topic!

Last Edited: Fri. May 22, 2015 - 08:15 PM

I doubt Atmel want to pay for the support of competitors products. Conversely, if you posted an Atmel issue on the Ti forums you would get'fresh aired' or quickly stopped.

Just some commenta about the code- it's full of complex equations, globals and very few comments. I gather you just 'wrote' the code rather than 'design' the code. There's a big difference. Some of the problems you might encounter when debugging your code is a 'numerical explosion' in that a defect causes an illegal value to propagate through your code and what comes out is not what you wanted. This is a common problem when using floats. With all your globals, you're going to have a hell of a time finding out where it started.
Your function MRAS takes no parameters and returns nothing. You read the adc values in your function - how would you test this function without hardware? How would you simulate this function?
Generally you'd write and test such a function on your PC so you can simulate and graph responses etc. on your target you'd want to put in the function header what it does, what it expects and what it returns. Then in your code you have ASSERTs that print out an error message or do something useful to alert you that an input was out of range or something went wrong. In the production code, the asserts are #defined to nothing and do not generate any code. Adopt these strategies and your code will tell you where it went wrong and for what reason. You'll debug in a tenth of the time and use the F* word less. Never kid yourself about the complexity of this stuff - if it were mechanical there would be thousands of spinning bits all interacting at millions of rpm.

clawson wrote:
BTW I know a double negative makes a positive so:

```if(theta2<0)
{
theta2=720-theta2;
//  theta2> 720   skeeve
}```

should work but personally I'd simply write:

```if (theta2 < 0) {
theta2 += 720;
}
```

Also, 25/50 is zero.

Iluvatar is the better part of Valar.