2016-06-19 07:46 AM
Hello to everyone, i am building an old project with STM32F107 now.
I am trying to calculate the SVPWM values on the fly but seems like compiler's code is so long.I am running on 72MHz.The fuction below needs around 60-65 usec,which is too much to fit on 20Khz timing.I am using KEIL uvision 5 and 3lvl optimization.float THETA;int SECTOR=0;float Ua=0;float Ub=0;float Uc=0;float PI=3.14;float T=0.0000625; // 16kHzfloat MAXMODINDEX = 2250;volatile float n=0;volatile float i=0;float FREF =50;int MAXn;//--------------------------------//void SVPWM(int count){__disable_irq(); THETA= 2*PI*FREF*count*T;SECTOR = THETA/(PI/3); Ua = (FREF/50)*sinf((PI/3)-(THETA-SECTOR*(PI/3)));Ub = (FREF/50)*sinf(THETA-SECTOR*(PI/3));Uc = 1.0-Ua-Ub;switch(SECTOR) { case 0: TIM3->CCR1 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ub + 0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(0.5*Uc); break; case 1: TIM3->CCR1 = MAXMODINDEX*(Ua + 0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(0.5*Uc); break; case 2: TIM3->CCR1 = MAXMODINDEX*(0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ub + 0.5*Uc); break; case 3: TIM3->CCR1 = MAXMODINDEX*(0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + 0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); break; case 4: TIM3->CCR1 = MAXMODINDEX*(Ub + 0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); break; case 5: TIM3->CCR1 = MAXMODINDEX*(Ua + Ub + 0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + 0.5*Uc); break; default: break; } __enable_irq(); }2016-06-20 09:18 PM
I made some changes and now the calculation times is about 40usec.I think next step is to caclulate only Ub with sinf() and use it to calculate Ua,cause theere been an trigonometric connection between them.
Thats the 40usec code:#define F 10000.0f // 10kHz#define T 1.0f/F #define PI_2_T 2.0f*PI*T#define PI 3.141592ffloat MAXMODINDEX = 3600;float THETA;float SECTOR=0;float Ua=0;float Ub=0;float Uc=0;float FREF =50.0f;void SVPWM(int count){__disable_irq(); THETA= PI_2_T*FREF*count; SECTOR = THETA/(PI/3.0f);Ua = (FREF * (1.0f/50.0f))*sinf((PI/3.0f) - (THETA - (float)SECTOR * (PI/3.0f))); Ub = (FREF * (1.0f/50.0f))*sinf(THETA - (float)SECTOR * (PI/3.0f)); Uc= 1.0f-Ua-Ub;switch((int)SECTOR) { case 0: TIM3->CCR1 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ub + (float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*((float)0.5*Uc); break; case 1: TIM3->CCR1 = MAXMODINDEX*(Ua + (float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*((float)0.5*Uc); break; case 2: TIM3->CCR1 = MAXMODINDEX*((float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ub + (float)0.5*Uc); break; case 3: TIM3->CCR1 = MAXMODINDEX*((float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*(Ua + (float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); break; case 4: TIM3->CCR1 = MAXMODINDEX*(Ub + (float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*((float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); break; case 5: TIM3->CCR1 = MAXMODINDEX*(Ua + Ub + (float)0.5*Uc); TIM3->CCR2 = MAXMODINDEX*((float)0.5*Uc); TIM3->CCR3 = MAXMODINDEX*(Ua + (float)0.5*Uc); break; default: break; } __enable_irq(); }