// FOC控制核心参数
typedef struct {
float i_d; // d轴电流
float i_q; // q轴电流
float i_d_ref; // d轴电流参考值
float i_q_ref; // q轴电流参考值
float v_d; // d轴电压
float v_q; // q轴电压
float v_alpha; // α轴电压
float v_beta; // β轴电压
float i_alpha; // α轴电流
float i_beta; // β轴电流
float theta; // 电气角度
float omega; // 电气角速度
float Kp_id, Ki_id; // d轴电流PI参数
float Kp_iq, Ki_iq; // q轴电流PI参数
float Kp_speed, Ki_speed; // 速度PI参数
float speed_ref; // 速度参考值
float speed; // 实际速度
uint16_t adc_data[3]; // ADC采样数据
} FOC_HandleTypeDef;
// FOC初始化函数
void FOC_Init(FOC_HandleTypeDef *foc) {
// 初始化PI控制器参数
foc->Kp_id = 5.0f;
foc->Ki_id = 100.0f;
foc->Kp_iq = 5.0f;
foc->Ki_iq = 100.0f;
foc->Kp_speed = 0.5f;
foc->Ki_speed = 5.0f;
// 初始化参考值
foc->i_d_ref = 0.0f;
foc->i_q_ref = 0.0f;
foc->speed_ref = 0.0f;
// 初始化定时器和ADC
TIMER_PWM_Init();
ADC_Init();
Encoder_Init();
}
// 坐标变换:Clarke变换 (abc -> αβ)
void Clarke_Transform(FOC_HandleTypeDef *foc) {
// 读取ADC采样值并转换为实际电流值
float i_a = (float)foc->adc_data[0] * ADC_SCALE - CURRENT_OFFSET;
float i_b = (float)foc->adc_data[1] * ADC_SCALE - CURRENT_OFFSET;
// Clarke变换公式
foc->i_alpha = i_a;
foc->i_beta = (i_a + 2*i_b) * 0.57735f; // 1/√3 ≈ 0.57735
}
// 坐标变换:Park变换 (αβ -> dq)
void Park_Transform(FOC_HandleTypeDef *foc) {
float sin_val = sinf(foc->theta);
float cos_val = cosf(foc->theta);
// Park变换公式
foc->i_d = foc->i_alpha * cos_val + foc->i_beta * sin_val;
foc->i_q = -foc->i_alpha * sin_val + foc->i_beta * cos_val;
}
// PI控制器:电流环
void Current_PI_Control(FOC_HandleTypeDef *foc) {
static float i_d_error_integral = 0.0f;
static float i_q_error_integral = 0.0f;
// 计算电流误差
float i_d_error = foc->i_d_ref - foc->i_d;
float i_q_error = foc->i_q_ref - foc->i_q;
// 积分项限幅
i_d_error_integral += i_d_error * SAMPLING_TIME;
i_q_error_integral += i_q_error * SAMPLING_TIME;
// 积分限幅
if (i_d_error_integral > INTEGRAL_LIMIT) i_d_error_integral = INTEGRAL_LIMIT;
if (i_d_error_integral < -INTEGRAL_LIMIT) i_d_error_integral = -INTEGRAL_LIMIT;
if (i_q_error_integral > INTEGRAL_LIMIT) i_q_error_integral = INTEGRAL_LIMIT;
if (i_q_error_integral < -INTEGRAL_LIMIT) i_q_error_integral = -INTEGRAL_LIMIT;
// 计算电压输出
foc->v_d = foc->Kp_id * i_d_error + foc->Ki_id * i_d_error_integral;
foc->v_q = foc->Kp_iq * i_q_error + foc->Ki_iq * i_q_error_integral;
// 电压限幅(根据DC母线电压调整)
float v_limit = DC_BUS_VOLTAGE * 0.577f; // 最大线电压 = DC_BUS_VOLTAGE * √3/3
float v_mag = sqrtf(foc->v_d * foc->v_d + foc->v_q * foc->v_q);
if (v_mag > v_limit) {
float scale = v_limit / v_mag;
foc->v_d *= scale;
foc->v_q *= scale;
}
}
// 坐标变换:逆Park变换 (dq -> αβ)
void Inverse_Park_Transform(FOC_HandleTypeDef *foc) {
float sin_val = sinf(foc->theta);
float cos_val = cosf(foc->theta);
// 逆Park变换公式
foc->v_alpha = foc->v_d * cos_val - foc->v_q * sin_val;
foc->v_beta = foc->v_d * sin_val + foc->v_q * cos_val;
}
// SVPWM(空间矢量脉宽调制)生成
void SVPWM_Generate(FOC_HandleTypeDef *foc) {
// 归一化电压
float v_alpha_norm = foc->v_alpha * (2.0f / DC_BUS_VOLTAGE);
float v_beta_norm = foc->v_beta * (2.0f / DC_BUS_VOLTAGE);
// 计算扇区
float U1 = v_beta_norm;
float U2 = -0.5f * v_beta_norm - 0.866f * v_alpha_norm;
float U3 = -0.5f * v_beta_norm + 0.866f * v_alpha_norm;
uint8_t sector = 1;
if (U1 <= 0) sector += 4;
if (U2 <= 0) sector += 2;
if (U3 <= 0) sector += 1;
// 计算各相占空比
float T1, T2, T0;
float Ta, Tb, Tc;
switch (sector) {
case 1: // 扇区1
T1 = v_beta_norm - 0.577f * v_alpha_norm;
T2 = 1.155f * v_alpha_norm;
break;
case 2: // 扇区2
T1 = -0.577f * v_alpha_norm - 0.5f * v_beta_norm;
T2 = 0.577f * v_alpha_norm - 0.5f * v_beta_norm;
break;
case 3: // 扇区3
T1 = -1.155f * v_alpha_norm;
T2 = 0.577f * v_alpha_norm + 0.5f * v_beta_norm;
break;
case 4: // 扇区4
T1 = -0.577f * v_alpha_norm - 0.5f * v_beta_norm;
T2 = -0.577f * v_alpha_norm + 0.5f * v_beta_norm;
break;
case 5: // 扇区5
T1 = -1.155f * v_alpha_norm;
T2 = -0.577f * v_alpha_norm - 0.5f * v_beta_norm;
break;
case 6: // 扇区6
T1 = 0.577f * v_alpha_norm - 0.5f * v_beta_norm;
T2 = -0.577f * v_alpha_norm - 0.5f * v_beta_norm;
break;
default:
T1 = 0;
T2 = 0;
break;
}
// 计算零矢量时间
T0 = 1.0f - T1 - T2;
// 确保时间非负
if (T0 < 0) {
float scale = 1.0f / (T1 + T2);
T1 *= scale;
T2 *= scale;
T0 = 0;
}
// 计算三相占空比(中心对齐PWM)
Ta = (T1 + T2 + T0/2) * PWM_PERIOD;
Tb = (T2 + T0/2) * PWM_PERIOD;
Tc = (T0/2) * PWM_PERIOD;
// 更新PWM比较值
TIM_SetCompare1(TIM1, Ta);
TIM_SetCompare2(TIM1, Tb);
TIM_SetCompare3(TIM1, Tc);
}
// 速度环PI控制
void Speed_PI_Control(FOC_HandleTypeDef *foc) {
static float speed_error_integral = 0.0f;
// 计算速度误差
float speed_error = foc->speed_ref - foc->speed;
// 积分项累积
speed_error_integral += speed_error * SAMPLING_TIME;
// 积分限幅
if (speed_error_integral > SPEED_INTEGRAL_LIMIT)
speed_error_integral = SPEED_INTEGRAL_LIMIT;
if (speed_error_integral < -SPEED_INTEGRAL_LIMIT)
speed_error_integral = -SPEED_INTEGRAL_LIMIT;
// 计算q轴电流参考值
foc->i_q_ref = foc->Kp_speed * speed_error + foc->Ki_speed * speed_error_integral;
// 电流限幅
if (foc->i_q_ref > CURRENT_LIMIT) foc->i_q_ref = CURRENT_LIMIT;
if (foc->i_q_ref < -CURRENT_LIMIT) foc->i_q_ref = -CURRENT_LIMIT;
}
// FOC主控制循环(在定时器中断中调用)
void FOC_MainControlLoop(FOC_HandleTypeDef *foc) {
// 1. 读取ADC采样值
ADC_Read(foc->adc_data);
// 2. 读取编码器位置
Update_EncoderPosition(&foc->theta, &foc->omega);
// 3. Clarke变换: abc -> αβ
Clarke_Transform(foc);
// 4. Park变换: αβ -> dq
Park_Transform(foc);
// 5. 速度环PI控制(仅在速度控制模式下)
Speed_PI_Control(foc);
// 6. 电流环PI控制
Current_PI_Control(foc);
// 7. 逆Park变换: dq -> αβ
Inverse_Park_Transform(foc);
// 8. SVPWM生成
SVPWM_Generate(foc);
}
|