#include"foc.h"
void RevParkOperate(float vd, float vq, float theta, float* valpha, float*vbeta){
*valpha = vd * cos(theta) - vq * sin(theta);
*vbeta = vd * sin(theta) + vq * cos(theta);
}
unsigned char SectorJude(float valpha, float vbeta){
float A = vbeta;
float B = valpha * sqrt3/2.0f - vbeta/2.0f;
float C = -valpha * sqrt3/2.0f - vbeta/2.0f;
unsigned char N = 0;
if(A > 0) N += 1;
if(B > 0) N += 2;
if(C > 0) N += 4;
return N;
}
void VectorActionTime(uint8_t n, float valpha, float vbeta, uint32_t udc, uint32_t tpwm, float* ta, float*tb){
float X = (sqrt3 * tpwm)/ udc * vbeta;
float Y = (sqrt3 * tpwm)/ udc * ((sqrt3/2.0f)*valpha - vbeta/2.0f);
float Z = (sqrt3 * tpwm)/ udc *(-(sqrt3/2.0f)*valpha - vbeta/2.0f);
switch(n){
case 3: *ta = Y; *tb = X; break;
case 1: *ta = -Y; *tb = -Z; break;
case 5: *ta = X; *tb = Z; break;
case 4: *ta = -X; *tb = -Y; break;
case 6: *ta = Z; *tb = Y; break;
case 2: *ta = -Z; *tb = -X; break;
}
}
void CCRCalculate(uint8_t n, float ta, float tb, uint32_t tpwm, uint32_t*ccr1, uint32_t*ccr2, uint32_t*ccr3){
float temp = ta + tb;
if(temp > tpwm){ ta = ta / temp*tpwm; tb = tb / temp*tpwm; }
float value1 = (tpwm - ta - tb)/4.0f;
float value2 = value1 + ta/2.0f;
float value3 = value2 + tb/2.0f;
switch(n){
case 3: *ccr1 = value1; *ccr2 = value2; *ccr3 = value3; break;
case 1: *ccr1 = value2; *ccr2 = value1; *ccr3 = value3; break;
case 5: *ccr1 = value3; *ccr2 = value1; *ccr3 = value2; break;
case 4: *ccr1 = value3; *ccr2 = value2; *ccr3 = value1; break;
case 6: *ccr1 = value2; *ccr2 = value3; *ccr3 = value1; break;
case 2: *ccr1 = value1; *ccr2 = value3; *ccr3 = value2; break;
}
}
void SvpwmAlgorithm(float vd, float vq, float theta, uint32_t udc, uint32_t tpwm){
float valpha = 0, vbeta = 0;
RevParkOperate(vd, vq, theta, &valpha, &vbeta);
unsigned char n = SectorJude(valpha, vbeta);
float ta = 0, tb = 0;
VectorActionTime(n, valpha, vbeta, udc, tpwm, &ta, &tb);
uint32_t ccr1 = 0, ccr2 = 0, ccr3 = 0;
CCRCalculate(n, ta, tb, tpwm, &ccr1, &ccr2, &ccr3);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, ccr1);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, ccr2);
__HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_3, ccr3);
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM3){
if(motor_state == 1){
Get_Pos();
Encoder_TypeDef.angle = Get_Elec_Angle();
if(Encoder_TypeDef.angle >= Encoder_TypeDef.angle_rad_offset){
Encoder_TypeDef.angle -= Encoder_TypeDef.angle_rad_offset;
} else {
Encoder_TypeDef.angle = 6.2831852f - Encoder_TypeDef.angle_rad_offset + Encoder_TypeDef.angle;
}
Encoder_TypeDef.electronic_angle = fmod(Encoder_TypeDef.angle * 7, 6.2831852f);
PID_Position_Out = PID_Function(&pid_position_TypeDef, target_location, encoder.rad_comulative);
vel_LPF = LPF_velocity(MT6701_GetVelocity());
PID_Speed_Out = PID_Function(&pid_speed_TypeDef, PID_Position_Out, vel_LPF);
Clark_Park(PhaseACurrent, PhaseBCurrent, Encoder_TypeDef.electronic_angle, &foc_current);
PID_Out_Value = PID_Function(&pid_current_Typedef, PID_Speed_Out, foc_current.Iq);
SvpwmAlgorithm(0, PID_Out_Value, Encoder_TypeDef.electronic_angle, 12, 3600);
}
}
}